ColdCore-3.1/
ColdCore-3.1/bin/
ColdCore-3.1/dbbin/
ColdCore-3.1/root/
ColdCore-3.1/root/html/
ColdCore-3.1/root/html/jlogin/
ColdCore-3.1/root/logs/
object $root;

var $root manager = $root;
var $root trusted = [];
var $root child_index = 0;
var $root inited = 0;
var $root quota = 75000;
var $root managed = [];
var $root writers = [$root];
var $root created_on = 0;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root quota_exempt = 0;
var $root writes = 0;
var $root trusted_by = 0;
var $root help_node = 0;
var $root settings = 0;
var $root defined_settings = #[["help-node", #[['get, ['help_node]], ['set, ['set_help_node_setting]], ['parse, ['parse_help_node_setting]], ['format, ['format_help_node_setting]]]]];
var $root semaphores = 0;
var $root credit = 0;

root method .init_root(): nooverride {
    .change_manager(this());
    flags = ['variables, 'methods, 'code];
    created_on = time();
};

root method .uninit_root(): nooverride {
    var obj;
    
    (| manager.del_managed_obj() |);
    catch any {
        for obj in (.managed())
            obj.change_manager($reaper);
    }
    catch any {
        for obj in (.writers('literal))
            .del_writer(obj);
    }
    catch any {
        for obj in (.writes())
            obj.del_writer(this());
    }
    catch any {
        for obj in (.trusted('literal))
            .del_trusted(obj);
    }
    catch any {
        for obj in (.trusted_by())
            obj.del_trusted(this());
    }
    
    // tell $sys we are going away
    $sys.sender_going_away();
};

public method .initialize(): nooverride {
    var ancestors, pos, len, method, a, def, str, tb;
    
    // called by $sys.create() to create a new object.
    if ((caller() != $sys) && (sender() != this()))
        throw(~perm, "Caller is not $sys and sender is not this.");
    if (inited)
        throw(~perm, "Already initialized.");
    ancestors = ancestors().reverse();
    for a in (ancestors) {
        refresh();
        if (!(method = (| tosym("init_" + tostr(a.objname())) |)))
            continue;
        if ((def = (| find_method(method) |))) {
            if (def != a) {
                (| (def.manager()).tell(((("Initialization method for " + a) + " in wrong place (") + find_method(method)) + ")") |);
            } else {
                catch any {
                    .(method)();
                } with {
                    // try and let somebody know they made a boo-boo somewhere
                    str = ((("UNINIT ERROR " + this()) + "<") + def) + ">:";
                    tb = traceback().fmt_tb();
                    if (def) {
                        (| (def.manager()).tell(str) |);
                        (| (def.manager()).tell(tb) |);
                    }
                    if ((.manager()) != sender()) {
                        (| sender().tell(str) |);
                        (| sender().tell(tb) |);
                    }
                    (| sender().tell("Continuing init..") |);
                    (| $sys.log_traceback(tb, "** " + str) |);
                }
            }
        }
    }
    inited = 1;
};

public method .uninitialize(): nooverride {
    arg @destroyed;
    var a, v, d, definer, method, descendants, str, tb;
    
    (> .perms(caller(), $root, $sys) <);
    destroyed = destroyed ? 1 : 0;
    descendants = (.descendants()) + [this()];
    
    // call [ancestors...].uninit_ancestor() on the object being destroyed
    for a in (ancestors()) {
        method = tosym("uninit_" + (a.objname()));
        if ((definer = (| find_method(method) |))) {
            if (definer != a) {
                // scream madly and run around--everybody should know this
                str = "UNINIT ERROR: uninit method for " + a;
                str += (" in wrong place (" + definer) + ")";
                (| (definer.manager()).tell(str) |);
                (| (a.manager()).tell(str) |);
                (| sender().tell(str) |);
                continue;
            }
            catch any {
                .(method)();
            } with {
                // try and let somebody know they made a boo-boo somewhere
                tb = traceback().fmt_tb();
                str = ((("UNINIT ERROR " + this()) + "<") + definer) + ">:";
                if (definer) {
                    (| (definer.manager()).tell(str) |);
                    (| (definer.manager()).tell(tb) |);
                }
                (| sender().tell(str) |);
                (| sender().tell(tb) |);
                (| sender().tell("Continuing uninit..") |);
                (| $sys.log_traceback(tb, "** " + str) |);
            }
        }
        refresh();
    }
    
    // if we have descendants, clean anything from the object being dested
    method = tosym("uninit_" + (.objname()));
    if ((definer = (| find_method(method) |))) {
        if (definer != this()) {
            // scream madly and run around--everybody should know this
            str = "UNINIT ERROR: uninit method for " + a;
            str += (" in wrong place (" + definer) + ")";
            (| (definer.manager()).tell(str) |);
            (| (.manager()).tell(str) |);
            (| sender().tell(str) |);
        } else {
            for d in (descendants) {
                catch any {
                    d.(method)();
                } with {
                    // try and let somebody know they made a boo-boo somewhere
                    str = ((("UNINIT ERROR " + d) + "<") + this()) + ">:";
                    tb = traceback().fmt_tb();
                    (| (.manager()).tell(str) |);
                    (| (.manager()).tell(tb) |);
                    if ((.manager()) != sender()) {
                        (| sender().tell(str) |);
                        (| sender().tell(tb) |);
                    }
                    (| sender().tell("Continuing uninit..") |);
                    (| $sys.log_traceback(tb, "** " + str) |);
                }
                refresh();
            }
        }
    }
    
    // clear vars
    if ((!destroyed) && descendants)
        $sys.clear_definer_vars(this(), descendants);
};

public method .perms(): nooverride {
    arg what, @args;
    var flag;
    
    if (!args)
        args = ['writer];
    if (type(args[1]) == 'symbol) {
        switch (args[1]) {
            case 'system:
                if (!($sys.is_system(what)))
                    throw(~perm, ("Permission Denied: " + what) + " is not of the system.", what);
            case 'manager:
                if (((.manager()) != what) && (!($sys.is_system(what))))
                    throw(~perm, ("Permission Denied: " + what) + " is not the manager.", what);
            case 'trusts:
                if (!(.trusts(what)))
                    throw(~perm, ("Permission Denied: " + what) + " is not a trustee.", what);
            case 'command:
                if ((what != $user) && (what != $body))
                    throw(~perm, what + " is not a valid command invoking object.");
            default:
                if (!(.is_writable_by(what)))
                    throw(~perm, ("Permission Denied: " + what) + " is not a writer.", what);
        }
    } else if (type(what) == 'objnum) {
        if (!(what in args))
            throw(~perm, (what + " is not one of: ") + ((args.mmap('namef, 'ref)).to_english()), what);
    }
};

public method .chparents() {
    arg @parents;
    var parent, cur;
    
    if (!(| .perms(sender(), 'manager) |))
        (> .perms(caller(), $root, $sys) <);
    (> $sys.touch() <);
    if (!parents)
        throw(~noparents, "There must be at least 1 parent for each object.");
    
    // Notify new parents of impending change.
    cur = parents();
    for parent in (parents) {
        if (!(parent in cur))
            (> parent.will_inherit(sender()) <);
    }
    
    // Everything's okay, go ahead and try it.
    .change_parents(parents);
};

public method .will_inherit() {
    arg who;
    
    if (this() in (sender().parents()))
        throw(~perm, ((sender() + " already has ") + this()) + " as a parent.");
    if ((!(.has_flag('fertile, sender()))) && (!(.trusts(who))))
        throw(~perm, ((this() + " refuses to be parent of ") + sender()) + ".");
};

public method .manager(): nooverride {
    return manager || $reaper;
};

public method .writers(): nooverride {
    arg @literal;
    
    if (literal)
        return writers || [];
    if (manager != this())
        return [manager, this()] + (writers || []);
    return [manager] + (writers || []);
};

public method .trusted(): nooverride {
    arg @literal;
    
    if (literal)
        return trusted || [];
    return (trusted || []) + (.writers());
};

public method .is_writable_by(): nooverride {
    arg obj;
    var o;
    
    for o in (.writers()) {
        if (o.has_ancestor($group)) {
            if (o.includes(obj))
                return 1;
        } else if (o == obj) {
            return 1;
        }
    }
    return $sys.is_system(obj);
    
    // return (| obj in .writers() |) || $sys.is_system(obj);
};

public method .trusts(): nooverride {
    arg obj;
    var o;
    
    for o in (.trusted()) {
        if (o.has_ancestor($group)) {
            if (o.includes(obj))
                return 1;
        } else if (o == obj) {
            return 1;
        }
    }
    return ($systrust_group.includes(obj)) || ($sys.is_system(obj));
};

public method .change_manager(): nooverride {
    arg new;
    var old;
    
    if ((caller() != definer()) && (!($sys.is_system(sender()))))
        throw(~perm, "You must have system privileges to change the manager.");
    (> $sys.touch() <);
    if (type(new) != 'objnum)
        throw(~invarg, "Managers must be given as a single dbref.");
    old = .manager();
    manager = new;
    old.del_managed_obj();
    new.add_managed_obj();
};

public method .add_writer(): nooverride {
    arg obj;
    
    (> .perms(sender(), 'manager) <);
    (> $sys.touch('coreok) <);
    writers = (writers || []).setadd(obj);
    obj.add_writable_obj();
};

public method .del_writer(): nooverride {
    arg obj;
    
    (caller() == definer()) || (> .perms(sender(), 'manager) <);
    writers = (writers || []).setremove(obj);
    (> $sys.touch('coreok) <);
    if (!writers)
        (| clear_var('writers) |);
    obj.del_writable_obj();
};

public method .add_trusted(): nooverride {
    arg obj;
    
    (caller() == definer()) || (> .perms(sender(), 'manager) <);
    (> $sys.touch('coreok) <);
    trusted = (trusted || []).setadd(obj);
    obj.add_trusted_obj();
};

public method .del_trusted(): nooverride {
    arg obj;
    
    (> .perms(sender(), 'manager) <);
    (> $sys.touch('coreok) <);
    trusted = (trusted || []).setremove(obj);
    if (!trusted)
        clear_var('trusted);
    obj.del_trusted_obj();
};

public method .as_this_run() {
    arg obj, method, args;
    
    (caller().is($http_interface)) || (> .perms(caller(), $scheduler, $page_set) <);
    return (> obj.(method)(@args) <);
};

public method .add_parent() {
    arg parent;
    
    (> .perms(sender(), 'manager) <);
    (> $sys.touch() <);
    (> parent.will_inherit(sender()) <);
    if (.has_ancestor(parent))
        throw(~perm, ((this() + " already has ") + parent) + " as an ancestor.");
    .change_parents(parents() + [parent]);
};

public method .del_parent() {
    arg parent;
    var parents;
    
    (> .perms(sender(), 'manager) <);
    (> $sys.touch() <);
    if (!valid(parent))
        throw(~type, "Not a valid parent, must send a valid object.");
    parents = .parents();
    if (!(parent in parents))
        throw(~parentnf, ((parent + " is not a parent of ") + this()) + ".");
    parents = parents.setremove(parent);
    (> .change_parents(parents) <);
};

public method .spawn(): nooverride {
    arg @suffix;
    var obj, tmp, objname, mngr, na;
    
    (> .will_spawn(sender()) <);
    suffix = (> .get_obj_suffix(@suffix) <);
    return $sys.spawn_sender(suffix, sender());
};

public method .destroy(): nooverride {
    // This doesn't actually destroy us immediately, but we will go away when
    // nothing is holding onto us any more.
    (> .perms(sender(), 'manager) <);
    if (.has_flag('core))
        throw(~perm, "This object is a core object, and cannot be destroyed!");
    (| .uninitialize('destroy) |);
    destroy();
};

public method .add_var(): nooverride {
    arg name, @args;
    var tmp, kid;
    
    (> .perms(sender()) <);
    (> $sys.touch() <);
    if (!(tostr(name).valid_ident()))
        throw(~invident, name + " is not a valid ident.");
    (> add_var(name) <);
    if ('core in (.flags()))
        $changelog.log((((("ADD-VAR: " + this()) + ",") + name) + " by ") + sender());
    
    // The following code is a kludge as we can't send a default value  
    // to the primitive.   
    if (args) {
        tmp = tosym((("__set_" + tostr(name)) + "_") + time());
        catch any {
            add_method([((tostr(name) + " = ") + toliteral(args[1])) + ";"], tmp);
            .(tmp)();
            if (((args.length()) > 1) && ((args[2]) == 'inherit)) {
                for kid in (.descendants())
                    kid.(tmp)();
            }
            del_method(tmp);
        } with {
            del_method(tmp);
            rethrow(error());
        }
    }
};

public method .variables(): nooverride {
    if (!(.has_flag('variables, sender())))
        throw(~perm, (sender() + " doesn't have permission to find methods on ") + this());
    return variables();
};

public method .del_var(): nooverride {
    arg name;
    var n, obj, errs;
    
    (caller() == definer()) || (> .perms(sender()) <);
    (> $sys.touch() <);
    
    // try and clear the variable on all of the descendants, before 
    // deleting the variable...since we are root, dont use the standard  
    // hooks as perms may not be right
    n = tosym("_dclear_var_" + tostr(time()));
    catch any {
        add_method([("clear_var('" + name) + ");"], n);
        for obj in (.descendants()) {
            (| obj.(n)() |);
            pause();
        }
    }
    (| del_method(n) |);
    
    // now delete the variable
    (> del_var(name) <);
    if ('core in (.flags()))
        $changelog.log((((("DEL-VAR: " + this()) + ",") + name) + " by ") + sender());
};

public method .del_method(): nooverride {
    arg name;
    
    (> .perms(sender()) <);
    (> del_method(name) <);
    if ('core in (.flags()))
        $changelog.log((((("DEL-METHOD: " + this()) + ",") + name) + " by ") + sender());
};

public method .methods(): nooverride {
    if (!(.has_flag('methods, sender())))
        throw(~perm, (sender() + " doesn't have permission to find methods on ") + this());
    return methods();
};

public method .parents(): nooverride {
    return parents();
};

public method .children(): nooverride {
    return children();
};

public method .ancestors(): nooverride {
    arg @args;
    
    return ancestors(@args);
};

public method .find_method(): nooverride {
    arg name;
    
    if (!(.has_flag('methods, sender())))
        throw(~perm, (sender() + " doesn't have permission to find methods on ") + this());
    return (> find_method(name) <);
};

public method .find_next_method(): nooverride {
    arg name, after;
    
    if (!(.has_flag('methods, sender())))
        throw(~perm, (sender() + " doesn't have permission to find methods on ") + this());
    return (> find_next_method(name, after) <);
};

private method .corify_descendants_of(): nooverride {
    arg obj;
    var d, name, l;
    
    name = (| tosym("core_" + (obj.objname())) |);
    catch ~methodnf {
        if ((> obj.find_method(name) <) != obj) {
            $sys.log(((("** Coremethod for " + obj) + " in wrong place (on ") + (obj.find_method(name))) + ") **");
            return;
        }
    } with {
        return;
    }
    for d in ([obj] + (obj.descendants())) {
        catch any {
            (> d.(name)() <);
        } with {
            $sys.log(((("** ERROR encountered in " + d) + ".") + name) + "():");
            for l in ($parse_lib.traceback(traceback()))
                $sys.log(l);
        }
        refresh();
    }
};

public method .add_method() {
    arg code, name, @evalonly;
    var l, m, line, errs;
    
    (> .perms(sender()) <);
    if (evalonly && (caller() in [$root, $sys, $programmer]))
        (> $sys.touch('lockok) <);
    else
        (> $sys.touch() <);
    
    // check for a few things only admins can do
    if (!(sender().is($admin))) {
        for l in [1 .. listlen(code)] {
            line = code[l];
            if ((m = line.match_regexp("[^a-z0-9_.]anticipate_assignment\("))) {
                (> sender().tell($code_lib.point_to_line("ERROR: call to anticipate_assignment()", ((m[1])[1]) + 2, ((m[1])[2]) - 2, l, line)) <);
                throw(~perm, "anticipate_assignment() may only be used by an administrator.");
            }
        }
    }
    errs = (> add_method(code, name) <);
    if ('core in (.flags()))
        $changelog.log((((("ADD-METHOD: " + this()) + ".") + name) + " by ") + sender());
    for l in [1 .. listlen(errs)] {
        line = errs[l];
        if (match_regexp(line, "Line [0-9]+: Unknown function length.")) {
            line = substr(line, 1, strlen(line) - 1);
            errs = replace(errs, l, line + "(), try listlen(), strlen() or buflen()");
        }
    }
    return errs;
};

public method .has_ancestor(): nooverride {
    arg obj;
    
    return has_ancestor(obj);
};

public method .eval(): nooverride {
    arg code, @dest;
    var errors, result, method;
    
    dest = dest ? (dest[1]) : this();
    if (!(sender() in [$scheduler, $root]))
        (> .perms(sender()) <);
    
    // Compile the code.
    method = tosym("tmp_eval_" + tostr(time()));
    errors = .add_method(code, method);
    if (errors)
        return ['errors, errors, 0, 0];
    
    // Evaluate the expression.  Be sure to remove it afterwards, so that no
    // one else can call it.
    catch any {
        result = (> dest.(method)() <);
    } with {
        (| del_method(method) |);
        rethrow(error());
    }
    (| del_method(method) |);
    return ['result, result];
};

public method .method_info(): nooverride {
    arg @args;
    
    return (> method_info(@args) <);
};

public method .data(): nooverride {
    arg @parent;
    var par, data, out;
    
    if (!(.has_flag('variables, sender())))
        throw(~perm, ((sender().namef('ref)) + " is not allowed to read variables on ") + (.namef('ref)));
    if (parent) {
        if (type(parent[1]) != 'objnum)
            throw(~type, (parent[1]) + " is not an object.");
        return (> data(parent[1]) <);
    } else {
        data = (> data() <);
        out = #[];
        for par in (data) {
            // if the parent doesn't exist anymore, just let them see the data.
            if ((!valid(par[1])) || ((par[1]).has_flag('variables, sender())))
                out = out.add(par[1], par[2]);
            else
                out = out.add(par[1], ["*** Permission Denied ***"]);
        }
        return out;
    }
};

public method .size(): nooverride {
    arg @args;
    
    [(args ?= 'int)] = args;
    switch (args) {
        case 'string:
            return tostr(size());
        case 'english:
            return size().to_english();
        default:
            return size();
    }
};

public method .descendants(): nooverride {
    var kids, i, c, child, d;
    
    d = #[];
    for child in (children())
        d = dict_add(d, child, 1);
    while ((| (c = dict_keys(d)[++i]) |)) {
        for child in (c.children()) {
            pause();
            d = dict_add(d, child, 1);
        }
        pause();
    }
    return dict_keys(d);
};

public method .get_quota(): nooverride {
    arg @args;
    
    return quota;
};

public method .quota_valid(): nooverride {
    if (quota_exempt)
        return 1;
    if (!(.is($user)))
        return 0;
    return (.quota_byte_usage()) < (.quota());
};

public method .match_children() {
    arg string;
    var children, child_names, c;
    
    children = .children();
    child_names = children.mmap('name);
    
    // direct matches first.
    for c in (child_names) {
        if (c == string)
            return children[c in child_names];
    }
    
    // ok, try partial matches
    for c in (child_names) {
        if ($string.match_begin(c, string))
            return children[c in child_names];
    }
    return 0;
};

public method .del_flag(): nooverride {
    arg flag;
    
    (> .perms(sender(), 'manager) <);
    (> $sys.touch('coreok) <);
    if ((flag == 'core) && (!($sys.writable_core())))
        throw(~perm, this() + " is a core object, and the core isn't writable.");
    
    // let them add any flag they want
    flags = (flags || []).setremove(flag);
};

public method ._display_descendants() {
    arg space, checked, levels, maxlev;
    var c, anc, list, id, perms;
    
    id = ((space + this()) + " ") + ($object_lib.see_perms(this()));
    for anc in (dict_keys(checked)) {
        if (.has_ancestor(anc))
            return [];
    
        // [id + "  (above)"];
    }
    if (((.parents()).length()) > 1)
        id += " (MI)";
    list = [id];
    space += "  ";
    levels++;
    
    // check children
    if ((!maxlev) || (maxlev != levels)) {
        for c in (.children()) {
            list += c._display_descendants(space, checked, levels, maxlev);
            checked = dict_add(checked, c, 1);
            pause();
        }
    }
    return list;
};

public method ._get_method_info(): nooverride {
    arg anc, method;
    var code, lines, dis_flag, meth_args, flags, first_comment;
    
    code = anc.list_method(method);
    lines = code.length();
    if (lines > 5)
        code = code.subrange(1, 5);
    flags = anc.method_flags(method);
    if (code) {
        meth_args = regexp(code[1], "arg ([^;]);");
        if (meth_args) {
            meth_args = meth_args[1];
            code = code.delete(1);
        } else {
            meth_args = "";
        }
        if (code && ((!(code[1])) || (((code[1])[1]) == "v")))
            code = code.delete(1);
        if (code && ((!(code[1])) || (((code[1])[1]) == "v")))
            code = code.delete(1);
        first_comment = code ? ((code[1]) + " ") : " ";
        first_comment = (((first_comment[1]) == "/") || ((first_comment[1]) == "r")) ? first_comment : "";
    } else {
        meth_args = "";
        first_comment = "";
    }
    return [anc, method, meth_args, flags, lines, first_comment];
};

public method .namef() {
    arg type;
    
    return tostr(this());
};

public method .match_descendants() {
    arg string;
    var match, child;
    
    match = .match_children(string);
    if (match)
        return match;
    for child in (.children()) {
        match = child.match_descendants(string);
        if (match)
            return match;
    }
    return 0;
};

public method .debug() {
    arg @stuff;
    var x, line, mngr, meth, stack, out, ref;
    
    stack = stack();
    meth = (| (((stack[2])[3]) + "() line ") + ((stack[2])[4]) |);
    
    // dont even bother
    mngr = .manager();
    if (!(| mngr.find_method('tell) |))
        return;
    if (sender() != caller())
        ref = ((sender() + "<") + caller()) + ">";
    else
        ref = sender();
    if (meth)
        line = ((("DEBUG " + ref) + ".") + meth) + ":";
    else
        line = ("DEBUG " + ref) + ":";
    mngr.tell(line);
    for x in (stuff) {
        refresh();
        mngr.tell(($data_lib.unparse_indent(x)).prefix("DEBUG    "));
    }
};

public method .set_quota(): nooverride {
    arg value;
    
    (> .perms(caller(), $user, @$sys.system(), $root, $admin) <);
    quota = value;
};

public method .name() {
    arg @args;
    
    return tostr(this());
};

public method .quota(): nooverride {
    return quota;
};

public method .quota_byte_usage(): nooverride {
    var total, obj;
    
    for obj in (.managed()) {
        if (!valid(obj))
            continue;
        total += obj.size();
    }
    return total;
};

public method .corify(): nooverride {
    var d;
    
    if (sender() != $sys)
        throw(~sysonly, "This should only be called by $sys.make_core().");
    
    // reverse engineer it--if coreify_<object> exists,
    // call it on this object and all of its descendants.
    for d in (((.descendants()).setremove($sys)) + [$sys]) {
        .corify_descendants_of(d);
        refresh();
    }
};

root method .change_parents(): nooverride {
    arg parents;
    var old_a, old_p, a, obj, new_a, definer, branch, method, str;
    
    if (!parents)
        throw(~noparents, "Objects must have at least 1 parent");
    
    // remember a few things
    old_a = setremove(ancestors(), this());
    old_p = .parents();
    branch = (.descendants()) + [this()];
    
    // build the new ancestors list by hand, so we can figure out what is
    // changing, and uninitialize those ancestors that are going away
    new_a = [];
    for obj in (parents)
        new_a = union(new_a, obj.ancestors());
    
    // uninit any ancestors going away
    for a in (old_a.set_difference(new_a)) {
        // call this ancestor's uninit on the obj and all its children
        method = tosym("uninit_" + (a.objname()));
        if ((definer = (| find_method(method) |))) {
            if (definer != a) {
                // scream madly and run around--everybody should know this
                str = "UNINIT ERROR: uninit method for " + a;
                str += (" in wrong place (" + definer) + ")";
                (| (definer.manager()).tell(str) |);
                (| (a.manager()).tell(str) |);
                (| sender().tell(str) |);
                continue;
            }
    
            // call the uninit method on this object only
            catch any {
                .(method)();
            } with {
                // try and let somebody know they made a boo-boo somewhere
                str = ((("UNINIT ERROR " + obj) + "<") + this()) + ">:";
                (| (.manager()).tell(str) |);
                (| (.manager()).tell_traceback(traceback()) |);
                (| sender().tell(str) |);
                (| sender().tell_traceback(traceback()) |);
                (| sender().tell("Continuing chparent..") |);
            }
        }
    
        // cleanup any old obj vars left lying around
        // if (branch)
        //     $sys.clear_definer_vars(a, branch);
        $sys.clear_definer_vars(a, [this()]);
        refresh();
    }
    
    // make the change
    (> chparents(parents) <);
    if ('core in (.flags()))
        $changelog.log(((((("CHANGE-PARENTS: " + this()) + " from ") + old_p) + " to ") + parents()) + " by ");
    new_a = setremove(ancestors(), this());
    
    // init anybody new to the family
    for a in (new_a.set_difference(old_a)) {
        method = tosym("init_" + (a.objname()));
        if ((definer = (| find_method(method) |))) {
            if (definer != a) {
                // scream madly and run around--everybody should know this
                // (damn inlaws, can't ever get things right)
                str = "INIT ERROR: init method for " + a;
                str += (" in wrong place (" + definer) + ")";
                (| (definer.manager()).tell(str) |);
                (| (a.manager()).tell(str) |);
                (| sender().tell(str) |);
                continue;
            }
    
            // introduce the new ancestor
            catch any {
                .(method)();
            } with {
                // try and let somebody know they made a boo-boo somewhere
                str = ((("INIT ERROR " + obj) + "<") + this()) + ">:";
                (| (.manager()).tell(str) |);
                (| (.manager()).tell_traceback(traceback()) |);
                (| sender().tell(str) |);
                (| sender().tell_traceback(traceback()) |);
                (| sender().tell("Continuing chparent..") |);
            }
        }
        refresh();
    }
};

public method .objname(): nooverride {
    return (> objname() <);
};

public method .set_objname() {
    arg objname;
    
    (> .perms(sender()) <);
    if (.has_flag('core))
        throw(~perm, this() + " is a core object; you cannot change its object name!");
    (> $sys.touch() <);
    
    // Make sure first argument is a symbol.
    if (type(objname) != 'symbol)
        throw(~type, "New objname is not a symbol.");
    
    // Make sure everything is lowercase.
    objname = tosym(tostr(objname).lowercase());
    
    // Do nothing if objname isn't different.
    if (objname == (| objname() |))
        return;
    return (> set_objname(objname) <);
};

public method .created_on(): nooverride {
    return created_on;
};

public method .is_of(): nooverride {
    arg obj;
    
    return obj in ancestors();
};

public method .is(): nooverride {
    arg @args;
    
    if (!args)
        throw(~invarg, "Must have one argument.");
    if (type(args[1]) == 'dictionary)
        return has_ancestor(args[2]);
    return has_ancestor(args[1]);
};

public method .hname() {
    arg @args;
    
    return ((("<a href=\"/bin/display?" + this()) + "\">") + this()) + "</a>";
};

public method .add_flag(): nooverride {
    arg flag;
    
    (> .perms(sender(), 'manager) <);
    (> $sys.touch('coreok) <);
    if ((flag == 'core) && (!($sys.is_system(sender()))))
        throw(~perm, "Only system objects can set the 'core flag.");
    (flag == 'fertile) && (> .perms(sender(), 'manager) <);
    
    // let them add any flag they want
    flags = (flags || []).setadd(flag);
};

public method .build_name() {
    arg @args;
    var output, type, part, rval;
    
    output = "";
    for part in (args) {
        type = type(part);
        if (type == 'list)
            output += (| .(part[1])(@part.subrange(2)) |) || "";
        else if (type == 'string)
            output += part;
    }
    return output;
};

public method .clear_variable(): nooverride {
    arg name;
    var n, obj;
    
    (> .perms(sender()) <);
    n = tosym("_clear_var_" + tostr(time()));
    catch any {
        .add_method([("clear_var(" + toliteral(name)) + ");"], n);
        for obj in (.descendants()) {
            (| obj.(n)() |);
            pause();
        }
        (| del_method(n) |);
    } with {
        (| del_method(n) |);
    }
};

public method .ancestors_to(): nooverride {
    arg checked, levels, maxlev;
    var c, list;
    
    list = [this()];
    levels++;
    
    // check parents
    if ((!maxlev) || (maxlev != levels)) {
        for c in (.parents()) {
            list += [c.ancestors_to(checked, levels, maxlev)];
            checked = checked.setadd(c);
        }
    }
    return list;
};

public method .descendants_to(): nooverride {
    arg checked, levels, maxlev;
    var c, list;
    
    list = [this()];
    levels++;
    
    // check parents
    if ((!maxlev) || (maxlev != levels)) {
        for c in (.children()) {
            list += [c.descendants_to(checked, levels, maxlev)];
            checked = checked.setadd(c);
        }
    }
    return list;
};

public method .ancestry(): nooverride {
    arg gen;
    var i, out;
    
    out = [];
    if (type(gen) == 'objnum) {
        for i in (.ancestors()) {
            if (i.has_ancestor(gen))
                out += [i];
        }
        return out;
    }
    if (gen != 0) {
        for i in (.parents())
            out = union(out, i.ancestry(gen - 1));
    }
    return out;
};

public method .generations(): nooverride {
    arg gen;
    var p, out;
    
    out = [this()];
    if (gen != 0) {
        for p in (.parents())
            out = union(out, p.generations(gen - 1));
    }
    return out;
};

public method .variable_info() {
    arg gen, def, fltr, match;
    var ancs, data, pp, p;
    
    if (!(.has_flag('variables, sender())))
        throw(~perm, (sender() + " cannot read variables on ") + this());
    if (def)
        ancs = [def];
    else
        ancs = .(gen[1])(gen[2]) || [this()];
    data = [];
    for pp in ((data().to_list()).reverse()) {
        if (valid(pp[1]) && ((pp[1]) in ancs)) {
            for p in (pp[2]) {
                if (tostr(p[1]).(match)(fltr) != 0)
                    data += [[pp[1], @p]];
            }
        }
    }
    return data;
};

public method .method_flags(): nooverride {
    arg method;
    
    if (!(.has_flag('methods, sender())))
        throw(~perm, (sender() + " doesn't have permission to find methods on ") + this());
    return (> method_flags(method) <);
};

public method .method_access(): nooverride {
    arg method;
    
    if (!(.has_flag('methods, sender())))
        throw(~perm, (sender() + " doesn't have permission to find methods on ") + this());
    return (> method_access(method) <);
};

public method .set_method_flags(): nooverride {
    arg method, flags;
    var current;
    
    if (!(.is_writable_by(sender())))
        throw(~perm, (sender() + " cannot write to ") + this());
    (> $sys.touch() <);
    current = method_flags(method);
    if ((('locked in flags) && (!('locked in current))) && (!($sys.is_system(sender()))))
        throw(~perm, "Only administrators can set the locked method flag.");
    if ((('nooverride in flags) && (!('nooverride in current))) && (!($sys.is_system(sender()))))
        throw(~perm, "Only administrators can set the nooverride method flag.");
    return set_method_flags(method, flags);
};

public method .set_method_access(): nooverride {
    arg method, state;
    
    if (!(.is_writable_by(sender())))
        throw(~perm, (sender() + " cannot write to ") + this());
    (> $sys.touch() <);
    return (> set_method_access(method, state) <);
};

public method .set_flags(): nooverride {
    arg new_flags;
    
    (> .perms(sender(), 'manager) <);
    (> $sys.touch() <);
    if (type(new_flags) != 'list)
        throw(~invflags, "Flags must be submitted as a list of symbols.");
    if ((!new_flags) && flags)
        return clear_var('flags);
    if ((('core in new_flags) && (!('core in (.flags())))) && (!($sys.is_system(sender()))))
        throw(~perm, "Only system objects can set the 'core flag.");
    if (('fertile in new_flags) && (!('fertile in flags)))
        (> .perms(sender(), 'manager) <);
    flags = new_flags;
};

public method .managed(): nooverride {
    return managed || [];
};

root method .add_managed_obj(): nooverride {
    managed = (managed || []).setadd(sender());
};

root method .del_managed_obj(): nooverride {
    managed = (managed || []).setremove(sender());
    if (!managed)
        clear_var('managed);
};

public method .writes(): nooverride {
    return writes || [];
};

root method .add_writable_obj(): nooverride {
    writes = (writes || []).setadd(sender());
};

root method .del_writable_obj(): nooverride {
    writes = (writes || []).setremove(sender());
    if (!writes)
        clear_var('writes);
};

public method .trusted_by(): nooverride {
    return trusted_by || [];
};

root method .add_trusted_obj(): nooverride {
    trusted_by = (trusted_by || []).setadd(sender());
};

root method .del_trusted_obj(): nooverride {
    trusted_by = (trusted_by || []).setremove(sender());
    if (!trusted_by)
        clear_var('trusted_by);
};

public method .has_flag(): nooverride {
    arg flag, @sender;
    
    [(sender ?= sender())] = sender;
    if (flag == 'core)
        return flag in (.flags());
    return (flag in (.flags())) || (.trusts(sender));
};

public method .flags(): nooverride {
    return flags || [];
};

public method .quota_exempt(): nooverride {
    return quota_exempt;
};

public method .clean_root() {
    var obj;
    
    // Called by $sys.clean_database()
    (> .perms(caller(), $sys) <);
    (| ._clean_root('trusted, 'trusted_by) |);
    (| ._clean_root('trusted_by, 'trusted) |);
    (| ._clean_root('writers, 'writes) |);
    (| ._clean_root('writes, 'writers) |);
    if (!manager) {
        manager = this();
        .change_manager($reaper);
    }
    if (managed) {
        managed = managed.valid_objects();
        for obj in (managed) {
            refresh();
            if ((obj.manager()) != this())
                managed = setremove(managed, obj);
        }
        if (!managed)
            clear_var('managed);
    }
};

public method .objnum(): nooverride {
    return objnum();
};

public method .list_methods() {
    arg gen, def, fltr, match;
    var ancs, a, m, i, methods;
    
    if (!(.has_flag('methods, sender())))
        throw(~perm, (sender() + " cannot view methods on ") + this());
    if (def)
        ancs = [def];
    else
        ancs = .(gen[1])(gen[2]) || [this()];
    methods = #[];
    for a in (ancs) {
        for m in (a.methods()) {
            if (tostr(m).(match)(fltr) != 0) {
                i = a.method_info(m);
                methods = methods.add_elem(i[5], [a, m, @i]);
            }
        }
    }
    return methods;
};

public method .method_bytecode() {
    arg method;
    
    return 'no;
    return (> method_bytecode(method) <);
};

public method .rename_method() {
    arg now, new;
    
    (> .perms(sender()) <);
    (> $sys.touch() <);
    return (> rename_method(now, new) <);
};

public method .examine() {
    return [];
};

private method ._clean_root() {
    arg v, m;
    var obj, value;
    
    if ((value = get_var(v))) {
        value = value.valid_objects();
        for obj in (value) {
            if (!(this() in obj.(m)()))
                value = value.setremove(obj);
            refresh();
        }
        if (value)
            set_var(v, value);
        else
            clear_var(v);
    }
};

public method .set_quota_exempt(): nooverride {
    arg bool;
    
    (> .perms(sender(), $user, @$sys.system(), $root) <);
    if (bool)
        quota_exempt = 1;
    else
        (| clear_var('quota_exempt) |);
};

public method .help_node() {
    arg @args;
    
    return help_node;
};

public method .parse_help_node_setting() {
    arg value, @args;
    
    if (!value)
        return 0;
    value = (> $object_lib.to_dbref(value) <);
    if (!(value.is($help_node)))
        throw(~perm, (value.namef('ref)) + " is not a $help_node.");
    return value;
};

public method .list_method(): nooverride {
    arg @args;
    
    if (!(.has_flag('code, sender())))
        throw(~perm, (("Method code on " + (.namef('ref))) + " is not readable by ") + (sender().namef('ref)));
    return (> list_method(@args) <);
};

public method .new() {
    arg @suffix;
    var obj, tmp, objname, mngr, na;
    
    // this difference between this and .spawn() is that you
    // can override this method to return a frob instead.
    (> .will_spawn(sender()) <);
    suffix = (> .get_obj_suffix(@suffix) <);
    return $sys.spawn_sender(suffix, sender());
};

public method .will_spawn(): nooverride {
    arg who;
    
    if (!(.has_flag('fertile, who)))
        throw(~perm, (.namef('ref)) + " is not fertile or readable.");
    
    // available quota?
    if (!(who.quota_valid()))
        throw(~quota, "Sender does not have the available quota");
};

public method .get_obj_suffix() {
    arg @suffix;
    var objname, tmp;
    
    // Figure out the suffix from the arguments and child index.
    [(suffix ?= 0)] = suffix;
    if (suffix) {
        // so they dont confuse child_index:
        if (suffix.is_numeric())
            throw(~perm, "You cannot specify a numeric suffix.");
    
        // so we get correct symbols & it is always lowercase:
        suffix = lowercase(strsed(suffix, "[^a-z0-9_]+", "", "g"));
    } else {
        // get the next valid objname
        objname = tostr((| .objname() |) || "unknown");
        tmp = tosym(objname);
        while ((| lookup(tmp) |)) {
            child_index++;
            tmp = tosym((objname + "_") + tostr(child_index));
        }
        suffix = tostr(child_index);
    }
    return suffix;
};

public method ._display_ancestors() {
    arg space, checked, levels, maxlev;
    var c, anc, list, id, perms;
    
    id = ((space + this()) + " ") + ($object_lib.see_perms(this()));
    for anc in (dict_keys(checked)) {
        if (.has_ancestor(anc))
            return [];
    
        // [id + "  (above)"];
    }
    if (((.parents()).length()) > 1)
        id += " (MI)";
    list = [id];
    space += "  ";
    levels++;
    
    // check parents
    if ((!maxlev) || (maxlev != levels)) {
        for c in (.parents()) {
            list += c._display_ancestors(space, checked, levels, maxlev);
            checked = dict_add(checked, c, 1);
            pause();
        }
    }
    return list;
};

public method .format_descendants() {
    arg ind, done, depth, max, yes, no, above;
    var c, anc, list, id, perms, f, show, myflags;
    
    myflags = .flags();
    show = 1;
    if (yes) {
        for f in (yes) {
            if (!(f in myflags)) {
                show = 0;
                break;
            }
        }
    }
    if (no) {
        for f in (myflags) {
            if (f in no) {
                show = 0;
                break;
            }
        }
    }
    if (show) {
        id = ((ind + this()) + " ") + ($object_lib.see_perms(this()));
        for anc in (dict_keys(done)) {
            if (has_ancestor(anc))
                return above ? [id + " (ABOVE)"] : [];
        }
        if (listlen(parents()) > 1)
            id += " (MI)";
        list = [id];
    } else {
        list = [];
    }
    ind += "  ";
    depth++;
    
    // check children
    if ((!max) || (max != depth)) {
        for c in (children()) {
            list += c.format_descendants(ind, done, depth, max, yes, no, above);
            done = dict_add(done, c, 1);
            pause();
        }
    }
    return list;
};

public method .undefine_setting(): nooverride {
    arg name;
    var d;
    
    (> .perms(sender()) <);
    if (!((.defined_settings()).contains(name)))
        throw(~setnf, (("Setting \"" + name) + "\" is not defined by ") + this());
    
    // clear it on all descendants, then us
    for d in ((.descendants()) + [this()]) {
        d._clear_setting(name);
        pause();
    }
    
    // bye bye
    defined_settings = dict_del(defined_settings, name);
    if (!defined_settings)
        clear_var('defined_settings);
};

public method .define_setting(): nooverride {
    arg name, @info;
    var i;
    
    (> .perms(sender()) <);
    if (info) {
        info = info[1];
        for i in (info) {
            if (!(> .valid_setting_attr(@i) <))
                info = dict_del(info, i[1]);
        }
    } else {
        info = #[];
    }
    if ((.all_defined_settings()).contains(name))
        throw(~setexists, ("Setting \"" + name) + "\" is already defined.");
    if (!($code_lib.valid_setting_id(name)))
        throw(~setbad, ("Setting name \"" + name) + "\" is unacceptable.");
    defined_settings = (.defined_settings()).add(name, info);
    return defined_settings[name];
};

public method .all_defined_settings(): nooverride {
    if (!(.has_flag('variables, sender())))
        throw(~perm, ((sender().namef('ref)) + " does not have permission to view settings on ") + (.name('ref)));
    return ._all_defined_settings();
};

public method .defined_settings(): nooverride {
    return defined_settings || #[];
};

public method .settings(): nooverride {
    (> .perms(sender()) <);
    return settings || #[];
};

public method .setting_info(): nooverride {
    arg setting;
    
    return defined_settings[setting];
};

public method .get_setting(): nooverride {
    arg name, definer;
    var i;
    
    i = definer.setting_info(name);
    if (dict_contains(i, 'access))
        (> .((i['access])[1])(name, sender(), caller(), @sublist(i['access], 2)) <);
    if (dict_contains(i, 'get))
        return (> .((i['get])[1])(name, definer, @sublist(i['get], 2)) <);
    catch any
        return settings[name];
    with
        return (> definer.get_default_setting(name) <);
};

public method .get_default_setting(): nooverride {
    arg name;
    
    return settings[name];
};

public method .clear_setting(): nooverride {
    arg name, definer;
    var info, args;
    
    (caller() == definer()) || (> .perms(sender()) <);
    info = (> definer.setting_info(name) <);
    if (dict_contains(info, 'clear)) {
        args = sublist(info['clear], 2);
        (> .((info['clear])[1])(name) <);
    } else if (settings && dict_contains(settings, name)) {
        settings = dict_del(settings, name);
        if (!settings)
            clear_var('settings);
    }
};

public method .format_setting(): nooverride {
    arg name, definer, value;
    var i, args;
    
    i = definer.setting_info(name);
    if (dict_contains(i, 'format)) {
        args = sublist(i['format], 2);
        catch ~methodnf
            return (> .((i['format])[1])(value, @args) <);
        with
            return (> $settings.((i['format])[1])(value, @args) <);
    }
    if (type(value) == 'objnum)
        return value.namef('ref);
    else
        return "" + value;
};

public method .set_setting_attr(): nooverride {
    arg name, attr, value;
    var info;
    
    (> .perms(sender()) <);
    if ((!defined_settings) || (!dict_contains(defined_settings, name)))
        throw(~setnf, (("Setting \"" + name) + "\" is not defined on ") + this());
    if (value && (!(> .valid_setting_attr(attr, value) <)))
        return;
    info = defined_settings[name];
    if (!value)
        info = dict_del(info, attr);
    else
        info = dict_add(info, attr, value);
    defined_settings = dict_add(defined_settings, name, info);
};

public method .get_setting_attr(): nooverride {
    arg name, attr;
    
    return (defined_settings[name])[attr];
};

public method .setting_definer(): nooverride {
    arg name;
    var a;
    
    for a in (ancestors()) {
        if (dict_contains(a.defined_settings(), name))
            return a;
    }
    throw(~setnf, ("Setting \"" + name) + "\" is not defined.");
};

public method .set_setting(): nooverride {
    arg name, definer, value;
    var i, args;
    
    (> .perms(sender()) <);
    i = (> definer.setting_info(name) <);
    if (dict_contains(i, 'parse)) {
        args = sublist(i['parse], 2);
        if ((| find_method((i['parse])[1]) |))
            value = (> .((i['parse])[1])(value, @args) <);
        else
            value = (> $settings.((i['parse])[1])(value, @args) <);
    }
    if (dict_contains(i, 'set))
        (> .((i['set])[1])(name, definer, value, @sublist(i['set], 2)) <);
    else
        settings = dict_add(settings || #[], name, value);
};

public method .valid_setting_attr(): nooverride {
    arg name, value;
    
    if (!(name in ['get, 'set, 'parse, 'clear, 'format, 'access]))
        throw(~setattr, "Invalid setting attribute '" + name);
    if (!value)
        return 0;
    else if (type(value) != 'list)
        throw(~setattr, "Setting attribute must be a list");
    else if (type(value[1]) != 'symbol)
        throw(~setattr, "Setting attribute[1] is not a symbol");
    return 1;
};

private method ._clear_setting(): nooverride {
    arg name;
    
    if (settings && dict_contains(settings, name)) {
        settings = dict_del(settings, name);
        if (!settings)
            clear_var('settings);
    }
};

public method .get_local_setting(): nooverride {
    arg name, definer;
    var i;
    
    i = definer.setting_info(name);
    if (dict_contains(i, 'access))
        (> .((i['access])[1])(name, sender(), caller(), @sublist(i['access], 2)) <);
    return (| settings[name] |) || (> definer.get_default_setting(name) <);
};

protected method ._all_defined_settings(): nooverride {
    var a, all, d;
    
    all = #[];
    for a in (ancestors()) {
        catch any {
            for d in (dict_keys(a.defined_settings()))
                all = dict_add(all, d, a);
        }
    }
    return all;
};

public method .ancestors_descending() {
    arg obj;
    var anc;
    
    return filter anc in (.ancestors()) where (anc.has_ancestor(obj));
};

public method .anc2(): nooverride {
    var i, c, parent, d;
    
    d = #[];
    for parent in (parents())
        d = dict_add(d, parent, 1);
    while ((| (c = dict_keys(d)[++i]) |)) {
        for parent in (c.parents()) {
            pause();
            d = dict_add(d, parent, 1);
        }
        pause();
    }
    return dict_keys(d);
};

root method .core_root() {
    (| clear_var('child_index) |) || (child_index = 0);
};

protected method .set_help_node_setting() {
    arg name, definer, value;
    
    if (!value)
        (| clear_var('help_node) |);
    else
        help_node = value;
};

public method .format_help_node_setting() {
    arg node;
    
    if (node)
        return node.namef('ref);
    return "";
};

public method .release_semaphore(): nooverride {
    arg type;
    
    if ((| (semaphores[type]) == task_id() |))
        semaphores = dict_del(semaphores, type);
    if (!semaphores)
        clear_var('semaphores);
};

public method .poll_semaphore(): nooverride {
    arg type;
    var t;
    
    if (!(caller().has_flag('core)))
        return;
    while (1) {
        if (!semaphores) {
            semaphores = #[[type, task_id()]];
            return;
        }
        if ((type((| (t = semaphores[type]) |)) == 'error) || (!(t in tasks()))) {
            semaphores = dict_add(semaphores, type, task_id());
            return;
        }
        pause();
        pause();
        pause();
    }
};

public method .query_semaphore() {
    arg type;
    var t;
    
    return (type((| (t = semaphores[type]) |)) != 'error) && ((t in tasks()) && (t != task_id()));
};

public method .poll_semaphores() {
    arg type, @s;
    var i;
    
    if (!(caller().has_flag('core)))
        return;
    refresh();
    while (find i in (s) where (i.query_semaphore(type))) {
        pause();
        pause();
        pause();
    }
    for i in (s)
        i.poll_semaphore(type);
};

public method .nop() {
    // the no operation, operation, woowoo
};

public method .credit() {
    var line;
    
    if ('core in (flags || [])) {
        line = "Created ";
        if ((.created_on()) > 0)
            line += ($time.format("%d-%h-%Y", .created_on())) + " ";
        line = [line + "as a part of ColdCore, see: @help Credit"];
    } else {
        line = [];
    }
    if (credit)
        return credit + line;
    return line;
};

public method .set_credit() {
    arg newcopy;
    var x;
    
    (> .perms(sender(), 'manager) <);
    if (newcopy == 0)
        return (| clear_var('credit) |);
    if ((type(newcopy) != 'list) || find x in (newcopy) where (type(x) != 'string))
        throw(~type, "You must submit a list of strings for the credit.");
    credit = newcopy;
};

public method .write_check(): nooverride {
    arg obj;
    
    if (.is($group))
        return .includes(obj);
    else
        return this() == obj;
};

root method .pass_test() {
    return "YYYYYYY";
};


object $sys: $root;

var $sys admins = [];
var $sys agents = [$root, $daemon];
var $sys startup = #[['objects, [$login_daemon, $http_daemon, $smtp_daemon, $world, $dns, $lag_watcher]], ['heartbeat_interval, 2]];
var $sys starting = #[['quota, 76800], ['new_user_class, $admin], ['anonymous_user_class, $guest]];
var $root defined_settings = #[["loggers", #[['get, ['loggers]], ['set, ['set_loggers]], ['parse, ['parse_itemlist, 'parse_object]], ['format, ['format_itemlist]]]], ["deny-hosts", #[['get, ['deny_hosts]], ['set, ['set_deny_hosts]], ['parse, ['parse_itemlist, 'parse_deny_host]], ['format, ['format_itemlist]]]], ["deny-users", #[['get, ['deny_users]], ['set, ['set_deny_users]], ['parse, ['parse_itemlist, 'parse_deny_user]], ['format, ['format_itemlist]]]], ["backup-interval", #[['get, ['get_backup_interval]], ['set, ['set_backup_interval]], ['parse, ['parse_backup_interval]], ['format, ['fmt_backup_interval]]]], ["validate-email-addresses", #[['parse, ['is_boolean]], ['format, ['format_boolean]], ['get, ['validate_email_addresses]], ['set, ['set_validate_email_addresses]]]], ["initial-quota", #[['get, ['get_initial_quota]], ['set, ['set_initial_quota]], ['parse, ['parse_initial_quota]], ['format, ['fmt_initial_quota]]]], ["new-user-class", #[['get, ['get_new_user_class]], ['set, ['set_new_user_class]], ['parse, ['parse_new_user_class]], ['format, ['format_object]]]], ["anonymous-user-class", #[['get, ['get_anon_user_class]], ['set, ['set_anon_user_class]], ['parse, ['parse_anon_user_class]], ['format, ['format_object]]]], ["startup-objects", #[['get, ['get_startup_objects]], ['set, ['set_startup_objects]], ['parse, ['parse_itemlist, 'parse_startup_object]], ['format, ['format_itemlist]]]], ["writable-core", #[['get, ['writable_core]], ['set, ['set_writable_core]], ['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["valid-genders", #[['parse, ['parse_itemlist, 'parse_valid_genders]], ['get, ['get_valid_genders]], ['set, ['set_valid_genders]], ['format, ['format_itemlist]]]], ["heartbeat-interval", #[['get, ['get_heartbeat_interval]], ['set, ['set_heartbeat_interval]], ['parse, ['parse_heartbeat_interval]], ['format, ['fmt_heartbeat_interval]]]], ["traceback-for", #[['parse, ['parse_traceback_for_setting]]]]];
var $sys core_version = "3.1";
var $sys validate_email_addresses = 0;
var $sys backup = #[['interval, 3600], ['last, 0], ['next, 0]];
var $sys system = [$sys, $root];
var $sys touched = 0;
var $sys loggers = [$daemon, $user, $connection, $dns, $guest];
var $root created_on = 796268969;
var $root inited = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root quota_exempt = 1;
var $root manager = $sys;
var $sys bindings = #[['atomic, $sys], ['create, $sys], ['backup, $sys], ['shutdown, $sys], ['set_heartbeat, $sys], ['cancel, $scheduler], ['task_info, $scheduler], ['execute, $sys], ['bind_function, $sys], ['unbind_function, $sys], ['bind_port, $daemon], ['unbind_port, $daemon], ['open_connection, $connection], ['reassign_connection, $daemon], ['fopen, $file], ['fstat, $file], ['fchmod, $file], ['fmkdir, $file], ['frmdir, $file], ['files, $file], ['fremove, $file], ['frename, $file], ['fclose, $file], ['fseek, $file], ['feof, $file], ['fwrite, $file], ['fread, $file], ['fflush, $file], ['chparents, $root], ['destroy, $root], ['dblog, $sys], ['add_var, $root], ['del_var, $root], ['variables, $root], ['list_method, $root], ['add_method, $root], ['del_method, $root], ['method_bytecode, $root], ['methods, $root], ['rename_method, $root], ['set_method_access, $root], ['set_method_flags, $root], ['data, $root], ['del_objname, $root], ['set_objname, $root], ['suspend, $scheduler], ['resume, $scheduler], ['set_user, $user], ['config, $sys], ['cache_info, $sys]];
var $root managed = [$sys];
var $sys deny_hosts = [];
var $sys deny_users = [];
var $sys writable_core = 0;
var $sys valid_genders = [$gender_male, $gender_female, $gender_neuter];
var $sys configured = #[];
var $sys config_set = ['new_user_class, 'server_name, 'server_title, 'daemons];
var $root settings = #[["traceback-for", $builder]];

public method .next_objnum(): native;

public method .version(): native;

driver method .startup() {
    arg args;
    var opt, str, obj, f, ver, firsttime, doinit;
    
    set_heartbeat(0);
    
    // clean db?
    if ("-clean" in args) {
        catch any {
            dblog("** Cleaning Database..");
            (> .clean_database() <);
            dblog("** Done.");
            if (dict_contains(startup, 'time))
                startup = dict_del(startup, 'time);
        } with {
            .log($parse_lib.traceback(traceback()));
        }
        doinit = "-init" in args;
    } else {
        doinit = ("-init" in args) || (!dict_contains(startup, 'time));
    }
    
    // init?
    if (doinit) {
        catch any {
            dblog("** Initializing Database..");
            (> .init_database() <);
            dblog("** Done.");
        } with {
            .log($parse_lib.traceback(traceback()));
        }
    }
    
    // done?
    if ("-quit" in args) {
        dblog("** Shutting down.");
        .shutdown();
        return;
    }
    
    // make core?
    if ((opt = find opt in (args) where (opt.match_begin("-makecore=")))) {
        ver = regexp(args[opt], "-MAKECORE=(.*)$")[1];
        dblog(("** Calling .make_core(\"" + ver) + "\")..");
        .make_core(ver);
        return;
    }
    
    // Standard startup..
    startup = startup.add('time, time());
    backup = backup.add('next, time() + (backup['interval]));
    
    // In case we're recovering from a backup
    if (dict_contains(backup, 'started))
        backup = dict_del(backup, 'started);
    catch any {
        // get back the heartbeat
        set_heartbeat(startup['heartbeat_interval]);
    
        // Bind functions for security
        for f in (bindings) {
            catch any
                bind_function(@f);
            with
                dblog((("** Unable to bind function " + (f[1])) + "() to ") + (f[2]));
        }
    
        // tell objects who should know, that we are online
        if (type(args) != 'list)
            args = [];
        for obj in (startup['objects]) {
            .log(("Calling " + obj) + ".startup()");
            catch any
                (> obj.startup(@args) <);
            with
                .log($parse_lib.traceback(traceback()));
        }
    } with {
        .log(("** Startup ERROR at " + ctime()) + ":");
        .log(toliteral(traceback()));
        .log($parse_lib.traceback(traceback(), -1, ""));
    }
};

public method .server_info() {
    arg what, @long;
    var tmp;
    
    switch (what) {
        case 'up_time:
            return time() - (startup['time]);
        case 'startup_time:
            return startup['time];
        case 'server_hostname:
            return $dns.hostname("");
        case 'server_ip:
            return $dns.ip("");
        case 'last_backup:
            return backup['last];
        case 'driver_version:
            tmp = .version();
            return (((((((long ? "Genesis " : "") + (tmp[1])) + ".") + (tmp[2])) + ".") + (tmp[3])) + "-") + ((listlen(tmp) == 3) ? "NEED TO UPGRADE" : (tmp[4]));
        case 'core_version:
            return (long ? "ColdCore " : "") + core_version;
        case 'version:
            tmp = .version();
            return ((((((((("Genesis/" + (tmp[1])) + ".") + (tmp[2])) + ".") + (tmp[3])) + "-") + (tmp[4])) + " ") + "ColdCore/") + core_version;
        default:
            throw(~unknown, "Unknown flag.");
    }
};

public method .create_user() {
    arg name, password, email, @type;
    var user;
    
    if ((!(| caller() == $login_interface |)) && (type((| .perms(sender(), 'system) |)) == 'error))
        throw(~perm, "Caller and Sender are not allowed to call this method.");
    [(type ?= 'new_user_class)] = type;
    catch any {
        user = (starting[type]).spawn(name);
        user.set_name(name);
        if (type == 'new_user_class)
            user.set_password(password);
        user.change_manager(user);
        user.set_user_info("rl-email", $user_info, email);
    } with {
        // Failed to initialize the child; destroy it.
        (| user.destroy() |);
        rethrow(error());
    }
    return user;
};

public method .admins() {
    return admins;
};

public method .is_admin() {
    arg obj;
    
    return (obj == $sys) || (obj in admins);
};

public method .shutdown() {
    var opt, str, obj;
    
    (> .perms(sender(), $sys) <);
    
    // tell startup objects that we are closing shop
    for obj in (startup['objects]) {
        .log(("Calling " + obj) + ".shutdown()");
        catch any
            (> obj.shutdown() <);
        with
            .log($parse_lib.traceback(traceback()));
    }
    touched = 0;
    return shutdown();
};

public method .spawn_sender() {
    arg suffix, manager;
    var namestr;
    
    (> .perms(caller(), $root, $sys) <);
    namestr = (tostr(sender().objname()) + "_") + suffix;
    return .create([sender()], tosym(namestr), manager);
};

public method .is_system() {
    arg obj;
    
    return obj in system;
};

private method ._logstr() {
    arg str;
    
    dblog((("[" + ($time.format("%d %b %y %H:%M"))) + "] ") + str);
};

public method .log_traceback(): forked {
    arg traceback, @command;
    var user, log, mail, l, s;
    
    if ((!($syslog_group.includes(caller()))) && (!(.is_writable_by(sender()))))
        throw(~perm, "Permission denied.");
    [(command ?= "")] = command;
    user = user() || sender();
    log = "Last Command: " + command;
    log = [log, ("User: " + user()) || sender()];
    if (type(traceback[1]) != 'string)
        traceback = $parse_lib.traceback(traceback);
    s = (user() || sender()) + ": received traceback";
    log += traceback;
    if ('__making_core in (.variables()))
        .log(log);
    else
        $no_one.mail_as(0, 0, s, log, $mail_list_tracebacks);
};

public method .slog() {
    arg msg;
    var l;
    
    if ((!($syslog_group.includes(caller()))) && (!(.is_writable_by(sender()))))
        throw(~perm, "Only objects in the $syslog_group can log.");
    if (type(msg) == 'list) {
        for l in (msg)
            .slog(l);
    } else {
        $channel_ui._broadcast('System, msg);
        ._logstr(msg);
    }
};

driver method .heartbeat() {
    (| $scheduler.pulse() |);
    if (time() > (backup['next]))
        .do_backup(this(), 'interval);
};

public method .do_backup() {
    arg @args;
    var line, who, how, name, dirty;
    
    (> .perms(sender(), 'system) <);
    if (dict_contains(backup, 'started)) {
        .log("BACKUP CONFLICT");
        line = "BACKUP CONFLICT at " + ($time.format("%I:%M:%S %p"));
        line += ", Current backup started at " + ($time.format("%I:%M:%S %p", backup['started]));
        $channel_ui._broadcast('System, line);
        return;
    }
    dirty = .dirty();
    [(who ?= sender()), (how ?= 'request)] = args;
    if (!valid(who))
        who = sender();
    backup = backup.add('next, time() + (backup['interval]));
    backup = backup.add('last, time());
    if ((how == 'interval) && (!dirty))
        return;
    catch any {
        name = who.namef('ref);
        .log(("BACKUP (" + name) + ") ");
        line = (("Backup started at " + ($time.format("%I:%M:%S %p"))) + " by ") + name;
        $channel_ui._broadcast('System, line);
    }
    
    // double pause will hopefully let people know about it before it happens
    pause();
    pause();
    backup = backup.add('started, time());
    (> backup() <);
};

public method .set_startup() {
    arg what, value;
    var valid;
    
    (> .perms(sender(), 'system) <);
    valid = startup.keys();
    if ((!what) in valid)
        throw(~type, "Key must be one of " + toliteral(valid));
    startup = startup.add(what, value);
};

public method .host_denied() {
    arg remote;
    var t;
    
    for t in (deny_hosts) {
        if (match_begin(remote, t) != 0)
            return 1;
    }
    return 0;
};

public method .new_admin() {
    if (caller() != $admin)
        throw(~perm, "Caller is not $admin.");
    admins = setadd(admins, sender());
};

public method .agents() {
    return agents;
};

public method .get_startup() {
    arg what;
    
    return startup[what];
};

public method .set_starting() {
    arg what, value;
    var valid;
    
    (> .perms(sender(), 'system) <);
    valid = starting.keys();
    if ((!what) in valid)
        throw(~type, "Key must be one of " + toliteral(valid));
    starting = starting.add(what, value);
};

public method .execute() {
    arg script, args, @background;
    
    (> .perms(sender(), 'system) <);
    (> execute(script, args, @background) <);
};

public method .get_starting() {
    arg what;
    
    return starting[what];
};

private method .create() {
    arg parents, name, manager;
    var new;
    
    new = create(parents);
    catch any {
        new.initialize();
    
        // niggle the names around... $has_name may have initted the wrong name
        new.set_objname(name);
        if ((new.has_ancestor($has_name)) && ((new.name()) == ("#" + (new.objnum())))) {
            catch ~invname
                new.set_name(substr(tostr(new), 2));
        }
    
        // let it manage itself
        new.change_manager(manager);
    } with {
        // Failed to initialize the child; destroy it.
        $sys.log_traceback(traceback(), ((((("CREATE (" + parents) + ", '") + name) + ", ") + manager) + ")");
        (| new.destroy() |);
        rethrow(error());
    }
    return new;
};

public method .system() {
    return system;
};

public method .deny_hosts() {
    arg @args;
    
    return deny_hosts;
};

protected method .set_loggers() {
    arg name, definer, value;
    
    switch (value[1]) {
        case 'set:
            loggers = value[2];
        case 'add:
            loggers = setadd(loggers, value[2]);
        case 'del:
            loggers = setremove(loggers, value[2]);
        default:
            throw(~type, "Unknown action: " + (value[1]));
    }
};

public method .add_method() {
    arg code, name, @evalonly;
    var line;
    
    (> .perms(sender()) <);
    line = (("SYSTEM: ." + tostr(name)) + "() ") + (evalonly ? "EVAL" : "MODIFIED");
    line = (line + " by ") + (sender().namef('ref));
    .log(line);
    return (> pass(code, name, @evalonly) <);
};

public method .atomic() {
    arg @args;
    
    (> .perms(sender(), 'system) <);
    return (> atomic(@args) <);
};

public method .fmt_backup_interval() {
    arg data;
    
    return $time.to_english(data);
};

public method .get_backup_interval() {
    arg @args;
    
    return backup['interval];
};

public method .validate_email_addresses() {
    arg @args;
    
    return validate_email_addresses;
};

public method .parse_backup_interval() {
    arg value, @args;
    
    value = (> $time.from_english(value) <);
    if (value < 300)
        throw(~perm, "You cannot set your backup interval to less than 5 minutes");
    return value;
};

driver method .signal() {
    arg signal;
    var line;
    
    // the driver will send the following signals:
    //   HUP  -- driver will drop out of atomic mode and will flush i/o
    //   USR2 -- driver does nothing
    //   USR1 -- driver aborts all currently executing tasks, not suggested
    //   QUIT -- For both of these the driver will shutdown after current
    //   INT     tasks finish their current execution frame.  Note: do not
    //           preempt tasks at this point as they will not resume.
    line = ("** Received Signal: " + signal) + " **";
    (| $channel_ui._broadcast('System, line) |);
    if (signal in ['QUIT, 'INT]) {
        (| $channel_ui._broadcast('all, "******************************") |);
        (| $channel_ui._broadcast('all, "** IMMINENT SERVER SHUTDOWN **") |);
        (| $channel_ui._broadcast('all, "******************************") |);
    }
};

root method .sender_going_away() {
    admins = admins.setremove(sender());
    agents = agents.setremove(sender());
    system = system.setremove(sender());
};

public method ._status(): native;

bind_native .status() ._status();

public method .status() {
    return (> ._status() <) + [backup['interval], backup['last], backup['next]];
};

private method ._loop_for_core() {
    arg code;
    var obj;
    
    $root.add_method(code, '___coretmp);
    for obj in ($root.descendants()) {
        obj.___coretmp();
        pause();
    }
    $root.del_method('___coretmp);
};

private method .initialize_core() {
    var obj;
    
    (| .clean_database() |);
    
    // reset child indices
    ._loop_for_core(["child_index = 0;"]);
};

private method .clean_database() {
    var obj, p, c, cmd;
    
    // cleanup some of $root's messiness
    for obj in ($root.descendants()) {
        (| obj.clean_root() |);
        refresh();
    }
    
    // purge all command caches
    for obj in ($command_cache.descendants()) {
        (| obj.purge_cache() |);
        refresh();
    }
    
    // check user info (move'em home etc)
    for obj in ($user.descendants()) {
        if ((| (obj.home()) != (obj.location()) |))
            (| obj.move_to(obj.home()) |);
        refresh();
    }
    
    // validate all locations and location content's
    for obj in ($physical.descendants()) {
        (| obj.validate_contents() |);
        if (obj.has_ancestor($located)) {
            if ((!valid(obj.location())) || (!(obj in ((obj.location()).contents()))))
                (| obj.move_to((| obj.home() |) || $lost_and_found) |);
        }
        refresh();
    }
};

protected method .set_backup_interval() {
    arg name, definer, value;
    
    backup = backup.add('interval, value);
};

public method .add_to_system() {
    arg obj;
    
    if (!(.is_admin(sender())))
        throw(~perm, "Sender is not an admin.");
    if (!((obj in admins) || (obj in agents)))
        throw(~perm, "Object is not an agent or admin.");
    system = setadd(system, obj);
};

public method .del_from_system() {
    arg obj;
    
    if (!(.is_admin(sender())))
        throw(~perm, "Sender is not an admin.");
    if (!((obj in admins) || (obj in agents)))
        throw(~perm, "Object is not an agent or admin.");
    system = setremove(system, obj);
};

public method .touch() {
    arg @nocorelock;
    
    if ((!nocorelock) && ((sender().has_flag('core)) && (!writable_core)))
        throw(~perm, sender() + " is a core object, and the core isn't writable. '@set $sys:writable-core = yes' to allow this.");
    touched = time();
};

public method .touched() {
    return touched;
};

public method .dirty() {
    return touched > (backup['last]);
};

public method .do_shutdown() {
    arg time, why;
    var increments, line, name, mins, secs;
    
    if ((!($sys.is_admin(sender()))) || (definer() != this()))
        throw(~perm, "Sender is not an admin.");
    increments = [600, 300, 180, 60];
    secs = time * 60;
    while (increments && (secs < (increments[1])))
        increments = increments.delete(1);
    if (increments && (secs > (increments[1])))
        increments = [secs] + increments;
    name = sender().namef('xref);
    .log(("*** SHUTDOWN called by " + name) + " ***");
    if (why) {
        why = ("*** REASON: " + why) + " ***";
        .log(why);
    }
    while (1) {
        if (!increments) {
            $channel_ui._broadcast('All, "*** SYSTEM SHUTDOWN ***");
            if (why)
                $channel_ui._broadcast('All, why);
            break;
        }
        line = "*** SYSTEM SHUTDOWN IN ";
        mins = (increments[1]) / 60;
        line = ((line + tostr(mins)) + " MINUTE") + ((mins == 1) ? "" : "S");
        line = ((line + " CALLED BY ") + name) + " ***";
        $channel_ui._broadcast('All, line);
        if (why)
            $channel_ui._broadcast('All, why);
        if ((increments.length()) > 1)
            $scheduler.sleep((increments[1]) - (increments[2]));
        else
            $scheduler.sleep(increments[1]);
        increments = increments.delete(1);
    }
    pause();
    pause();
    return .shutdown();
};

public method .loggers() {
    arg @args;
    
    return loggers;
};

root method .core_sys(): nooverride {
    deny_hosts = (deny_users = []);
    touched = 0;
    system = [$sys, $root];
    backup = #[['interval, 3600], ['last, 0], ['next, 0]];
    validate_email_addresses = 0;
    starting = #[['quota, 76800], ['new_user_class, $admin], ['anonymous_user_class, $guest]];
    startup = #[['objects, [$login_daemon, $http_daemon, $smtp_daemon, $world, $dns, $lag_watcher]], ['heartbeat_interval, 2]];
    agents = [$root, $daemon];
    admins = [];
    writable_core = 0;
    configured = #[];
};

driver method .backup_done() {
    var elapsed;
    
    elapsed = time() - (backup['started]);
    backup = backup.del('started);
    catch any {
        $channel_ui._broadcast('System, "Backup completed, elapsed time " + ($time.to_english(elapsed)));
        $channel_ui._broadcast('System, "Executing filesystem cleanup.. ");
        pause();
        pause();
        .execute("backup", []);
    }
};

private method .make_core() {
    arg ver;
    var obj, obj2, d, o, top, x, admin, tmp, name;
    
    // core rooms should be +core, and cant be destroyed
    // traverse the list inverseley, less unseen heirarchial shuffling
    .add_var('__making_core);
    dblog("** Starting Core Extraction " + ctime());
    d = $root.descendants();
    top = listlen(d);
    core_version = ver;
    dblog(("** " + top) + " objects total, tidying up core objects...");
    
    // tidy up core objects first
    for obj in (d) {
        refresh();
        if (obj.has_flag('core)) {
            tmp++;
            catch any {
                obj.change_manager(obj);
                for o in (obj.writers('literal)) {
                    refresh();
                    obj.del_writer(o);
                }
            } with {
                dblog(("** TIDY " + obj) + " traceback: ");
                for o in ($parse_lib.traceback(traceback()))
                    dblog("**   " + o);
            }
        }
    }
    
    // nuke anything not core
    dblog(("** " + tmp) + " core objects, destroying non-core objects...");
    for x in [1 .. top] {
        pause();
        obj = d[(top - x) + 1];
        if (!valid(obj)) {
            // dblog(".. Skipping invalid object " + obj);
            continue;
        }
        if (!(obj.has_flag('core))) {
            if (obj.children()) {
                for obj2 in (obj.children()) {
                    if (obj2.has_flag('core)) {
                        dblog("** ABORTING: A NON CORE OBJECT HAS CORE CHILDREN: ");
                        dblog((("** " + obj) + " => ") + (obj.children()));
                        shutdown();
                    }
                }
            }
            catch any {
                // dblog(".. Destroying " + obj);
                obj.destroy();
            } with {
                dblog(("** " + obj) + ".destroy() traceback: ");
                for o in ($parse_lib.traceback(traceback()))
                    dblog("**   " + o);
            }
        }
    }
    
    // shutdown this task so that references can have
    // a chance to clear out, on destroyed objects.
    dblog("** done, suspending for new task **");
    
    // do this the hard way, to be secure--wait a little while for
    // things to wrapup, five seconds should be fine.
    pause();
    set_heartbeat(5);
    .add_var('TMP_HEARTBEAT_CODE, .list_method('heartbeat));
    .add_method([".finish_core();"], 'heartbeat);
};

public method .task_info() {
    arg @args;
    
    (> .perms(sender(), 'system) <);
    return (> task_info(@args) <);
};

public method .destroy_sender() {
    // potential problem spot, but sometimes its needed
    // add core definer items to the list, if you want them to call it
    (> .perms(caller(), $path, $connection, $connection_interface) <);
    (> sender().destroy() <);
};

private method .finish_core() {
    var i;
    
    // cleanup heartbeat
    set_heartbeat(1);
    .add_method(TMP_HEARTBEAT_CODE, 'heartbeat);
    .del_var('TMP_HEARTBEAT_CODE);
    
    // ok, finish up
    catch any {
        dblog("** Verifying all non-core objects were destroyed");
        for i in ($root.descendants()) {
            refresh();
            if (!(i.has_flag('core)))
                dblog(("** !!!!! " + i) + " was not destroyed !!!!!");
        }
        .del_var('__making_core);
        dblog("** corifying remaining objects");
        $root.corify();
        dblog("** cleaning database..");
        .clean_database();
        dblog("** shutting down..");
        shutdown();
    } with {
        dblog("traceback: " + traceback());
    }
};

public method .old_admin() {
    if (caller() != $admin)
        throw(~perm, "Caller is not $admin.");
    admins = setremove(admins, sender());
    system = setremove(system, sender());
};

root method .clear_definer_vars(): nooverride {
    arg definer, objs;
    var code, v, a, meth, errs, d;
    
    code = [];
    for v in (definer.variables())
        code += [("(| clear_var('" + v) + ") |);"];
    meth = tosym("_root_tmp_" + time());
    if (!(definer.add_method(code, meth, 1))) {
        for d in (objs) {
            pause();
            (| d.(meth)() |);
        }
        (| definer.del_method(meth) |);
    }
};

public method .spawn_selfmanager() {
    arg name, @writers;
    var obj, w;
    
    // Differs from .spawn_sender in that the object created manages itself.  
    // Add to this list as necessary:
    (> .perms(sender(), $mail_message) <);
    obj = (> .create([sender()], name, this()) <);
    for w in (writers)
        obj.add_writer(w);
    obj.change_manager(obj);
    return obj;
};

private method .init_database() {
    var obj, p, c, cmd, other;
    
    // re-init caches
    $remote_cache.rehash_cache();
    
    // only rehash non-general caches--general caches should be initialized
    // as they are needed, by .cache_server_init().
    other = ($command_cache.children()).setremove($user_interfaces);
    other = ((other.mmap('descendants)).flatten()).compress();
    for obj in (filter obj in (other) where (!(obj.is_general_cache()))) {
        (| obj.rehash_cache() |);
        refresh();
    }
};

public method .startup_dnsserv() {
    if (sender() != $dns)
        (> .perms(sender(), 'system) <);
    execute("dnsstartup", [], 1);
};

protected method .set_deny_hosts() {
    arg name, definer, value;
    
    switch (value[1]) {
        case 'set:
            deny_hosts = value[2];
        case 'add:
            deny_hosts = setadd(deny_hosts, value[2]);
        case 'del:
            deny_hosts = setremove(deny_hosts, value[2]);
        default:
            throw(~type, "Unknown action: " + (value[1]));
    }
};

public method .parse_deny_host() {
    arg value, @args;
    var parts;
    
    // DNS Hostnames are not used due to the extreme slowdown it would
    // cause to _ALL_ services
    if (match_regexp(value, "[^0-9.]"))
        throw(~type, "Invalid Internet Host IP address or subnet: " + value);
    parts = explode(value, ".");
    if (listlen(parts) < 2)
        throw(~type, "Do you really want to deny an entire class A network?");
    if (listlen(parts) > 4)
        throw(~type, "Invalid IP Address: " + (parts.join(".")));
    return parts.join(".");
};

public method .deny_users() {
    arg @args;
    
    return deny_users;
};

public method .user_denied() {
    arg user;
    
    return user in deny_users;
};

protected method .set_deny_users() {
    arg name, definer, value;
    
    switch (value[1]) {
        case 'set:
            deny_users = value[2];
        case 'add:
            deny_users = setadd(deny_users, value[2]);
        case 'del:
            deny_users = setremove(deny_users, value[2]);
        default:
            throw(~type, "Unknown action: " + (value[1]));
    }
};

public method .parse_deny_user() {
    arg value, @args;
    var obj;
    
    if (value && ((value[1]) == "$")) {
        obj = (> $object_lib.to_dbref(value) <);
        if (!(obj.is($user)))
            throw(~perm, (obj.namef('ref)) + " is not a user.");
    } else {
        obj = (> $user_db.search(value) <);
    }
    return obj;
};

protected method .set_validate_email_addresses() {
    arg name, definer, value;
    
    validate_email_addresses = value;
};

public method .fmt_initial_quota() {
    arg data;
    
    return data.to_bytes();
};

public method .get_initial_quota() {
    arg @args;
    
    return starting['quota];
};

public method .parse_initial_quota() {
    arg value, @args;
    
    value = (> value.to_bytes() <);
    if (value < 1024)
        throw(~perm, "You cannot set your initial quota to less than 1 kb");
    return value;
};

protected method .set_initial_quota() {
    arg name, definer, value;
    
    starting = starting.add('quota, value);
};

public method .get_new_user_class() {
    arg @args;
    
    return starting['new_user_class];
};

public method .parse_new_user_class() {
    arg value, @args;
    
    value = (> $object_lib.to_dbref(value) <);
    if (!(value.is($user)))
        throw(~perm, (value.namef('ref)) + " is not a $user object.");
    if (!(value.has_flag('command_cache)))
        throw(~perm, (value.namef('ref)) + " is not a command cache object.");
    return value;
};

protected method .set_new_user_class() {
    arg name, definer, value;
    
    starting = starting.add('new_user_class, value);
};

public method .get_anon_user_class() {
    arg @args;
    
    return starting['anonymous_user_class];
};

public method .parse_anon_user_class() {
    arg value, @args;
    
    value = (> $object_lib.to_dbref(value) <);
    if (!(value.is($user)))
        throw(~perm, (value.namef('ref)) + " is not a $user object.");
    if (!(value.has_flag('command_cache)))
        throw(~perm, (value.namef('ref)) + " is not a command cache object.");
    return value;
};

protected method .set_anon_user_class() {
    arg name, definer, value;
    
    starting = starting.add('anon_user_class, value);
};

protected method .set_startup_objects() {
    arg name, definer, value;
    
    switch (value[1]) {
        case 'set:
            startup = startup.add('objects, value[2]);
        case 'add:
            startup = startup.add('objects, setadd(startup['objects], value[2]));
        case 'del:
            startup = startup.add('objects, setremove(startup['objects], value[2]));
        default:
            throw(~type, "Unknown action: " + (value[1]));
    }
};

public method .configure_core() {
    var list, l, x, t, err, s;
    
    if (caller() != $admin)
        (> .perms(sender()) <);
    s = sender();
    
    // if there is nothing left to config, leave..
    if (configured) {
        if (!(list = config_set.set_difference(configured.keys())))
            return;
    } else {
        configured = #[];
    }
    .add_to_system(s);
    
    // wait for other things to finish printing messages to them
    pause();
    pause();
    
    // expand on this as we go
    s.tell(["*" * 78, strfmt("%78{*}c", " Welcome to ColdCore "), "*" * 78]);
    s.tell(("This is an interactive configuration system which any admin who connects (until it is completed) is sent through.  You must complete this configuration before you can do anything else.  You can skip a specific question at any time by typing '@skip'.  Suggested default values will be enclosed in square brackets.  Pressing enter without any value will use the default value.".wrap_lines(78)).mmap('center, 78));
    s.tell("*" * 78);
    
    // first question please
    if (!(configured.contains('new_user_class))) {
        s.tell("What class should new users be created as?  Available classes:");
        list = filter x in ($user.descendants()) where (('general_cache in (x.flags())) && (x != $guest));
        t = .get_new_user_class();
        list = map x in (list) to ((list == t) ? (x + " (current class)") : x);
        s.tell(list.prefix("    "));
        while (!l) {
            refresh();
            l = (> s.prompt(("New User Class [" + t) + "] ") <);
            if (l == "@skip") {
                s.tell("Skipping..");
                break;
            }
            if (l) {
                catch any {
                    l = $object_lib.to_dbref(l);
                    if (!(l in list))
                        s.tell("Invalid selection, try again.");
                } with {
                    s.tell(("Invalid selection '" + l) + "'");
                    continue;
                }
            } else {
                l = t;
            }
            .set_setting("new-user-class", $sys, l);
            configured = configured.add('new_user_class, 1);
            s.tell("New User Class set to: " + l);
        }
        s.tell(["", "You can set this at any time, with the command:"]);
        s.tell("  @set $sys:new-user-class=" + l);
    }
    refresh();
    
    // server name/title
    if (!(configured.contains('server_name))) {
        s.tell(["", "---"]);
        t = $motd.server_name();
        l = (> s.prompt(("What is your server name? [" + t) + "] ") <) || t;
        if (l == "@skip") {
            s.tell("Skipping..");
        } else {
            $motd.set_setting("server-name", $motd, l);
            configured = configured.add('server_name, 1);
            s.tell("Server name set to: " + l);
        }
        s.tell(["", "You can set this at any time, with the command:"]);
        s.tell("  @set $motd:server-name=" + l);
    }
    refresh();
    if (!(configured.contains('server_title))) {
        s.tell(["", "---"]);
        t = $motd.server_title();
        l = (> s.prompt(("What is your server title? [" + t) + "] ") <) || t;
        if (l == "@skip") {
            s.tell("Skipping..");
        } else {
            $motd.set_setting("server-title", $motd, l);
            configured = configured.add('server_title, 1);
            s.tell("Server title set to: " + l);
        }
        s.tell(["", "You can set this at any time, with the command:"]);
        s.tell("  @set $motd:server-title=" + l);
    }
    refresh();
    if (!(configured.contains('daemons))) {
        s.tell(["", "---"]);
        while (1) {
            refresh();
            list = ($daemon.children()).setremove($login_daemon);
            s.tell("Which network daemons do you want to have automatically startup,");
            s.tell("Other than $login_daemon.  Available daemons:");
            t = filter l in (startup['objects]) where (l.is($daemon));
            for l in (list) {
                if (l in t)
                    s.tell(strfmt("  %20s (auto starting)", l));
                else
                    s.tell("  " + l);
            }
            l = (> s.prompt(("Auto-Start: [" + (t.join(", "))) + "] ") <);
            if (l == "@skip") {
                s.tell("Skipping..");
                break;
            } else if (!l) {
                s.tell("Using existing daemons: " + (t.join(", ")));
                configured = configured.add('daemons, 1);
                break;
            } else {
                err = 0;
                for x in (l.explode_english_list()) {
                    catch any {
                        .set_setting("startup-objects", $sys, "+" + x);
                        s.tell(("Added " + x) + " as a startup daemon.");
                    } with {
                        s.tell(("Unable to add '" + x) + "' as a daemon:");
                        s.tell("=> " + ((traceback()[1])[2]));
                        err++;
                    }
                }
                if (!err) {
                    configured = configured.add('daemons, 1);
                    break;
                }
                s.tell("Errors occurred...");
            }
        }
        s.tell(["", "You can set this at any time, with the command:"]);
        s.tell("  @set $sys:startup-objects=OBJECTS...");
    }
    
    // Other things to add: HTTP Virtual Hosting info,
    // Let them know, if they actually saw anything..
    s.tell(["", strfmt("%79{*}c", " Configuration Complete ")]);
};

public method .parse_startup_object() {
    arg value, action, @args;
    
    value = (> $object_lib.to_dbref(value) <);
    if (action == 'del) {
        if (!(value in (startup['objects])))
            throw(~failed, ("The object '" + value) + "' is not set, and thus cannot be removed");
        return value;
    }
    return value;
};

public method .writable_core() {
    arg @args;
    
    return writable_core;
};

protected method .set_writable_core() {
    arg name, definer, value;
    
    writable_core = value;
};

protected method .set_valid_genders() {
    arg name, definer, value;
    
    switch (value[1]) {
        case 'set:
            valid_genders = value[2];
        case 'add:
            valid_genders = setadd(valid_genders, value[2]);
        case 'del:
            valid_genders = setremove(valid_genders, value[2]);
        default:
            throw(~type, "Unknown action: " + (value[1]));
    }
};

public method .get_valid_genders() {
    arg @ignored;
    
    return valid_genders;
};

public method .parse_valid_genders() {
    arg value, action, @args;
    var obj, kids, i;
    
    if (!(| (obj = $object_lib.to_dbref("gender_" + value)) |))
        (> (obj = $object_lib.to_dbref(value)) <);
    if (action == 'del) {
        if (!(obj in (.get_valid_genders())))
            throw(~set, ("The object '" + value) + "' is not set, and thus cannot be removed");
        return obj;
    }
    if (!(obj in ($gender.children())))
        throw(~set, ("The object '" + value) + "' is not a child of $gender");
    return obj;
};

public method .get_startup_objects() {
    arg @args;
    
    return startup['objects];
};

public method .cache_info() {
    return cache_info();
};

public method .fmt_heartbeat_interval() {
    arg data;
    
    return $time.to_english(data);
};

public method .get_heartbeat_interval() {
    arg @args;
    
    return startup['heartbeat_interval];
};

public method .parse_heartbeat_interval() {
    arg value, @args;
    
    value = (> $time.from_english(value) <);
    if (value < 1)
        throw(~set, "You cannot set the system heartbeat interval to less than 1 second");
    return value;
};

protected method .set_heartbeat_interval() {
    arg name, definer, value;
    
    startup = startup.add('heartbeat_interval, value);
    set_heartbeat(value);
};

public method .parse_traceback_for_setting() {
    arg value, @args;
    var obj;
    
    obj = (> $object_lib.to_dbref(value) <);
    if (!(obj.is($user)))
        throw(~invset, "Setting must be a user type class");
    if (!('general_cache in (obj.flags())))
        throw(~invset, "Setting must be a user class");
    return obj;
};

public method .log() {
    arg msg;
    var l;
    
    if ((!($syslog_group.includes(caller()))) && (!(.is_writable_by(sender()))))
        throw(~perm, "Only objects in the $syslog_group can log.");
    if (type(msg) == 'list) {
        for l in (msg)
            .log(l);
    } else {
        ._logstr(msg);
    }
};

public method .broadcast() {
    arg mesg;
    var s;
    
    // do better perms for this later; intended as a 'panic' type
    // message, generally for daemon process type stuff
    if (caller() != $http_interface)
        throw(~perm, "Sorry.");
    mesg = (("[" + caller()) + "] ") + mesg;
    return $channel_ui._broadcast('System, mesg);
};


new object $mutex: $root;

var $root manager = $mutex;
var $mutex locks = 0;
var $root flags = ['variables, 'methods, 'code, 'core, 'fertile];
var $root created_on = 858071384;
var $root inited = 1;
var $mutex suspended = 0;
var $mutex tasks = 0;
var $mutex queues = 0;
var $root help_node = $help_mutex;
var $root managed = [$mutex];

private method ._test_locks() {
    arg tid, values;
    var i;
    
    return filter i in (values) where (!(._test_lock(tid, i)));
};

private method ._add_to_lock() {
    arg tid, val;
    
    if ((| ((locks[val])[1]) == tid |))
        locks = locks.add(val, [tid, ((locks[val])[2]) + 1]);
    else
        locks = locks.add(val, [tid, 1]);
};

public method .release_all() {
    .release(@tasks[task_id()]);
};

private method ._del_from_lock() {
    arg tid, val;
    var i, l;
    
    if (((| (l = locks[val]) |)[1]) != tid)
        return;
    if ((l[2]) == 1) {
        (| (locks = locks.del(val)) |);
        ._del_from_queue(val);
    } else {
        locks = locks.add(val, [tid, (l[2]) - 1]);
    }
};

private method ._test_lock() {
    arg tid, val;
    var i;
    
    if ((| ((locks[val])[1]) != tid |)) {
        queues = queues.add(val, (| (queues[val]) + [tid] |) || [tid]);
        return 0;
    }
    return 1;
};

public method .release() {
    arg @values;
    var tid, t, vlist, i, obj;
    
    values ?= [0];
    tid = task_id();
    vlist = tasks[tid];
    for obj in (.descendants())
        obj.release(@values);
    for i in (values) {
        vlist = vlist.setremove(i);
        ._del_from_lock(tid, i);
    }
    if (vlist)
        tasks = tasks.add(tid, vlist);
    else
        tasks = tasks.del(tid);
};

public method .grab() {
    arg @values;
    var i, tid, l, obj;
    
    values ?= [0];
    tid = task_id();
    for obj in (.descendants())
        obj.grab(@values);
    tasks = tasks.add(tid, (| (tasks[tid]) + [values] |) || values);
    while (1) {
        if (!(l = ._test_locks(tid, values))) {
            for i in (values)
                ._add_to_lock(tid, i);
            return;
        } else {
            suspended = suspended.add(tid, l.length());
            $scheduler.suspend(this());
        }
    }
};

private method ._del_from_queue() {
    arg val;
    var tid, s, q;
    
    q = (| queues[val] |) || [];
    (| (queues = queues.del(val)) |);
    for tid in (q) {
        if ((s = suspended[tid]) == 1) {
            suspended = suspended.del(tid);
            (| $scheduler.resume(tid) |);
        } else {
            suspended = suspended.add(tid, s - 1);
        }
    }
};

public method .cleanup_dead_tasks() {
    var t, i, j;
    
    t = tasks();
    for i in (tasks.keys()) {
        if (!(i in t)) {
            for j in (tasks[i])
                ._del_from_lock(i, j);
            tasks = tasks.del(i);
        }
    }
};

root method .init_mutex() {
    tasks = (suspended = (queues = (locks = #[])));
};


new object $mutex_access: $mutex;

var $root manager = $mutex_access;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858089211;
var $root inited = 1;
var $root managed = [$mutex_access];


new object $mutex_mail: $mutex_access;

var $root manager = $mutex_mail;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858089236;
var $root inited = 1;
var $root managed = [$mutex_mail];


new object $mutex_vr: $mutex;

var $root manager = $mutex_vr;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858089305;
var $root inited = 1;
var $root managed = [$mutex_vr];


new object $mutex_building: $mutex_access, $mutex_vr;

var $root manager = $mutex_building;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858089261;
var $root inited = 1;
var $root managed = [$mutex_building];


new object $mutex_location: $mutex_access, $mutex_vr;

var $root manager = $mutex_location;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858089228;
var $root inited = 1;
var $mutex tasks = #[];
var $mutex locks = #[];
var $mutex queues = #[];
var $mutex suspended = #[];
var $root managed = [$mutex_location];


new object $dmi_data: $root;

var $root manager = $dmi_data;
var $dmi_data descriptions = #[];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 860904004;
var $root inited = 1;
var $root managed = [$dmi_data];
var $root credit = ["Bruce Mitchener, Jr <bruce@puremagic.com>"];

root method .init_dmi_data() {
    descriptions = #[];
};

root method .uninit_dmi_data() {
    var i;
    
    descriptions ?= #[];
    for i in (descriptions.keys())
        $interface_registry.del_description(this(), i);
    descriptions = 0;
};

public method .add_description_to_db() {
    arg method, description;
    
    if (caller() != $interface_registry)
        (> .perms(sender()) <);
    descriptions ?= #[];
    descriptions = (> descriptions.add(method, description) <);
};

public method .del_description_from_db() {
    arg method;
    
    if (caller() != $interface_registry)
        (> .perms(sender()) <);
    descriptions = (| descriptions.del(method) |);
};

public method .describe_method() {
    arg method;
    
    return (> descriptions[method] <);
};

public method .add_data_to_method() {
    arg method, identifier, @data;
    var method_data, identifier_data;
    
    (> .perms(sender()) <);
    method_data = (| descriptions[method] |) || #[];
    if ((data.length()) == 1) {
        method_data = method_data.add(identifier, @data);
    } else if ((data.length()) == 2) {
        identifier_data = (| method_data[identifier] |) || #[];
        identifier_data = identifier_data.add(data[1], data[2]);
        method_data = method_data.add(identifier, identifier_data);
    }
    descriptions = descriptions.add(method, method_data);
};

public method .del_data_from_method() {
    arg method, identifier, @data;
    var method_data, identifier_data;
    
    (> .perms(sender()) <);
    method_data = (| descriptions[method] |) || #[];
    if ((data.length()) == 0) {
        (| (method_data = method_data.del(identifier)) |);
    } else if ((data.length()) == 1) {
        identifier_data = (| method_data[identifier] |) || #[];
        (| (identifier_data = identifier_data.del(data[1])) |);
        method_data = method_data.add(identifier, identifier_data);
    }
    descriptions = descriptions.add(method, method_data);
};


new object $core: $root, $dmi_data;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root managed = [$core];
var $root manager = $core;

root method .core_group() {
    group = #[];
};


new object $libraries: $core;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root manager = $libraries;
var $root managed = [$libraries];


new object $dictionary: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $dictionary;
var $root managed = [$dictionary];

public method .to_list() {
    arg dict;
    var x;
    
    // merges into an associated list.
    return map x in (dict) to (x);
};

public method .values(): native;

public method .replace() {
    arg dict, key, value;
    
    // GOING AWAY!
    anticipate_assignment();
    return dict_add(dict, key, value);
};

public method .apply() {
    arg tdict, list;
    var x;
    
    // Apply a translation-dict to a list
    for x in [1 .. list.length()] {
        catch ~keynf
            list = list.replace(x, tdict[list[x]]);
    }
    return list;
};

public method .apply_to_keys() {
    arg tdict, dict;
    var x, newdict;
    
    // Apply a t-dict to the keys of a dict
    newdict = #[];
    for x in (dict) {
        catch ~keynf
            x = x.replace(1, tdict[x[1]]);
        newdict = newdict.add(@x);
    }
    return newdict;
};

public method .apply_to_values() {
    arg tdict, dict;
    var x, newdict;
    
    // Apply a t-dict to the values of a dict
    newdict = #[];
    for x in (dict) {
        catch ~keynf
            x = x.replace(2, tdict[x[2]]);
        newdict = newdict.add(@x);
    }
    return newdict;
};

public method .invert() {
    arg dict;
    var x;
    
    // Invert a dict keys and values
    return hash x in (dict) to ([x[2], x[1]]);
};

public method .add_elem() {
    arg dict, key, elem;
    var value;
    
    // Add an element to the list value of a dictionary key
    value = (| dict[key] |);
    if ((type(value) != 'list) && (type(value) != 'error))
        throw(~type, ((("Value for key " + key) + " (") + value) + ") is not a list.");
    anticipate_assignment();
    if (value) {
        // reduce references to 'value'
        dict = dict_add(dict, key, 0);
        value += [elem];
    } else {
        value = [elem];
    }
    return dict_add(dict, key, value);
};

public method .del_elem() {
    arg dict, key, elem;
    var value;
    
    value = (| dict[key] |);
    if ((type(value) != 'list) && (type(value) != 'error))
        throw(~type, ((("Value for key " + key) + " (") + value) + ") is not a list.");
    anticipate_assignment();
    dict = dict_add(dict, key, 0);
    value = setremove(value, elem);
    if (!value)
        return dict_del(dict, key);
    return dict_add(dict, key, value);
};

public method .add(): native;

public method .del(): native;

public method .keys(): native;

public method .contains(): native;

public method .to_trie() {
    arg dict;
    var i, trie;
    
    trie = $trie.new();
    for i in (dict) {
        trie = trie.add(i[1], i[2]);
        refresh();
    }
    return trie;
};

public method .union(): native;

public method .setadd_elem() {
    arg dict, key, elem;
    var value;
    
    value = (| dict[key] |);
    if ((type(value) != 'list) && (type(value) != 'error))
        throw(~type, ((("Value for key " + key) + " (") + value) + ") is not a list.");
    anticipate_assignment();
    if (value) {
        dict = dict_add(dict, key, 0);
        value = setadd(value, elem);
    } else {
        value = [elem];
    }
    return dict_add(dict, key, value);
};

public method .mmap() {
    arg list, method, @args;
    var x;
    
    // call 'method on each object, return results.
    return map x in (list) to (x.(method)(@args));
};

public method .to_dict() {
    arg dict;
    
    return dict;
};


new object $buffer: $libraries;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $buffer;
var $root managed = [$buffer];

public method .to_list() {
    arg buf;
    var i, list;
    
    return map i in [1 .. buflen(buf)] to (buf[i]);
};

public method .from_list() {
    arg list;
    var buf, i;
    
    // this differs from $list.to_buffer()
    buf = `[];
    for i in (list)
        buf += `[i];
    return buf;
};

public method .length(): native;

public method .to_string(): native;

public method .to_strings(): native;

public method .from_string(): native;

public method .from_strings(): native;

public method .replace(): native;

public method .subrange(): native;

public method .to_veil_pkts(): native;

public method .from_veil_pkts(): native;

public method .break_lines() {
    arg buf;
    var i, sub, out;
    
    // break a buffer by \r or \n but keep its sub contents as buffers
    out = [];
    while ((i = 10 in buf)) {
        sub = subbuf(buf, 1, i - 1);
        buf = subbuf(buf, i + 1);
        while ((i = 13 in sub)) {
            if (buflen(sub) == i)
                sub = subbuf(sub, 1, i - 1);
            else
                sub = subbuf(sub, 1, i - 1) + subbuf(sub, i + 1);
        }
        out += [sub];
    }
    if (buf) {
        while ((i = 13 in buf)) {
            if (buflen(buf) == i)
                buf = subbuf(buf, 1, i - 1);
            else
                buf = subbuf(buf, 1, i - 1) + subbuf(buf, i + 1);
        }
        if (buf)
            out += [buf];
    }
    return out;
};

public method .bufsub() {
    arg buf, a, b;
    var i, la, lb, lt;
    
    // do we need a builtin for this?
    // from Kipp's core (until I write a builtin--optimized by Brandon) 
    if ((a == b) || ((buflen(a) > buflen(buf)) || ((!a) || (!buf))))
        return buf;
    la = buflen(a);
    lb = buflen(b);
    lt = buflen(buf);
    i = 1;
    anticipate_assignment();
    while ((i <= buflen(buf)) && (i = bufidx(buf, a, i))) {
        buf = (subbuf(buf, 1, i - 1) + b) + subbuf(buf, i + la);
        i += lb;
    }
    return buf;
};


new object $string: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $string alphabet = "abcdefghijklmnopqrstuvwxyz";
var $string numbers = "0123456789";
var $string non_alphanumeric = "!@#$%^&*()_+-=~`'{}[]|/?\",.<>;: ";
var $root manager = $string;
var $string number_names = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
var $string base64str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var $root managed = [$string];

public method .left() {
    arg str, width, @fchar;
    
    // will not chop off 'str' if it is longer than width, use pad() for that.
    [(fchar ?= " ")] = fchar;
    if (strlen(str) < width)
        return str + pad("", width - (str.length()), fchar);
    return str;
};

public method .center() {
    arg text, width, @args;
    var fill, sides;
    
    // args[1] <op> == what to fill the left|right side with.
    // args[2] <op> == if exists also fill the right side.
    [(fill ?= " "), (sides ?= 'left)] = args;
    if (sides == 'both)
        return strfmt(("%*{" + fill) + "}c", width, text);
    else
        return pad("", (width - strlen(text)) / 2, fill) + text;
};

public method .trim(): native;

public method .right() {
    arg str, width, @fchar;
    
    // will not chop off 'str' if it is longer than width (unlike pad())
    [(fchar ?= " ")] = fchar;
    if (strlen(str) < width)
        return pad(str, -width, fchar);
    return str;
};

public method .alphabet() {
    return alphabet;
};

public method .numbers() {
    return numbers;
};

public method .capitalize(): native;

public method .is_numeric() {
    arg string;
    
    return toint(string) || (| ((string.trim())[1]) == "0" |);
};

public method .a_or_an() {
    arg string;
    
    return $english_lib.indef_article(string);
};

public method .strip() {
    arg string, @strip;
    
    anticipate_assignment();
    if (!strip)
        return strsed(string, "[][!@#$%^&*()_+=~`'{}|/?\"\,.<>;: -]", "", "g");
    else
        return strsed(string, ("[" + (strip[1])) + "]", "", "g");
};

public method .non_alphanumeric() {
    return non_alphanumeric;
};

public method .chop() {
    arg str, len, @end;
    
    // chops string off end.length() characters before len and appends len
    [(end ?= "...")] = end;
    if ((strlen(str) < len) || (strlen(str) < strlen(end)))
        return str;
    anticipate_assignment();
    return pad(str, len - strlen(end)) + end;
};

public method .replace(): native;

public method .explode_english_list() {
    arg line, @opts;
    var x, output, tmp;
    
    if (!line)
        return [];
    
    // explodes an english list ("foo, bar and zoo").
    line = line.explode(",");
    output = [];
    for x in (line) {
        x = .trim(x);
        if ((| x.subrange(1, 4) |) == "and ")
            output += [.trim(x.subrange(4))];
        else
            output += [x];
    }
    
    // check the last element, if they didn't specify  'noand
    if (!('noand in opts)) {
        line = (output[output.length()]).explode();
        tmp = "";
        for x in [1 .. line.length()] {
            if ((line[x]) == "and") {
                output = output.delete(output.length());
                if (tmp)
                    output += [tmp];
                tmp = (line.subrange(x + 1)).join();
                if (tmp)
                    output += [tmp];
    
                // only bother with the first "and"
                break;
            }
            tmp = (tmp + (tmp ? " " : "")) + (line[x]);
        }
    }
    return output;
};

public method .explode_delimited() {
    arg str, left, right;
    var pattern, parsed, matched, match_num, match_result;
    
    // parse str looking for anything surrounded by left and right
    // ;$string.explode_delimited("foo<bar>baz", "<", ">")  
    // => [["foo", 1, "baz"], ["bar"]]
    pattern = ((("*" + left) + "*") + right) + "*";
    parsed = [];
    matched = [];
    match_num = 0;
    anticipate_assignment();
    while (str) {
        match_result = match_pattern(str, pattern);
        if (match_result) {
            match_num++;
            parsed += [match_result[1], match_num];
            matched += [match_result[2]];
            str = match_result[3];
        } else {
            parsed += [str];
            str = "";
        }
    }
    return [parsed, matched];
};

public method .wrap_line() {
    arg str, len, @stuff;
    var output, cutoff, firstline, prefix, plen;
    
    // takes string and wraps it by words, compared to length, breaks with \n
    [(prefix ?= ""), (firstline ?= 0)] = stuff;
    output = "";
    if (firstline)
        str = prefix + str;
    plen = strlen(prefix);
    while (strlen(str) > len) {
        cutoff = stridx(substr(str, 1, len), " ", -1);
        if (cutoff <= plen) {
            output += "\n" + substr(str, 1, len);
            str = prefix + substr(str, len + 1);
        } else {
            output += "\n" + substr(str, 1, cutoff - 1);
            str = prefix + substr(str, cutoff + 1);
        }
    }
    return (output ? ((output.subrange(3)) + "\n") : "") + str;
};

public method .rindex() {
    arg string, index;
    
    return stridx(string, index, -1);
};

public method .is_boolean() {
    arg str;
    
    if (match_regexp(str, "^(yes|y|true|t|1)$"))
        return 1;
    if (match_regexp(str, "^(no|n|false|f|0)$"))
        return 0;
    return -1;
};

public method .explode(): native;

public method .match_template(): native;

public method .explode_template_word() {
    arg template;
    var t, x, idx, out, new;
    
    // this only explodes single word templates
    template = template.explode("|");
    out = [];
    for t in (template) {
        idx = "?" in t;
        if (idx) {
            t = t.strip("?");
            new = t.subrange(1, idx - 1);
            out += [new];
            for x in [idx .. t.length()] {
                new += t[x];
                out += [new];
            }
        } else {
            out += [t];
        }
    }
    return out;
};

public method .match_pattern(): native;

public method .match_regexp(): native;

public method .to_number() {
    arg str;
    
    if (str.is_numeric())
        return toint(str);
    throw(~nonum, ("\"" + str) + "\" is not a number.");
};

public method .last() {
    arg str;
    
    return str[str.length()];
};

public method .explode_list() {
    arg str;
    
    if (("," in str) || (" and " in str))
        return str.explode_english_list();
    else
        return str.explode();
};

public method .find_escaped() {
    arg str, char;
    var good, start, pos, p;
    
    good = 0;
    start = 0;
    while ((!good) && (start < (str.length()))) {
        pos = (char in (str.subrange(start + 1))) + start;
        good = 1;
        if (pos > start) {
            p = pos - 1;
            while ((p > 0) && ((str[p]) == "\\")) {
                good = good ? 0 : 1;
                p = p - 1;
            }
        }
        if (good)
            return pos;
        else
            start = pos;
    }
};

public method .explode_quoted() {
    arg str;
    var out, result, x, qstr;
    
    out = [];
    
    // HACK: we need to make this a native--its horribly inefficient
    qstr = ("#$#QUOTE-" + time()) + "#$#";
    str = strsub(str, "\\\"", qstr);
    while (str) {
        result = match_pattern(str, "*\"*\"*");
        if (result) {
            out += ((result[1]).explode()) + [(result[2]).trim()];
            str = result[3];
        } else {
            out += str.explode();
            str = "";
        }
    }
    for x in [1 .. listlen(out)]
        out = replace(out, x, strsub(out[x], qstr, "\""));
    return out;
};

public method .strip_article() {
    arg str;
    
    return strsed(str, "^(an|a|the)  *", "", "g");
};

public method .unquote() {
    arg str;
    
    if (str && (((str[1]) == "\"") && ((str[str.length()]) == "\"")))
        return str.subrange(2, (str.length()) - 2);
    return str;
};

public method .to_buffer() {
    arg string;
    
    return (> str_to_buf(string) <);
};

public method .pad(): native;

public method .wrap_lines() {
    arg str, len, @stuff;
    var output, cutoff, firstline, prefix, plen;
    
    // takes string and wraps it by words, compared to length, returns a list. 
    [(prefix ?= ""), (firstline ?= 0)] = stuff;
    output = [];
    if (firstline)
        str = prefix + str;
    plen = strlen(prefix);
    while (strlen(str) > len) {
        cutoff = stridx(substr(str, 1, len), " ", -1);
        if (cutoff <= plen) {
            output += [substr(str, 1, len)];
            str = prefix + substr(str, len + 1);
        } else {
            output += [substr(str, 1, cutoff - 1)];
            str = prefix + substr(str, cutoff + 1);
        }
    }
    return output + [str];
};

public method .length(): native;

public method .subrange(): native;

public method .match_begin(): native;

public method .crypt(): native;

public method .uppercase(): native;

public method .lowercase(): native;

public method .compare(): native;

public method .format(): native;

public method .to_symbol() {
    arg str;
    
    str = lowercase(strsed(str, "[^a-zA-Z0-9_]+", "", "g"));
    return (> tosym(str) <);
};

public method .valid_ident() {
    arg str;
    
    return strsed(str, "[^a-z0-9_]+", "", "g") == str;
};

public method .regexp(): native;

public method .sed(): native;

public method .split(): native;

public method .word(): native;

public method .dbquote_explode(): native;

public method .to_html() {
    arg line;
    
    anticipate_assignment();
    line = strsub(line, "&", "&amp;");
    line = strsub(line, "<", "&lt;");
    line = strsub(line, ">", "&gt;");
    line = strsub(line, "\"", "&quot;");
    return line;
};

public method .explode_url() {
    arg line;
    var out, args, i;
    
    i = "?" in line;
    if (i) {
        args = substr(line, i + 1);
        line = substr(line, 1, i - 1);
    }
    if (args)
        out = #[['path, explode(line, "/")], ['args, .explode_http_encoding(args)]];
    else
        out = #[['path, explode(line, "/")], ['args, #[]]];
    return out;
};

public method .explode_http_encoding() {
    arg args;
    var fields, field, values;
    
    fields = #[];
    for field in (args.explode("&")) {
        field = field.explode("=");
        if (listlen(field) == 1)
            field = [field[1], ""];
        fields = fields.add(@field);
    }
    return fields;
};

public method .add_indefinite() {
    arg str;
    
    anticipate_assignment();
    return ((str.a_or_an()) + " ") + str;
};

public method .rangeset() {
    arg string, start, len, new;
    
    anticipate_assignment();
    return ((string.subrange(1, start - 1)) + new) + (string.subrange(start + len));
};

public method .decode64() {
    arg enc_chars;
    var i, j, k, ints, out_buf, len, num, ob;
    
    i = 1;
    out_buf = `[];
    len = enc_chars.length();
    while (i < len) {
        refresh();
        ints = [0, 0, 0, 0];
        j = 1;
        while (j <= 4) {
            if (((enc_chars[i]) in base64str) || ((enc_chars[i]) == "=")) {
                for k in [1 .. 64] {
                    refresh();
                    if (strcmp(enc_chars[i], base64str[k]) == 0) {
                        ints = replace(ints, j, (k - 1) % 64);
                        break;
                    }
                }
                j++;
            }
            i++;
        }
        out_buf = out_buf + `[(((ints[1]).shleft(2)) % 256) + ((ints[2]).shright(4)), (((ints[2]).shleft(4)) % 256) + ((ints[3]).shright(2)), (((ints[3]).shleft(6)) % 256) + (ints[4])];
    }
    return buf_to_str(out_buf);
};

public method .html_escape(): native;

public method .random() {
    arg str;
    
    return str[random(strlen(str))];
};

public method .global_regexp() {
    arg string, regexp;
    var result, location, left, begin_match, end_match;
    
    result = [];
    left = string;
    while (left) {
        if ((location = match_regexp(left, regexp))) {
            [begin_match, end_match] = location[1];
            result += [(begin_match == 1) ? "" : (left.subrange(1, begin_match - 1))];
            result += [left.subrange(begin_match, end_match)];
            left = left.subrange(begin_match + end_match);
        } else {
            result += [left];
            left = "";
        }
    }
    if (!((result.length()) % 2))
        result += [""];
    return result;
};

public method .to_bytes() {
    arg str;
    var words, num;
    
    words = str.explode();
    if (listlen(words) == 1) {
        if (!(words = regexp(words[1], "^([0-9]+)(.*)$")))
            throw(~type, "Invalid size.");
    }
    num = (> (words[1]).to_number() <);
    switch (words[2]) {
        case "b", "byte", "bytes":
            return num;
        case "k", "kb", "kbytes", "kilobytes":
            return num * 1024;
        case "m", "mb", "mbytes", "megabytes":
            return (num * 1024) * 1024;
        case "g", "gb", "gbytes", "gigabytes":
            return ((num * 1024) * 1024) * 1024;
        default:
            throw(~type, "Invalid byte size: " + (words[2]));
    }
};

public method .rformat() {
    arg first, second, @rest;
    
    // so you can mmap a list of strings through strfmt
    return strfmt(second, first, @rest);
};

public method .strip_html() {
    arg str;
    var r, ra;
    
    while ((r = "<" in str))
        str = (str.subrange(1, r - 1)) + (str.subrange((">" in str) + 1));
    str = strsub(str, "&lt;", "<");
    str = strsub(str, "&gt;", ">");
    str = strsub(str, "&nbsp;", " ");
    str = strsub(str, "&quot;", "\"");
    str = strsub(str, "&amp;", (ra = ("/" + ($code_lib.random_word())) + "\\"));
    while ((r = "&" in str))
        str = ((str.subrange(1, r - 1)) + "*") + (str.subrange((";" in str) + 1));
    str = strsub(str, ra, "&");
    return str;
};

public method .regexp_escape() {
    arg str;
    
    // anticipate_assignment();
    return strsed(str, "([[\^$|)(.*+?])", "\%1", "g");
};

public method .is_positive() {
    arg str;
    
    if (match_regexp(str, "^(yes|y|true|t|all|everybody|anybody|everywhere|anywhere|1)$"))
        return 1;
    return 0;
};

public method .is_negative() {
    arg str;
    
    if (match_regexp(str, "^(no|n|false|f|none|nobody|nowhere|0)$"))
        return 1;
    return 0;
};

public method .reverse() {
    arg string;
    var length, output, x;
    
    length = string.length();
    output = "";
    for x in [1 .. length]
        output += string[(length - x) + 1];
    return output;
};

public method .prefix_a_or_an() {
    arg str;
    
    anticipate_assignment();
    return (($english_lib.indef_article(str)) + " ") + str;
};

public method .equals() {
    arg str1, str2;
    
    return str1 == str2;
};

public method .index() {
    arg @args;
    
    return stridx(@args);
};

public method .ansi_wrap_line() {
    arg str, len, @stuff;
    var output, cutoff, firstline, prefix, plen, x, ansilist, lengthvals, counter, elem, wordlist, wordsum, flag;
    
    // Thanks Scott for letting me port this back from TEC.
    //   - Bruce
    // takes string and wraps it by words, compared to length, returns a list. 
    [(prefix ?= ""), (firstline ?= 0)] = stuff;
    output = "";
    if (firstline)
        str = prefix + str;
    plen = strlen(prefix);
    while (strlen(str) > len) {
        refresh();
        flag = "\n";
        counter = 0;
    
        // Check for ansi codes first
        ansilist = .weed_ansi(str);
    
        // If there are ansi codes, do the spiel, otherwise do a regular
        // line wrap (this can happen on a segment by segment basis)
        if (listlen(ansilist) > 1) {
            // create a word-only list w/o the ansi codes, and a letter-count
            // list both for the entire list and for the word-only list
            lengthvals = map x in (ansilist) to (strlen(x));
            wordlist = ansilist.odds();
            wordsum = map x in (wordlist) to (strlen(x)).sum();
    
            // wordsum = lengthvals.odds().sum();
            // if the letter-count for the word-only list is greater than the 
            // line length, then we'll need to hack it up, otherwise, we'll
            // just use the length of the entire line, codes and all
            if (wordsum > len) {
                // We've got too many letters. Have to find out where in
                // the word (non-ansi-code) part of the string the len is.
                // we mark its spot in the master list, but only count its
                // letter value if it's really a word. We also need to
                // remember how many letters we've gone through before
                // possibly hitting a big chunk of string (counter).
                elem = find x in (ansilist) where ((x in wordlist) && ((counter += strlen(x)) > len));
                if (elem)
                    counter -= strlen(x);
    
                // Going to establish where to cut the string. Take the
                // sum of the letter-count list up to the marker we just found
                cutoff = (lengthvals.subrange(1, elem - 1)).sum();
    
                // We already know the string is too long for a line, or we
                // wouldn't be here. If the counter is less than our line length
                // it probably means the next element was too long to add, 
                // (a big chunk of string with no codes) so we'll tack on the
                // len - our counter value.
                if (counter < len)
                    cutoff += len - counter;
                cutoff = stridx(substr(str, 1, cutoff), " ", -1);
            } else {
                cutoff = lengthvals.sum();
                flag = "";
            }
        } else {
            cutoff = stridx(substr(str, 1, len), " ", -1);
        }
    
        // The rest of this has been tweaked slightly. The main goal was to
        // get cutoff vals that this section of the code will be happy with.
        if (cutoff <= plen) {
            output += "\n" + substr(str, 1, len);
            str = prefix + substr(str, len + 1);
        } else {
            output += "\n" + substr(str, 1, cutoff);
            str = prefix + substr(str, cutoff + 1);
        }
    }
    
    // Here's the tweak and the pain in the ass I'd like solved. When the
    // length of the word value of the string matches the line length, the
    // extra "\n" a the end causes extra spacing for .atelln()
    return (output ? ((output.subrange(3)) + flag) : "") + str;
};

public method .weed_ansi() {
    arg str;
    
    return str.global_regexp("\\\A[0-9]*(;[0-9]*)*[a-zA-Z]");
};

public method .toliteral() {
    arg @args;
    
    return toliteral(@args);
};


new object $command_lib: $libraries;

var $root manager = $command_lib;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $command_lib arg_types = ["this", "any", "any:*", "object", "object:*", "user", "user:*", "descendant of *", "descendant of *:*", "number", "number:*", "objref", "objref:*"];
var $root managed = [$command_lib];

public method .get_argument_type() {
    arg type;
    var a, m, opts, o, result, is_list;
    
    o = $object_lib;
    is_list = 0;
    if ((m = type.match_template("list *"))) {
        type = m[2];
        is_list = 1;
    }
    for a in (arg_types) {
        m = match_pattern(type, a);
        if (type(m) == 'list) {
            switch (a) {
                case "descendant of *":
                    result = ['descendant, [(> o.to_dbref(m[1]) <)]];
                case "descendant of *:*":
                    opts = ._parse_option_templates(m[2]);
                    result = ['descendant, [(> o.to_dbref(m[1]) <)] + opts];
                case "number:*", "objref:*", "any:*", "object:*", "user:*":
                    opts = ._parse_option_templates(m[1]);
                    result = [tosym(((a.explode(":"))[1]) + "_opt"), opts];
                default:
                    result = [tosym(a), []];
            }
            return is_list ? ['list, result] : result;
        }
    }
    throw(~command, ("Invalid argument type \"" + type) + "\"");
};

public method .handle_shortcut_fields() {
    arg subs, fields;
    var subbed_list, elem;
    
    subbed_list = [];
    for elem in (subs) {
        if (type(elem) == 'string)
            subbed_list += [elem];
        else if (type(elem) == 'integer)
            subbed_list += [(> fields[elem] <)];
        else
            throw(~type, "Substitution element is of wrong type.");
    }
    return subbed_list;
};

public method .validate_command_template() {
    arg str;
    var cmd, tmp, loc, types, part, relations;
    
    [tmp, types] = str.explode_delimited("<", ">");
    loc = [];
    cmd = [];
    relations = #[];
    for part in (tmp) {
        if (type(part) == 'string)
            cmd += part.explode();
        else
            cmd += [part];
    }
    
    // clean
    for part in [1 .. cmd.length()] {
        if (type(cmd[part]) == 'string) {
            cmd = cmd.replace(part, (cmd[part]).trim());
        } else {
            relations = relations.add(part - 1, (> .get_argument_type(types[cmd[part]]) <));
            cmd = cmd.replace(part, "*");
        }
    }
    cmd = [cmd[1], (cmd.subrange(2)).join()];
    if ((| "* *" in (cmd[2]) |))
        throw(~parse, "Invalid template: two args cannot be next to each other (<> <>)");
    return [cmd, relations];
};

public method .parse_relation() {
    arg left, right;
    var x, str, out, cards, last;
    
    left = .break_cards(left);
    right = .break_cards(right);
    if (((left[2]).length()) != ((right[2]).length()))
        throw(~invrel, "Left side cards differ from the right side.");
    str = "";
    for x in (left[1]) {
        if (type(x) == 'string)
            str += x;
        else if (str && ((str[strlen(str)]) == "*"))
            str += " *";
        else
            str += "*";
    }
    
    // and now for some sanity...
    cards = #[];
    for x in (left[2]) {
        if (x != (last + 1))
            throw(~invcard, ((("Left side cards are not in sequence (%" + x) + " before %") + (x - 1)) + ").");
        last = x;
        cards = dict_add(cards, x, 1);
    }
    
    // move to the right side
    out = [str, @left];
    str = "";
    for x in (right[1]) {
        if (type(x) == 'string)
            str += x;
        else
            str += "*";
    }
    
    // final sanity check...
    for x in (right[2]) {
        if (!dict_contains(cards, x))
            throw(~invcard, ("Card %" + x) + " does not exist on the left side!");
    }
    
    // good...
    return [out, [str, @right]];
};

public method .unparse_shortcut() {
    arg s;
    var part, line, short, method, args, x;
    
    line = "";
    [short, [method, args]] = s;
    for part in (args) {
        if (type(part) == 'string)
            line += part;
        else
            line += "%" + part;
    }
    short = .recard_shortcut(short);
    return ((((("\"" + short) + "\"").left(10)) + " => \"") + line) + "\"";
};

public method .format_commands_long() {
    arg cmds, type, clen;
    var def, name, c, cdef, line, o, cs, dname;
    
    o = [];
    for def in (cmds.keys()) {
        o += [((type + " commands on ") + (def.name())) + ":"];
        for cdef in (cmds[def]) {
            for c in (cdef[2])
                o += [((("  " + (toliteral(c[3]).left(clen))) + ".") + tostr(c[4])) + "()"];
        }
    }
    return o;
};

public method .format_commands_short() {
    arg cmds, type, len;
    var def, name, c, cdef, line, o, cs, dname;
    
    o = [];
    for def in (cmds.keys()) {
        o += [((type + " commands on ") + (def.name())) + ":"];
        cs = [];
        for cdef in (cmds[def]) {
            for c in (cdef[2])
                cs += [("\"" + (c[3])) + "\""];
        }
        o += ((cs.sort()).lcolumnize(len - 2, " ")).prefix("  ");
    }
    return o;
};

public method .break_cards() {
    arg str;
    var card, reg, i, x, cards, out, s;
    
    out = (cards = []);
    while ((reg = match_regexp(str, "(%[0-9]+)"))) {
        if (((reg[2])[1]) != 1)
            out += [@.break_wildcards(str.subrange(1, ((reg[2])[1]) - 1))];
        card = substr(str, @reg[2]);
        str = substr(str, (reg[2]).sum());
        if (!((card[2]).is_numeric()))
            throw(~invcard, "Argument cards must be numeric.");
        card = toint(substr(card, 2));
        cards += [card];
        out += [card];
    }
    if (str)
        out += [str];
    return [out, cards];
};

public method .format_relation() {
    arg relation;
    var x, str;
    
    str = "";
    for x in (relation) {
        if (type(x) == 'integer)
            str = (str + "%") + tostr(x);
        else
            str += x;
    }
    return str;
};

public method .break_wildcards() {
    arg str;
    var out, i, s;
    
    out = [];
    while ((i = "*" in str)) {
        out += [substr(str, 1, i - 1), ""];
        str = str.subrange(i + 1);
    }
    if (str)
        out += [str];
    return out;
};

public method ._parse_option_templates() {
    arg opt;
    var reg, out;
    
    out = [];
    opt = strsed(opt, "^ *", "");
    while (opt) {
        if ((reg = regexp(opt, "^[\+-]([^= ]*)=([^ ]+) *(.*)"))) {
            opt = reg[3];
            out += delete(reg, 3);
        } else if ((reg = regexp(opt, "^[\+-]([^ ]+) *(.*)"))) {
            opt = reg[2];
            out += [reg[1]];
        } else {
            throw(~invopt, "Option templates must begin with '+' or '-'");
        }
        opt = strsed(opt, "^ *", "");
    }
    return out;
};

public method .arg_types() {
    return arg_types;
};

public method .unparse_shortcut_full() {
    arg s;
    var part, out, short, method, args;
    
    [short, [method, args]] = s;
    out = "";
    for part in (args) {
        if (type(part) == 'string)
            out += ((out ? ", \"" : "\"") + part) + "\"";
        else
            out += ((out ? ", " : "") + "%") + part;
    }
    out = ((("." + method) + "(") + out) + ")";
    short = .recard_shortcut(short);
    return (((("\"" + short) + "\"").left(10)) + " => ") + out;
};

public method .recard_shortcut() {
    arg short;
    var x, part;
    
    part = 1;
    while ((x = stridx(short, "*"))) {
        short = ((substr(short, 1, x - 1) + "%") + part) + substr(short, x + 1);
        part++;
    }
    return short;
};


new object $http: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $http;
var $root managed = [$http];

public method .decode(): native;

public method .encode(): native;


new object $object_lib: $libraries;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $object_lib;
var $root help_node = $help_obj_object_lib;
var $root managed = [$object_lib];

public method .to_dbref() {
    arg obj;
    var dbref;
    
    switch (type(obj)) {
        case 'string:
            if (!obj)
                throw(~invdbref, "Invalid object reference \"\".");
            if ((obj[1]) == "$") {
                obj = obj.subrange(2);
                dbref = (| lookup(tosym(obj)) |);
            } else if ((obj[1]) == "#") {
                obj = substr(obj, 2);
                if (obj.is_numeric())
                    dbref = (| toobjnum(toint(obj)) |);
                else
                    throw(~objnf, ("Cannot find object \"#" + obj) + "\".");
            } else {
                dbref = toint(obj[1]);
                if (dbref || (obj == "0"))
                    dbref = toobjnum(dbref);
                else
                    dbref = (| lookup(obj) |);
            }
            if (!dbref) {
                dbref = (obj.replace(" ", "_")).lowercase();
                catch ~symbol
                    dbref = tosym(dbref);
                with
                    throw(~symbol, ("Object reference '" + dbref) + "' is invalid.");
                dbref = (> lookup(dbref) <);
            }
            return dbref;
        case 'objnum:
            return obj;
        default:
            return (> lookup(obj) <);
    }
};

public method .get_name() {
    arg obj, @args;
    var meth;
    
    // get_name(obj, 'method, [args]) (3rd arg must be a list)
    if ((type(obj) == 'frob) && (!valid(frob_class(obj))))
        return toliteral(obj);
    if ((type(obj) != 'frob) && (!valid(obj)))
        return toliteral(obj);
    [(meth ?= 'name), (args ?= [])] = args;
    return obj.(meth)(@args);
};

public method .see_perms() {
    arg obj, @args;
    var str, flag, who, encapsulate, flags;
    
    [(encapsulate ?= ["[", "]"])] = args;
    str = encapsulate[1];
    flags = obj.flags();
    if ('core in flags) {
        flags = flags.setremove('core);
        str += "*";
    } else {
        str += "-";
    }
    if ('fertile in flags) {
        flags = flags.setremove('fertile);
        str += "f";
    } else {
        str += "-";
    }
    if ('methods in flags) {
        flags = flags.setremove('methods);
        str += "m";
    } else {
        str += "-";
    }
    if ('variables in flags) {
        flags = flags.setremove('variables);
        str += "v";
    } else {
        str += "-";
    }
    if ('code in flags) {
        flags = flags.setremove('code);
        str += "c";
    } else {
        str += "-";
    }
    for flag in (flags)
        str += (tostr(flag)[1]).uppercase();
    return str + (encapsulate[2]);
};

public method .str_to_objlist() {
    arg args;
    var out, x, obj;
    
    if ("," in args)
        args = args.explode_english_list();
    else
        args = args.explode();
    return .list_to_objlist(args);
};

public method .list_to_objlist() {
    arg args;
    var out, x, obj;
    
    out = #[['valid, []], ['invalid, []]];
    for x in (args) {
        obj = (| .to_dbref(x) |);
        if (obj)
            out = out.add_elem('valid, obj);
        else
            out = out.add_elem('invalid, x);
    }
    return out;
};

public method .parse_method_flags() {
    arg flags;
    
    return (((" " + (('nooverride in flags) ? "!" : "-")) + (('forked in flags) ? "f" : "-")) + (('locked in flags) ? "l" : "-")) + (('native in flags) ? "n" : "-");
};

public method .format_object() {
    arg obj, chop;
    var len, line, out, c;
    
    if (type(obj) == 'frob)
        return ["Frob " + (obj.namef('ref))];
    c = obj.created_on();
    out = ["Object:   " + (obj.namef('xref)), "Created:  " + (c ? ctime(c) : "(Before Time)"), (("Quota:    " + (obj.quota())) + " bytes") + ((obj.quota_exempt()) ? " ** exempt **" : ""), "Perms:    " + (((obj.flags()).prefix("+")).join()), ("Size:     " + ((obj.size()).to_english())) + " bytes (on disk)", "Manager:  " + (.get_name(obj.manager(), 'namef, ['xref]))];
    line = obj.writers('literal);
    if ((line.length()) != 1)
        line = "Writers:  " + (line.to_english("(none)"));
    else
        line = "Writer:   " + ((line[1]).namef('xref));
    if (chop)
        line = line.chop(chop);
    out += [line];
    line = (obj.trusted('literal)) || [];
    if (listlen(line)) {
        line = "Trusts:   " + (line.to_english("(none)"));
        if (chop)
            line = line.chop(chop);
        out += [line];
    }
    line = obj.parents();
    if ((line.length()) > 1)
        line = "Parents:  " + ((line.mmap('namef, 'xref)).to_english());
    else if (!line)
        line = "Parents:  (none)";
    else
        line = "Parent:   " + ((line[1]).namef('xref));
    if (chop)
        line = line.chop(chop);
    out += [line];
    if (obj.has_ancestor($located))
        out += ["Location: " + (.get_name(obj.location(), 'namef, ['xref]))];
    if ((obj.is($path)) && (obj.ways()))
        out += ["Paths:    " + (((obj.ways()).mmap('join, " => ")).join(", "))];
    return out;
};

public method .format_method_header() {
    arg obj, method, opt, flags, access;
    var f;
    
    if (access) {
        // shorten it a little
        access = tostr(access);
        access = strsub(access, "protected", "prot");
        access = strsub(access, "public", "pub");
        opt += ((opt ? " " : "") + "+access=") + access;
    }
    f = flags.join(",");
    
    // shorten it a little
    f = strsub(f, "nooverride", "noover");
    if (f)
        opt += ((opt ? " " : "") + "+flags=") + f;
    return (((("@program " + obj) + ".") + method) + "() ") + opt;
};


new object $integer: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $integer;
var $integer ones = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
var $integer teens = ["eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"];
var $integer tens = ["ten", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety"];
var $root help_node = $help_obj_integer;
var $root managed = [$integer];

public method .n_to_nth() {
    arg number;
    var tens_digit_is_1, ones_digit, single_digit;
    
    if (type(number) != 'integer)
        throw(~type, "Must receive an integer");
    ones_digit = abs(number) % 10;
    tens_digit_is_1 = ((abs(number) / 10) % 10) == 1;
    single_digit = abs(number) < 10;
    if ((ones_digit in [1, 2, 3]) && (!tens_digit_is_1)) {
        switch (ones_digit) {
            case 1:
                return tostr(number) + "st";
            case 2:
                return tostr(number) + "nd";
            case 3:
                return tostr(number) + "rd";
        }
    } else {
        return tostr(number) + "th";
    }
};

public method .parse_range() {
    arg range;
    var r1, r2, reg;
    
    if ("-" in range) {
        reg = regexp(range, "([0-9^#\.]+) *- *([0-9\$\.]+)");
        return [(> ._range_type(reg[1]) <), (> ._range_type(reg[2]) <)];
    } else {
        return [(> ._range_type(range) <), 'none];
    }
    
    // ("1-5") => (1, 5)      -- 1, 5
    // ("1-$") => (1, 'end)   -- 1, 'end (end number)
    // (".-3") => ('cur, 3)   -- 'cur (current number), 3
    // ("^-3") => ('bgn, 3)   -- 'bgn (beginning number), 3
    // ("#-3") => ('bgn, 3)   -- 'bgn (beginning number), 3
};

public method .to_english() {
    arg num;
    var num_str, sign;
    
    // 12500 => "12,500"
    // if (abs(num) < 9999)
    //  return tostr(num);
    sign = num ? (abs(num) / num) : 1;
    num = abs(num);
    num_str = "";
    while (num > 999) {
        num_str = ("," + (tostr(1000 + (num % 1000)).subrange(2))) + num_str;
        num = num / 1000;
    }
    num_str = tostr(num) + num_str;
    return ((sign == 1) ? "" : "-") + num_str;
};

public method .range() {
    arg x, y;
    var element;
    
    return map element in [x .. y] to (element);
};

public method .to_string() {
    arg number;
    
    return (> tostr(number) <);
};

public method ._range_type() {
    arg type;
    
    switch (type) {
        case "0" .. "9":
            return toint(type);
        case "$":
            return 'end;
        case ".":
            return 'cur;
        case "#", "^":
            return 'bgn;
        default:
            throw(~invrange, ("Invalid range character \"" + type) + "\".", type);
    }
};

public method .and(): native;

public method .or(): native;

public method .xor(): native;

public method .shleft(): native;

public method .shright(): native;

public method .not(): native;

public method .to_english_text() {
    arg number;
    var an, isneg, temp;
    
    an = abs(number);
    isneg = (number < 0) ? "negative " : "";
    if (!number)
        return "zero";
    if (an < 11)
        return isneg + (ones[an]);
    if (an < 20)
        return isneg + (teens[an - 10]);
    if (an < 100)
        return (isneg + (tens[an / 10])) + ((temp = an % 10) ? ("-" + (temp.to_english_text())) : "");
    if (an < 1000)
        return ((isneg + (ones[an / 100])) + " hundred") + ((temp = an % 100) ? (" " + (temp.to_english_text())) : "");
    if (an < 1000000)
        return ((isneg + ((an / 1000).to_english_text())) + " thousand") + ((temp = an % 1000) ? (" " + (temp.to_english_text())) : "");
    if (an < 1000000000)
        return ((isneg + ((an / 1000000).to_english_text())) + " million") + ((temp = an % 1000000) ? (" " + (temp.to_english_text())) : "");
    return ((isneg + ((an / 1000000000).to_english_text())) + " billion") + ((temp = an % 1000000) ? (" " + (temp.to_english_text())) : "");
    
    // $#Written by: Kipp
};

public method .to_bytes() {
    arg num, @long;
    
    if (num > 1073741824)
        return strfmt("%.1l", num / 1.07374e+09) + (long ? " gigabytes" : " gb");
    else if (num > 1048576)
        return strfmt("%.1l", num / 1.04858e+06) + (long ? " megabytes" : " mb");
    else if (num > 1024)
        return strfmt("%.1l", num / 1024.0) + (long ? " kilobytes" : " kb");
    return num + (long ? " bytes" : " b");
};

public method .to_roman_numeral() {
    arg num;
    var str, neg, methstr;
    
    str = "";
    neg = "";
    
    // Handle negatives:
    if (num < 0) {
        neg = "negative ";
        num = abs(num);
    }
    if (num >= 1000000)
        return "Out of range";
    if (num >= 1000) {
        str = "M" * (num / 1000);
        num = num % 1000;
        if (num == 0)
            return str;
    }
    if (num >= 100) {
        str = str + ((num / 100).roman_numeral_scheme("C", "D", "M"));
        num = num % 100;
        if (num == 0)
            return str;
    }
    if (num >= 10) {
        str = str + ((num / 10).roman_numeral_scheme("X", "L", "C"));
        num = num % 10;
        if (num == 0)
            return str;
    }
    if (num > 0)
        str = str + (num.roman_numeral_scheme("I", "V", "X"));
    else if (!str)
        str = "";
    return neg + str;
};

public method .roman_numeral_scheme() {
    arg val, x, y, z;
    var rnlist;
    
    rnlist = [x, x * 2, x * 3, x + y, y, y + x, y + (x * 2), y + (x * 3), x + z];
    return rnlist[val];
};


new object $parse_lib: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $parse_lib boolean_strs = [["yes", "true", "1", "on"], ["no", "false", "0", "off"]];
var $root manager = $parse_lib;
var $parse_lib ordinal = ["first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eight", "ninth", "tenth"];
var $root managed = [$parse_lib];

public method .object_match() {
    arg name, @who;
    var msg;
    
    // .object_match("name"[, who])
    // -> 0        name was the empty string
    // -> ~objnf   nothing matched name
    // -> ~ambig   more than one object matched name
    // Attempt to match an object name with who.match_environment().  If one
    // is found, return it.  Else, print a message and return one of the above
    // false values.
    // 'who' defaults to sender().
    who = who ? (who[1]) : sender();
    if (!name) {
        (| who.tell("You must give the name of something.") |);
        return 0;
    }
    catch ~objnf, ~ambig {
        return who.match_environment(name);
    } with {
        switch (error()) {
            case ~objnf:
                msg = ("I don't see any \"" + name) + "\" here.";
            case ~ambig:
                msg = ("I don't know which \"" + name) + "\" you mean.";
        }
        (| who.tell(msg) |);
        return error();
    }
};

public method .traceback() {
    arg traceback, @args;
    var line, out, pre, lines, cur, x, error;
    
    // $parse_lib.traceback(traceback(), lines, pre);
    // -1 lines represents the full error
    // pre is set to "! " unless otherwise specified.
    [(lines ?= -1), (pre ?= "! "), (error ?= 0)] = args;
    out = [(pre + "=> ") + ((traceback[1])[2])];
    pre += "   ";
    
    // The primary error
    if (error == 0)
        out += [(pre + "Thrown by ") + (._traceback(@(traceback[2]).subrange(2)))];
    else
        out += [(((pre + "Error ") + error) + " caused by ") + (._traceback(@(traceback[2]).subrange(2)))];
    
    // The rest of it
    for x in [1 .. (traceback.length()) - 2] {
        if ((x <= lines) || (lines == (-1))) {
            line = ((traceback[x + 2])[1]) + ": ";
            line += ._traceback(@(traceback[x + 2]).subrange(2));
            out += [pre + line];
        }
    }
    if (user())
        user().set_last_traceback([time(), traceback, out]);
    return out;
};

public method ._traceback() {
    arg what, @more;
    var line;
    
    if (more) {
        if ((more[1]) == (more[2]))
            return ((((more[1]) + ".") + what) + "() line ") + (more[3]);
        else
            return ((((((more[1]) + "<") + (more[2])) + ">.") + what) + "() line ") + (more[3]);
    } else {
        return what;
    }
};

public method .range() {
    arg str;
    var out;
    
    out = split(str, " *- *");
    if ((out.length()) == 1) {
        if ("," in str)
            return ['specific, str];
        out = [(> ._range(str) <), 'single];
    } else if ((out.length()) == 2) {
        out = out.replace(1, (> ._range(out[1]) <));
        out = out.replace(2, (> ._range(out[2]) <));
    } else {
        throw(~range, "Invalid range reference.");
    }
    return out;
};

public method ._range() {
    arg str;
    
    if (str.is_numeric()) {
        return toint(str);
    } else {
        switch (str) {
            case "$", "last", "end":
                return 'end;
            case ".", "here":
                return 'current;
            case "^", "start":
                return 'start;
            default:
                throw(~range, "Invalid range reference.");
        }
    }
};

public method .getopt() {
    arg line, @defaults;
    var out, newlist, part, v, opt, t, keys, key, x;
    
    // submit: [["template", value], [...]];
    // => if value is 1, it will take the next part of the string
    // receive: [["template", "flag", bool, value]], [...]]; 
    line = line.explode_quoted();
    out = [];
    newlist = [];
    [(defaults ?= [])] = defaults;
    while (line) {
        [x, @line] = line;
        if (x && ((x[1]) in ["-", "+"])) {
            opt = 0;
            v = "";
            part = x.subrange(2);
            if ("=" in part) {
                part = part.explode("=", 1);
                [part, v] = part;
            }
            for t in (defaults) {
                if (part.match_template(t[1])) {
                    opt = [t[1], part, (x[1]) == "+"];
                    if ((| t[2] |) && ((!v) && line)) {
                        [v, @line] = line;
                        if (v == "=")
                            [(v ?= ""), @line] = line;
                    }
                    opt += [v];
                }
            }
            if (!opt)
                opt = [0, part, (x[1]) == "+", ""];
            out += [opt];
        } else {
            newlist += [x];
        }
    }
    return [newlist, out];
};

public method .buildref() {
    arg type, obj, def, name, @ignore;
    var line;
    
    line = tostr(obj);
    if (obj != def)
        line += ("<" + def) + ">";
    if (type == 'object)
        return line;
    if (type == 'method)
        return ((line + ".") + tostr(name)) + "()";
    if (type == 'variable)
        return (line + ",") + tostr(name);
};

public method .filter_ctext() {
    arg what, @defaults;
    var dic, output, prop, eff, ctext;
    
    dic = #[['receiver, sender()], ['time, 'post], ['formatter, $plain_format]];
    if (defaults && (type(defaults[1]) == 'dictionary))
        dic = dict_union(dic, defaults[1]);
    switch (class(what)) {
        case $ctext_frob:
            output = (what.set_vars(dic)).format();
        case $message_frob:
            output = what.format(dic);
        case $filtered_frob:
            if ((prop = (| sender().default_propagator() |)))
                what = what.propagate(prop);
            if (!what) {
                output = `[];
            } else {
                ctext = (what.message()).to_ctext(dic);
                for eff in (what.effects()) {
                    if (type(eff) == 'string)
                        ctext = ($ctext_frob.new_with([eff + " "], ctext.vars())).append(ctext);
                    else
                        ctext = $propagator_effects.(eff[1])(ctext, dic, eff.subrange(2));
                }
                ctext = ctext.set_vars(what.sensory());
                output = ctext.format();
            }
        default:
            output = what;
    }
    return output;
};

public method .ref() {
    arg str, @args;
    var def, me, obj, reg, member, match, type, second;
    
    [(me ?= sender())] = args;
    if ((args.length()) > 1)
        match = args[2];
    else
        match = [me, 'match_environment, []];
    if (str == ".") {
        obj = (> (match[1]).(match[2])(".") <);
        return ['object, obj, obj, 0, 0];
    }
    if ((reg = regexp(str, "^(.*)<([^>]*)>(.*)$"))) {
        def = (> (match[1]).(match[2])(reg[2], @match[3]) <);
        str = (reg[1]) + (reg[3]);
    }
    if ((reg = regexp(str, "([^\.,]*)([\.,]+)([^\( ]*)"))) {
        obj = reg[1];
        member = reg[3];
        type = reg[2];
        if (((type.length()) > 1) && (((type[1]) == ".") && (!obj))) {
            type = type.subrange(2);
            obj = (> (match[1]).(match[2])(".") <);
        } else {
            obj = obj ? (> (match[1]).(match[2])(obj, @match[3]) <) : me;
        }
        if ("." in type) {
            if ("," in type)
                second = 'variable;
            type = 'method;
        } else {
            type = 'variable;
        }
    } else {
        obj = (> (match[1]).(match[2])(str, @match[3]) <);
        type = 'object;
    }
    return [type, obj, def || obj, member, second];
};

public method .parse_method_access() {
    arg str;
    var t;
    
    for t in (["pub?lic", "pro?tected", "pri?vate", "r?oot", "dr?iver", "f?rob"]) {
        if (match_template(str, t))
            return tosym(t.strip("?"));
    }
    return 'public;
};

public method .parse_method_flags() {
    arg flags;
    var t, out, flag;
    
    out = [];
    for flag in (flags.explode(",")) {
        for t in (["no?override", "l?ocked", "f?orked", "na?tive"]) {
            if (match_template(flag, t))
                out += [tosym(t.strip("?"))];
        }
    }
    return out;
};

public method .html_traceback() {
    arg t, status;
    var line, out, x;
    
    out = ("<h2>" + (((t[1])[2]).to_html())) + "</h2>";
    out += ("<i><b>Thrown by " + (._html_traceback(@t[2]))) + "</b></i><p>";
    for x in [3 .. listlen(t)]
        out += ((("<code><i>" + ((t[x])[1])) + "</i>: ") + (._html_traceback(@t[x]))) + "</code><br>";
    return $http.response(status, out + "</p>");
};

public method ._html_traceback() {
    arg type, what, @more;
    var line;
    
    switch (type) {
        case 'function:
            return ("function <tt>" + what) + "()</tt>";
        case 'opcode:
            return ("operator <tt>" + what) + "</tt>";
        default:
            line = (((((((((("method <tt><a href=\"/bin/display?target=" + (more[2])) + "\">") + (more[2])) + "</a>.<a href=\"/bin/method?target=") + (more[2])) + ".") + tostr(what)) + "&linenumbers=yes\">") + tostr(what)) + "</a>") + "()</tt>";
            if ((more[1]) != (more[2]))
                line += (((" (<a href=\"/bin/display?target=" + (more[1])) + "\">") + (more[1])) + "</a>)";
            line = (line + " line ") + (more[3]);
            return line;
    }
};

public method .ordinal_reference() {
    arg str;
    var rx, num;
    
    if (!(rx = regexp(str, "^ *(first|second|third|fourth|fifth|sixth|seventh|eighth|ninth|tenth|1st|2nd|3rd|[456789]th|10th) *(.*)$")))
        return 0;
    num = toint(rx[1]) || ((rx[1]) in ordinal);
    return [rx[2], num];
    
    // Original code from LamdaMOO, Author Unknown
};

public method .possessive_reference() {
    arg str;
    var rx;
    
    if ((rx = regexp(str, "^my$|^my +(.+)?"))) {
        return ["me", (| rx[1] |) || ""];
    } else if ((rx = regexp(str, "^([^ ]+'s|[^ ]+s') *(.+)?"))) {
        if (listlen(rx) == 1)
            return 0;
        return [substr(rx[1], 1, strlen(rx[1]) - 2), rx[2]];
    }
    return 0;
};

public method .ordinal() {
    return ordinal;
};

public method .ask() {
    arg question, @rx;
    var ans, def;
    
    [(rx ?= "(yes|y)"), (def ?= "")] = rx;
    ans = (> (sender().prompt(question)).trim() <);
    ans ?= def;
    if (ans == "@abort")
        throw(~stop, "** Aborted **");
    return match_regexp(ans, rx);
};

public method .opt() {
    arg line, @defs;
    var out, a, l, x, m, args, opts, o, i, v;
    
    // submit: ["template", "template"..]
    // => if value is 1, it will take the next part of the string
    // receive: [["template", "flag", bool, value]], [...]];
    opts = (args = []);
    line = line.explode_quoted();
    l = listlen(line);
    x = 1;
    while (x <= l) {
        a = line[x];
        if ((m = regexp(a, "^[+-]"))) {
            o = (m[1]) == "+";
            v = "";
            a = substr(a, 2).trim();
            if (!a)
                throw(~stop, ("Missing option flag following '" + (o ? "+" : "-")) + "'");
            if ((i = "=" in a)) {
                if ((i == strlen(a)) && (listlen(line) > x)) {
                    v = line[++x];
                    a = substr(a, 1, strlen(a) - 1).trim();
                } else {
                    [a, v] = explode(a, "=", 1);
                }
            }
            if ((i = find m in (defs) where (match_template(a, m))))
                opts += [[defs[i], a, o, v]];
            else
                opts += [[0, a, o, v]];
        } else {
            args += [a];
        }
        x++;
    }
    return [args, opts];
};


new object $code_lib: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'variables, 'core, 'code];
var $code_lib quotes = [["\"Abandon all hope, ye who enter here.\""], ["\"Pull out Wedge, your not doing any more good back there.\"", "", "- Luke Skywalker, StarWars"], ["\"God is in the details.\""], ["\"I don't practice what I preach,", "because I'm not the type of person I'm preaching too.\"", "", "- Bob Dobbs"], ["\"I haven't shaved for six years.", "I seem to be cursed with a thin beard.\"", "", "- Calvin, Age 6 (of Calvin & Hobbes)"], ["\"I may be a Dreamer, but I'm not the only one.\"", "", "- John Lennon"], ["\"C code.  C code run.  Run, Code, Run!  Please!?\"", "", "- Anonymous C hacker."], ["\"They who dream by day are cognizant of many things", "which escape those who dream only by night.\"", "", "- Edgar Allan Poe"], ["\"The good die first,", "and they whose hearts are dry as a summer dust", "burn to the socket.\"", "", "- William Wordsworth"], ["\"Banning guns to prevent murder", "is like banning word processors to prevent libel.\"", "", "- Unknown"], ["\"You will not be punished for your anger,", "you will be punished by your anger.\"", "", "- Buddha"], ["What part of:", "", "main() { printf(&unix[\"021%six0120\"],(unix)[\"have\"]+\"fun\"-0x60);}", "", "do you not understand?", "", "(taken from the 1987 Obfuscated C Code Contest)"], ["\"The goal of computer science is to build something that will", "last at least until we've finished building it.\""], ["\"Give me ambiguity or give me something else.\""], ["\"We are born naked, wet and hungry. Then things get worse.\""], ["\"Make it idiot proof and someone will make a better idiot.\""], ["\"Lottery: A tax on people who are bad at math.\""], ["\"There's too much blood in my caffeine system.\""], ["\"Artificial Intelligence usually beats real stupidity.\""], ["\"Ever notice how fast MS-Windows runs? Neither did I.\""], ["\"Very funny, Scotty. Now beam down my clothes.\""], ["\"Consciousness: that annoying time between naps.\""], ["\"The gene pool could use a little chlorine.\""], ["\"When there's a will, I want to be in it.\""], ["\"Change is inevitable, except from a vending machine.\""], ["\"MS-Windows is a virus:", "it takes over your computer and makes it run bad.\""], ["\"I have not failed 10,000 times,", "I have sucessfully found 10,000 ways that do not work.\"", "- Thomas Edison"], ["\"The difference between literature and journalism is", "that journalism is unreadable and literature is not read.\"", "", "- Oscar Wilde (1854-1900)"], ["\"The man who reads nothing at all is better educated", "than the man who reads nothing but newspapers.\"", "", "- Thomas Jefferson (1743-1826)"], ["\"In the mind of the beginner, there are many possibilities.", "In the mind of the expert there are few.\"", "", "- Shunryu Suzuki"], ["\"Time is a great teacher, but unfortunately it kills all of its pupils.\"", "", "- Hector Berlioz"], ["\"After I'm dead I'd rather have people ask", "why I have no monument, than why I have one.\"", "", "- Cato the Elder (234-249 B.C.)"], ["\"I loathe people who keep dogs. They are cowards who haven't", "got the guts to bite people themselves.\"", "", "-August Strindberg"], ["\"By the time I'd grown up, I natrually supposed that I'd be grown up.\"", "", "-Eve Babitz"], ["\"Every place has a spirit:", "it may be good, it may be bad", "it can be restful as eternity.", "This place-spirit can inhabit a book, a house, a town, a valley;", "the nature of the spirits is they remain.\"", "", "- William S. Burroughs"], ["\"I have never been lost... but I will admit to being confused for several weeks.\"", "", "- Daniel Boon"], ["Time is what keeps things from happening all at once."], ["According to my calculations the problem doesn't exist."], ["Forget about World Peace ... visualize using your turn signal."], ["Ever stop to think, and forget to start again?"], ["Diplomacy is the art of saying \"nice doggie!\"...till you can find a rock."], ["\"The sign of growing up is being able to form independent opinions,", "The sign of maturity is knowing when they are not wanted.\""], ["\"Microsoft seems hell-bent on repeating very many of the problems", "originally suffered by Unix almost 20 years ago.\"", "", "-Unknown"]];
var $root manager = $code_lib;
var $root managed = [$code_lib];

public method .quotes() {
    return quotes;
};

public method .add_random_quote() {
    arg quote, @from;
    
    if (!($sys.is_admin(sender())))
        throw(~perm, "Sender is not an admin");
    if (type(quote) != 'string)
        throw(~type, "Quote must be given as a string.");
    quote = ("\"" + quote) + "\"";
    quote = quote.wrap_line(70);
    quote = from ? [@quote, "     - " + (from[1])] : quote;
    quotes += [quote];
};

public method .generate_listing() {
    arg who, @args;
    var meths, header, title, i;
    
    // called by one of the who_cmds, does all the grunge work.
    [(title ?= "Connected Users"), (meths ?= [['namef, 'doing], ['connected_time], ['idle_time], ['realm_name]]), (header ?= ["Name", "On for", "Idle", "Location"])] = args;
    header = map i in (header) to ([i, "".pad(i.length(), "-")]);
    
    // if who is empty, only print header
    if (!who)
        return [("--- " + title) + " (0) ---"];
    
    // get values using $list.mmap and format
    return ["--- %l (%l) ---".format(title, who.length()), @map i in (meths) to (who.mmap(@i)).tabulate(header, 0, 1, " ", (| sender().linelen() |) || 79), "---"];
};

public method .random_quote() {
    var which;
    
    which = random(quotes.length());
    if (which)
        return quotes[which];
    return [];
};

public method .parse_name() {
    arg name, @def;
    var article, match, flag, type, tmps, ignore;
    
    // used to parse $has_name names and name templates
    [name, flag] = (> $parse_lib.opt(name, "u?nique", "p?roper", "n?ormal", "i?gnore") <);
    name = name.join();
    
    // Parse +prop +norm +uniq and +ignore flags
    if (flag) {
        def = [@def, ["p?roper", "p", 1, ""]][1];
        flag = (| flag.last() |) || def;
        if ((flag[1]) == "i?gnore") {
            article = 'prop;
            ignore = 1;
        } else {
            switch (flag[1]) {
                case "n?ormal":
                    type = 'normal;
                case "u?nique":
                    type = 'uniq;
                case "p?roper":
                    type = 'prop;
            }
            article = type;
        }
    } else {
        article = 'prop;
    }
    [name, @tmps] = name.split(" *, *");
    
    // Check to see if the name already has articles in it.
    if (!ignore) {
        if ((match = name.regexp("^the +(.*)$"))) {
            article = 'uniq;
            name = match[1];
        } else if ((match = name.regexp("^(a|an) +(.*)$"))) {
            article = 'normal;
            name = match[2];
        }
    
        // Complain if the flag does not agree with the given article
        if (type && (article != type))
            throw(~article, (("Conflicting name types " + type) + " and ") + article);
    }
    return [[name, article], tmps];
};

public method .random_word() {
    arg @args;
    var len, out, con, vow, rare, c, caps, maxcaps, flag, last, min, max, extra;
    
    [(min ?= 3), (max ?= 10), (extra ?= #[])] = args;
    len = random(max - min) + min;
    out = "";
    con = "bcdfghjklmnprst";
    rare = ["q", "aa", "ee", "oo", "qu", "v", "w", "x", "z", "y"];
    vow = "aeiou";
    if ((| extra['con] |))
        con += extra['con];
    if ((| extra['vow] |))
        vow += extra['vow];
    if ((| extra['rare] |))
        rare += extra['rare];
    flag = random(15);
    maxcaps = random(4) + 2;
    while (strlen(out) < len) {
        switch (flag) {
            case 1, 2:
                if (rare) {
                    c = rare.random();
                    if (random(2) == 1)
                        rare = setremove(rare, c);
                    out += c;
                    flag = random(15);
                }
            case 3 .. 8:
                c = vow.random();
                while (c == last)
                    c = vow.random();
                out += c;
                flag = random(7) + 3;
            case 9 .. 15:
                c = con.random();
                while (c == last)
                    c = con.random();
                out += c;
                flag = random(10);
        }
        last = c;
    }
    return out;
};

public method .punctuation_type() {
    arg str;
    var end, offset, noses;
    
    end = str.length();
    switch (str[end]) {
        case "!":
            return "exclaim";
        case "?":
            return "ask";
        case ".":
            return "say";
        case ")":
            if (end > 1) {
                if ((end > 2) && ((str[end - 1]) == "-"))
                    offset = 2;
                else
                    offset = 1;
                switch (str[end - offset]) {
                    case ";":
                        return "wink";
                    case ":", "=":
                        return "smile";
                    case "8":
                        return "grin";
                    default:
                        return "say";
                }
            }
        case "(":
            if (end > 1) {
                if ((end > 2) && ((str[end - 1]) == "-"))
                    offset = 2;
                else
                    offset = 1;
                if ((str[end - offset]) in ["=", "8", ":"])
                    return "frown";
            }
    }
    return "say";
};

public method .verify_code() {
    arg code, method, warn;
    var l, line, m, warns, isadmin, msg;
    
    warns = [];
    method = ("\." + tostr(method)) + "\(";
    isadmin = sender().is($admin);
    for l in [1 .. code.length()] {
        line = code[l];
    
        // if its in a comment, ignore it
        if (match_begin(line, "//"))
            continue;
    
        // required warnings, sorry
        if ((m = line.match_regexp("[^._]anticipate_assignment\(")))
            warns += .point_to_line("WARNING: call to anticipate_assignment()", ((m[1])[1]) + 2, ((m[1])[2]) - 2, l, line);
        if ((m = line.match_regexp("(!)[a-z0-9_]+ in "))) {
            warns += ["WARNING: possible ambiguity, line " + l];
            warns += .point_to_line("WARNING: parenthesis suggested around followup expression to '!'", ((m[2])[1]) + 1, (m[2])[2], l, line);
        }
        if ((m = line.match_regexp("(if *\(|&&|\|\|) *[a-z0-9_]+ *(=)[^=]")))
            warns += .point_to_line("WARNING: parenthesis suggested around assignment expression", ((m[3])[1]) + 1, (m[3])[2], l, line);
    
        // optional warnings
        if (warn && (m = line.match_regexp(method)))
            warns += .point_to_line("WARNING: Possible Recursion", ((m[1])[1]) + 2, ((m[1])[2]) - 2, l, line);
        refresh();
    }
    return warns;
};

public method .generate_object_listing() {
    arg objs, multi, @args;
    var line, obj, col, name, fmt, out;
    
    if (!objs) {
        out = ["** None **"];
    } else {
        col = ((| sender().linelen() |) || 79) / 10;
        fmt = ((((("%3L%" + tostr(col * 4)) + "L %") + tostr(col)) + "L %") + tostr(col)) + "R ";
        out = [strfmt(fmt, "#", "Name", "Perms", "Size") + "Manager"];
        col = col * 4;
        for obj in (objs) {
            line = strfmt(fmt, obj.(multi)(@args).length(), obj.namef('xref), $object_lib.see_perms(obj, ["", ""]), obj.size());
            name = (obj.manager()).namef('xref);
            if ((name.length()) > col)
                name = name.pad(col);
            out += [line + name];
        }
    }
    return out;
};

public method .point_to_line() {
    arg err, left, right, lineno, line;
    var out;
    
    return [((err + ", line ") + lineno) + ":", "  " + line, strfmt("%*{-}l%*{^}l", left, "", right, "")];
};

public method ._debug_listing() {
    arg list;
    var indent, i, out, t, j;
    
    indent = "";
    out = [" Tick#  Event", " -----  -----------------------------"];
    t = 0;
    for i in (list) {
        if (type(i) == 'integer) {
            if (indent)
                indent = indent.subrange(3);
            out += [strfmt("%6r  %lreturn", i - t, indent)];
        } else {
            if (!t)
                t = i[1];
            j = strfmt("%6r  %l%l(%l)", (i[1]) - t, indent, (._show_ref(i)).replace("()", ""), (toliteral(i[5]).match_pattern("[*]"))[1]);
            out += [j];
            indent += "  ";
        }
        refresh();
    }
    return out;
};

public method .generate_debug_listing() {
    arg info, mode;
    
    return .(tosym(("_" + tostr(mode)) + "_listing"))(info);
};

public method ._trace_listing() {
    arg list;
    var indent, i, out, t, j;
    
    indent = "";
    out = [" Tick#  Event", " -----  -----------------------------"];
    t = 0;
    for i in (list) {
        if (type(i) == 'integer) {
            if (indent)
                indent = indent.subrange(3);
        } else {
            if (!t)
                t = i[1];
            j = strfmt("%6r  %l%l", (i[1]) - t, indent, ._show_ref(i));
            out += [j.chop(79)];
            indent += "  ";
        }
        refresh();
    }
    return out;
};

public method ._trace_profile() {
    arg list;
    var i, out, ref, times, sums, callers, t, tic, max, start;
    
    out = ["Object<definer>.method                               Tics  (%)  Cummul. (%)"];
    times = #[];
    sums = #[];
    callers = [];
    for i in (list) {
        refresh();
        if (type(i) == 'integer) {
            if (callers) {
                [[ref, tic], @callers] = callers;
                times = times.add(ref, (((| times[ref] |) || 0) + (i[1])) - t);
                sums = sums.add(ref, (((| sums[ref] |) || 0) + (i[1])) - tic);
            }
            t = i;
        } else {
            if (callers) {
                ref = (callers[1])[1];
                times = times.add(ref, (((| sums[ref] |) || 0) + (i[1])) - t);
            }
            ref = strfmt("%l<%l>.%l", i[2], i[3], i[4]);
            callers = [[ref, i[1]], @callers];
            t = i[1];
        }
        start ?= t;
    }
    max = 0.01 * (t - start);
    out = map i in (times.keys()) to (refresh() && [i, times[i], (times[i]) / max, sums[i], (sums[i]) / max]);
    out = out.sort(out.slice(2));
    out = map i in (out) to (strfmt(i, "%50l%7r%7r%7r%7r"));
    return out;
};

public method ._profile_listing() {
    arg list;
    var i, out, ref, times, sums, callers, t, tic, max, start, head;
    
    head = ["Object<definer>.method                               Tics    (%)  Total    (%)", "----------------------                               ----    ---  -----    ---"];
    times = #[];
    sums = #[];
    callers = [];
    for i in (list) {
        refresh();
        if (type(i) == 'integer) {
            if (callers) {
                [[ref, tic], @callers] = callers;
                times = times.add(ref, (((| times[ref] |) || 0) + i) - t);
                if (!(ref in callers))
                    sums = sums.add(ref, (((| sums[ref] |) || 0) + i) - tic);
            }
            t = i;
        } else {
            if (callers) {
                ref = (callers[1])[1];
                times = times.add(ref, (((| times[ref] |) || 0) + (i[1])) - t);
            }
            ref = ._show_ref(i);
            callers = [[ref, i[1]], @callers];
            t = i[1];
        }
        start ?= t;
    }
    max = 0.01 * (t - start);
    out = map i in (times.keys()) to (refresh() && [i.chop(50), times[i], (times[i]) / max, sums[i], (sums[i]) / max]);
    out = out.sort(map i in (out) to (refresh() && (-(i[2]))));
    out = map i in (out) to (strfmt("%50l%7r%6.1r%%%7r%6.1r%%", @i));
    out = head + out;
    return out;
};

public method ._show_ref() {
    arg i;
    
    return ((i[2]) != (i[3])) ? strfmt("%l<%l>.%l()", i[2], i[3], i[4]) : strfmt("%l.%l()", i[2], i[4]);
};

public method .valid_message_id() {
    arg str;
    
    return !match_regexp(str, "[^a-z0-9-]");
};

public method .random_password() {
    var len, out, con, vow, rare, num, c, caps, maxcaps, flag, last;
    
    len = random(5) + 7;
    out = "";
    con = "bcdfghjklmnprst";
    rare = ["q", "aa", "ee", "oo", "qu", "v", "w", "x", "z", "y"];
    vow = "aeiou";
    num = "1234567890";
    flag = random(15);
    maxcaps = random(4) + 2;
    while (strlen(out) < len) {
        switch (flag) {
            case 1:
                c = num.random();
                out += c;
                flag = random(15);
            case 2, 3:
                if (rare) {
                    c = rare.random();
                    if (random(2) == 1)
                        rare = setremove(rare, c);
                    out += c;
                    flag = random(15);
                }
            case 4 .. 8:
                c = vow.random();
                while (c == last)
                    c = vow.random();
                out += c;
                flag = random(7) + 3;
            case 9 .. 15, -1:
                c = con.random();
                while (c == last)
                    c = con.random();
                out += c;
                flag = random(10);
            case -15 .. -9:
                c = con.random();
                while (c == last)
                    c = con.random();
                out += uppercase(c);
                flag = random(10);
            case -8 .. -4:
                c = vow.random();
                while (c == last)
                    c = vow.random();
                out += uppercase(c);
                flag = random(7) + 3;
            case -3, -2:
                if (rare) {
                    c = rare.random();
                    if (random(2) == 1)
                        rare = setremove(rare, c);
                    out += uppercase(c);
                    flag = random(15);
                }
        }
        last = c;
        if ((caps < maxcaps) && (random(10) == 1)) {
            caps++;
            flag = -flag;
        }
    }
    return out;
};

public method .valid_setting_id() {
    arg str;
    
    return !match_regexp(str, "[^@a-z0-9-]");
};

public method .code_to_html() {
    arg code, object, options;
    var line, object_parse, results, obj_regexp, meth_regexp, chunk, word, method_parse, last_word, mode, chunk_out, meth_r2;
    
    obj_regexp = "\$[a-zA-Z0-9_]+";
    meth_regexp = "((^)|[ (!])\.[a-zA-Z0-9_]+\(";
    meth_r2 = "^(\.[a-zA-Z0-9_]+\()(.*)$";
    results = [];
    for line in (code) {
        if (match_regexp(line, "^ *//")) {
            results += [("<font color=\"#a0a0a0\">" + line) + "</font>"];
        } else {
            object_parse = line.global_regexp(obj_regexp);
            last_word = 0;
            chunk_out = "";
            while (object_parse) {
                [chunk, (word ?= 0), @object_parse] = object_parse;
                if (last_word && (method_parse = chunk.regexp(meth_r2))) {
                    chunk_out += ._do_method_href(method_parse[1], last_word, options);
                    chunk = method_parse[2];
                }
                method_parse = chunk.global_regexp(meth_regexp);
                mode = 0;
                chunk_out += map chunk in (method_parse) to ((mode = !mode) ? chunk : (._do_method_href(chunk, object, options))).join("");
                if (word) {
                    last_word = word;
                    if ((| $object_lib.to_dbref(word) |))
                        chunk_out += ((("<A HREF=\"/bin/display?target=" + ((last_word = word).subrange(2))) + "\">") + word) + "</A>";
                    else
                        chunk_out += word;
                }
            }
            results += [chunk_out + (object_parse.join(""))];
        }
    }
    return results;
};

public method ._do_method_href() {
    arg method, object, options;
    var mod_method, prefix, postfix, index;
    
    prefix = "";
    postfix = "";
    if ((method[1]) != ".") {
        index = stridx(method, ".");
        prefix = method.subrange(1, index);
        method = method.subrange(index + 1);
    } else {
        prefix = ".";
        method = method.subrange(2);
    }
    postfix = "(";
    if (options)
        options = (options.mmap('join, "=")).join("&");
    method = method.subrange(1, (method.length()) - 1);
    return (((((((((prefix + "<A HREF=\"/bin/method?target=") + object) + ".") + method) + "()") + (options ? ("&" + options) : "")) + "\">") + method) + "</A>") + postfix;
};

public method .valid_name() {
    arg name, type;
    
    if (!(type in ['prop, 'normal, 'uniq]))
        throw(~invarg, "Type must be one of: 'prop, 'normal or 'uniq");
    if ("\\" in name)
        throw(~invname, "Names cannot include backslashes.");
    if (name && ((name[1]) in ["$", "#"]))
        throw(~invname, "Names cannot begin with \"$\" or \"#\".");
    if (type(name) != 'string)
        throw(~type, "New name must be given as a string.");
    if ((type != 'prop) && (name.match_regexp("^(a|an|the) +")))
        throw(~bad_name, "Articles included in unique or normal name.");
    if (!(type in ['prop, 'normal, 'uniq]))
        throw(~invarg, "Type must be one of: 'prop, 'normal or 'uniq");
};

public method .random_password2() {
    var len, out, con, vow, rare, more, c, caps, maxcaps, flag, last, special;
    
    len = random(6) + 7;
    out = "";
    con = "bcdfghjklmnprst";
    rare = ["q", "aa", "ee", "oo", "qu", "v", "w", "x", "z", "y"];
    vow = "aeiou";
    more = "1234567890+,:.@'\"/!#%*^~";
    flag = random(15);
    maxcaps = random(4) + 2;
    while (strlen(out) < len) {
        switch (flag) {
            case 1, 2:
                special++;
                c = more.random();
                out += c;
                flag = random(15);
            case 3:
                if (rare) {
                    c = rare.random();
                    if (random(2) == 1)
                        rare = setremove(rare, c);
                    out += c;
                    flag = random(15);
                }
            case 4 .. 7:
                c = vow.random();
                out += c;
                flag = random(7) + 8;
            case 8 .. 15:
                c = con.random();
                while (c == last)
                    c = con.random();
                out += c;
                flag = random(15);
        }
        last = c;
    }
    if (!special) {
        for c in [1 .. random(len / 2)] {
            special = more.random();
            c = random(len);
            out = strgraft(out, c, special);
        }
    }
    return out;
};


new object $list: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $list;
var $root help_node = $help_obj_list;
var $root managed = [$list];

public method .to_english() {
    arg list, @options;
    var empty, and, sep;
    
    [(empty ?= "nothing"), (and ?= " and "), (sep ?= ", ")] = options;
    switch (list.length()) {
        case 0:
            return empty;
        case 1:
            return tostr(list[1]);
    }
    return (join(list.delete(list.length()), sep) + and) + tostr(list[list.length()]);
};

public method .mmap() {
    arg list, method, @args;
    var x;
    
    // call 'method on each object, return results.
    return map x in (list) to (x.(method)(@args));
};

public method .mfilter() {
    arg list, method, @args;
    var x;
    
    // similar to .mmap, but returns a list of objects which returned a
    // true value from 'method.
    return filter x in (list) where (x.(method)(@args));
};

public method .sort(): native;

public method .columnize() {
    arg list, cols, @rest;
    var width, lines, line, separator, linelength, curcol;
    
    // turn [...] into ".   .   ."
    // rest[1]==separator; rest[2]==linelength
    [(separator ?= "   "), (linelength ?= 78)] = rest;
    width = (linelength / cols) - (separator.length());
    lines = [];
    while (list) {
        line = (list[1]).pad(width);
        list = list.subrange(2);
        for curcol in [2 .. cols] {
            if (list) {
                line = (line + separator) + ((list[1]).pad(width));
                list = list.subrange(2);
            }
        }
        lines += [line];
    }
    return lines;
};

public method .reverse() {
    arg list;
    var i, len;
    
    // .reverse(list)
    // -> list with its elements reversed
    len = (list.length()) + 1;
    return map i in [1 .. len - 1] to (list[len - i]);
};

public method .compress() {
    arg list;
    var x;
    
    // [a,a,b,b,c,c,d,d] => [a,b,c,d]
    // removes duplicate entries in a list
    return hash x in (list) to ([x, 1]).keys();
};

public method .last() {
    arg list;
    
    return list[listlen(list)];
};

public method .count() {
    arg list, elem;
    var count, i;
    
    // count of elem in list
    for i in (list) {
        if (i == elem)
            count++;
    }
    return count;
};

public method .element_maxlength() {
    arg list;
    var i, s, t;
    
    s = 0;
    for i in (list) {
        if ((t = strlen(tostr(i))) > s)
            s = t;
    }
    return s;
};

public method .nth_element_maxlength() {
    arg lists, element;
    var list;
    
    // Returns longest string whose index is element in one of the lists in
    // lists.
    if (type(element) != 'integer)
        throw(~type, "Second argument is not an integer");
    if (type(lists) != 'list)
        throw(~type, "First argument is not a list");
    return map list in (lists) to (tostr(list[element]).length()).max();
};

public method .numbered_text() {
    arg text;
    var line;
    
    // receives a list of strings, returns that list with line numbers
    // prepended
    return map line in [1 .. text.length()] to ("%3r: %l".format(line, text[line]));
};

public method .slice() {
    arg big_list, element;
    var list, i;
    
    // Return elementh' element of all lists in big_list
    // No type or length checking done for speed purposes.
    // element can be a list, in which cases, a list of list is returned
    if (type(element) == 'integer)
        return map list in (big_list) to (list[element]);
    else
        return map list in (big_list) to (map i in (element) to (list[i]));
};

public method .swap() {
    arg list, a, b;
    var holder;
    
    // swap elements at indexes a and b
    if ((listlen(list) < a) || ((listlen(list) < b) || ((a < 1) || (b < 1))))
        throw(~args, "Index specifiers are outside the range of the list.");
    anticipate_assignment();
    holder = list[a];
    list = replace(list, a, list[b]);
    list = replace(list, b, holder);
    return list;
};

public method .max() {
    arg list;
    
    return (| max(@list) |) || 0;
};

public method .min() {
    arg list;
    
    return (| min(@list) |) || 0;
};

public method .lcolumnize() {
    arg list, @args;
    var line, part, lines, max, cols, col, width, len, sep;
    
    [(len ?= (| sender().linelen() |) || 78), (sep ?= " ")] = args;
    lines = [];
    line = "";
    max = (.element_maxlength(list)) + (sep.length());
    cols = (len > max) ? (len / max) : 1;
    width = (len / cols) - (sep.length());
    col = cols;
    for part in (list) {
        col = col - 1;
        if (!col) {
            lines = lines + [line + part];
            line = "";
            col = cols;
            continue;
        }
        line = line + (part.pad(width));
    }
    if (line)
        return lines + [line];
    return lines;
};

public method .mmap_objects() {
    arg list, method, @args;
    var x;
    
    return map x in (list) to ((type(x) == 'objnum) ? x.(method)(@args) : x);
};

public method .map_to_english() {
    arg list, method, @args;
    
    return .to_english(.mmap(list, method, @args));
};

public method .map_to_string() {
    arg list, method, @args;
    
    return .join(.mmap(list, method, @args));
};

public method .flatten() {
    arg list;
    var toret, elem;
    
    // [[[x], x], x]   =>   [x, x, x]
    toret = [];
    for elem in (list) {
        if (type(elem) == 'list)
            toret += .flatten(elem);
        else
            toret += [elem];
    }
    return toret;
};

public method .sum() {
    arg data;
    var ret, i;
    
    // returns a sum of each element in the list.
    if (!data)
        return 0;
    [ret, @data] = data;
    for i in (data)
        ret += i;
    return ret;
};

public method .numbers() {
    // returns a list of numbers
    return ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
};

public method .center_lines() {
    arg lines, width, @args;
    var line, fmt;
    
    fmt = ("%" + width) + "c";
    return map line in (lines) to (strfmt(fmt, line));
};

public method .to_buffer() {
    arg @args;
    
    return (> strings_to_buf(@args) <);
};

public method .delete(): native;

public method .replace(): native;

public method .chop() {
    arg list, @count;
    
    // chops the last <count> elements off the list.
    // return [] if count is longer then the list.
    count = count || 1;
    anticipate_assignment();
    return (| sublist(list, 1, listlen(list) - count) |) || [];
};

public method .join(): native;

public method .lmap() {
    arg list, method, @args;
    var x, s;
    
    // call methods for each thing in list on sender()
    s = sender();
    return map x in (list) to (s.(method)(x, @args));
};

public method .length(): native;

public method .union(): native;

public method .omap() {
    arg list, object, method, @args;
    var obj;
    
    // calls object.method(obj, @args) for each obj in list
    return map obj in (list) to (object.(method)(obj, @args));
};

public method .del() {
    arg list, element;
    
    return (> setremove(list, element) <);
};

public method .add() {
    arg list, element;
    
    return (> setadd(list, element) <);
};

public method .set_difference() {
    arg @args;
    var set, list, element;
    
    // Usage:  diff(set 1, set 2, ..., set n)
    // Returns all elements of set 1 that are not in sets 2..n
    if (!args)
        return [];
    set = args[1];
    anticipate_assignment();
    for list in (delete(args, 1)) {
        for element in (list)
            set = setremove(set, element);
    }
    return set;
};

public method .set_contains() {
    arg @args;
    var super, list, element;
    
    // True if the first list given is a superset of all subsequent lists.
    // False otherwise.  [] is a superset of [] and nothing else; anything is
    // a superset of [].  If only one list is given, return true.
    super = args ? (args[1]) : [];
    for list in (delete(args, 1)) {
        for element in (list) {
            if (!(element in super))
                return 0;
        }
    }
    return 1;
};

public method .set_equal() {
    arg set1, set2;
    var e, dict1, dict2;
    
    // True if the two lists given contain the same elements.
    // False otherwise.
    dict1 = hash e in (set1) to ([e, 1]);
    dict2 = hash e in (set2) to ([e, 1]);
    for e in (dict1.keys()) {
        if (!dict_contains(dict2, e))
            return 0;
    }
    for e in (dict2.keys()) {
        if (!dict_contains(dict1, e))
            return 0;
    }
    return 1;
};

public method .fold() {
    arg list, object, method, @args;
    var i, out;
    
    // apply object.method to a current result and the next element, return the
    // result
    switch (list.length()) {
        case 0:
            return 0;
        case 1:
            return list[1];
    }
    out = list[1];
    for i in (sublist(list, 2, listlen(list) - 1))
        out = object.(method)(out, i, @args);
    return out;
};

public method .setadd(): native;

public method .set_intersection() {
    arg l1, l2;
    var i, out;
    
    // set intersection if the arguments
    out = [];
    for i in (l1) {
        if (i in l2)
            out = out.setadd(i);
    }
    return out;
};

public method .setremove(): native;

public method .insert(): native;

public method .subrange(): native;

public method .prefix() {
    arg list, prefix;
    var elem;
    
    return map elem in (list) to (prefix + elem);
};

public method .valid_objects() {
    arg list;
    var obj;
    
    return filter obj in (list) where (valid(obj));
};

public method .grep() {
    arg lines, regexp;
    var line, result, out, reg;
    
    out = [];
    for line in [1 .. lines.length()] {
        if ((reg = match_regexp(lines[line], regexp)))
            out += [[line, reg, lines[line]]];
    }
    return out;
};

public method .vcolumnize() {
    arg list, cols, @rest;
    var linelength, sep, width, lines, i, j, line, outlist;
    
    [(linelength ?= (| sender().linelen() |) || 78), (sep ?= " ")] = rest;
    lines = ((list.length()) / cols) + (((list.length()) % cols) ? 1 : 0);
    width = linelength / cols;
    return ._vcolumnize(list, lines, cols, width, sep);
};

public method .make() {
    arg n, @elt;
    var i;
    
    [(elt ?= 0)] = elt;
    return map i in [1 .. n] to (elt);
};

public method ._vcolumnize() {
    arg list, lines, cols, width, @other;
    var outlist, line, i, j, sep;
    
    [(sep ?= " ")] = other;
    width -= sep.length();
    lines = (lines > (list.length())) ? (list.length()) : lines;
    outlist = [];
    for i in [1 .. lines] {
        line = (list[i]).pad(width);
        for j in [1 .. cols]
            (| (line = (line + sep) + ((list[i + (j * lines)]).pad(width))) |);
        outlist += [line.trim('right)];
    }
    return outlist;
};

public method .affix() {
    arg l1, l2;
    var last, first;
    
    // Combines l1 and l2 by appending the first element of l2 to the last
    // of l1.
    if (type(l2) != 'list)
        l2 = [l2];
    last = (| l1.last() |) || "";
    first = (| l2[1] |) || "";
    l1 = [@l1.chop(), last + first];
    if ((l2.length()) > 1)
        l1 += l2.subrange(2);
    return l1;
};

public method .addkey() {
    arg l, key, val;
    var i;
    
    i = find i in [1 .. l.length()] where (((l[i])[1]) == key);
    anticipate_assignment();
    return i ? replace(l, i, [key, val]) : (l + [[key, val]]);
};

public method .delkey() {
    arg l, key;
    var i;
    
    i = find i in [1 .. l.length()] where (((l[i])[1]) == key);
    anticipate_assignment();
    return i ? delete(l, i) : l;
};

public method .getkey() {
    arg l, key;
    var i, x;
    
    if (!(x = find i in [1 .. l.length()] where (((l[i])[1]) == key)))
        throw(~keynf, "Key not found.");
    return (l[x])[2];
};

public method .getkey_index() {
    arg l, key;
    var i, x;
    
    if (!(x = find i in [1 .. l.length()] where (((l[i])[1]) == key)))
        throw(~keynf, "Key not found.");
    return x;
};

public method .setremove_all() {
    arg list, remove;
    var part;
    
    if (type(list) != 'list)
        throw(~type, "First argument must be a list.");
    if (type(remove) != 'list)
        throw(~type, "Second argument must be a list.");
    anticipate_assignment();
    for part in (remove)
        list = setremove(list, part);
    return list;
};

public method .vcolumnize2() {
    arg list, lines, @rest;
    var linelength, sep, cols, width, i, j, line, outlist;
    
    [(linelength ?= (| sender().linelen() |) || 78), (sep ?= " ")] = rest;
    cols = ((list.length()) / lines) + (((list.length()) % lines) ? 1 : 0);
    width = linelength / cols;
    return ._vcolumnize(list, lines, cols, width, sep);
};

public method .vcolumnize3() {
    arg list, lines, @rest;
    var linelength, cols, width, i, j, line, outlist;
    
    [(linelength ?= (| sender().linelen() |) || 78)] = rest;
    cols = ((list.length()) / lines) + (((list.length()) % lines) ? 1 : 0);
    width = linelength / cols;
    outlist = [];
    for i in [1 .. lines] {
        line = "";
        for j in [0 .. cols]
            (| (line = line + ((list[i + (j * lines)]).pad(width))) |);
        outlist += [line];
    }
    return outlist;
};

public method .vcolumnize4() {
    arg list, @args;
    var linelength, sep, lines, cols, width, max;
    
    [(linelength ?= (| sender().linelen() |) || 79), (sep ?= " ")] = args;
    max = (.element_maxlength(list)) + (sep.length());
    cols = (linelength > max) ? (linelength / max) : 1;
    width = linelength / cols;
    lines = ((list.length()) / cols) + (((list.length()) % cols) ? 1 : 0);
    return ._vcolumnize(list, lines, cols, width, sep);
};

public method .random() {
    arg list;
    
    return list[random(listlen(list))];
};

public method .to_dict() {
    arg list;
    var a;
    
    return hash a in (list) to (a);
};

public method .match_nth() {
    arg objs, str, nth;
    var obj, n;
    
    n = nth;
    for obj in (objs) {
        if (obj.match_name(str)) {
            if (!--n)
                return obj;
        }
    }
    throw(~match, ((("There are not " + ((.numbers())[nth])) + " ") + str) + "'s available.");
};

public method .match_object() {
    arg objs, str;
    var obj, found, l, f;
    
    found = [];
    for obj in (objs) {
        if ((type(obj) == 'frob) && (!valid(frob_class(obj))))
            throw(~badfrob, "Bad Thing Frob", obj);
        else if (obj.match_name(str))
            found += [obj];
    }
    if (listlen(found) == 1)
        return found[1];
    if (listlen(found) > 1) {
        if ((f = filter f in (found) where ((f.name()) == str))) {
            if (listlen(f) == 1)
                return f[1];
            found = f;
        }
        throw(~ambig, "ambiguous match", found);
    }
    throw(~objnf, "Object not found.");
};

public method .tabulate() {
    arg list, headers, @rest;
    var i, j, t, t1, trim_cols, header_sep, colsizes, len;
    
    if (!list)
        return [];
    [(colsizes ?= 0), (trim_cols ?= 0), (header_sep ?= " "), (len ?= 79)] = rest;
    if (!headers)
        headers = .make(list.length(), []);
    if (type(headers[1]) == 'string)
        headers = map i in (headers) to ([i]);
    
    // Find the column sizes
    if (!colsizes) {
        if (trim_cols) {
            t = map i in (list) to (refresh() && ((i.element_maxlength()) + 2));
            t1 = filter i in [1 .. t.length()] where ((t[i]) > 2);
            t = map i in (t1) to (t[i]);
            list = map i in (t1) to (list[i]);
            headers = map i in (t1) to (headers[i]);
        }
        colsizes = t ? map i in [1 .. headers.length()] to (refresh() && max(t[i], ((headers[i]).element_maxlength()) + 2)) : map i in [1 .. list.length()] to (refresh() && (max((headers[i]).element_maxlength(), (list[i]).element_maxlength()) + 2));
    }
    t = map i in (colsizes) to (("%" + i) + "l").sum();
    t1 = map i in (colsizes) to (((("%" + i) + "{") + header_sep) + "}l").sum();
    
    // Now format the thing...
    return map i in (headers.transpose()) to (refresh() && (((t1.format(@i)).pad(len)).trim('right))) + map i in (list.transpose()) to (refresh() && (((t.format(@i)).pad(len)).trim('right)));
};

public method .transpose() {
    arg list;
    
    return $math.transpose(list);
};

public method .format() {
    arg list, format;
    
    return strfmt(format, @list);
};

public method .nonzero() {
    arg list;
    var x;
    
    return filter x in (list) where (x);
};

public method .match_object2() {
    arg objs, str;
    var obj, found;
    
    found = [];
    for obj in (objs) {
        if ((type(obj) == 'frob) && (!valid(frob_class(obj))))
            (<$thing_frob, frob_value(obj)>).discard();
        else if (obj.match_name(str))
            found += [obj];
    }
    if (listlen(found) == 1)
        return found[1];
    if (listlen(found) > 1)
        throw(~ambig, "ambiguous match", found);
    throw(~objnf, "Object not found.");
};

public method .intersection() {
    arg l1, l2;
    var i;
    
    // set intersection of the arguments
    return filter i in (l1) where (i in l2);
};

public method .odds() {
    arg list;
    var chunk, mode;
    
    return filter chunk in (list) where ((mode = !mode));
};

public method .fmt_tb() {
    arg tb, @args;
    
    return $parse_lib.traceback(tb, @args);
};

public method .locate() {
    arg list, value;
    var idx;
    
    return filter idx in [1 .. listlen(list)] where (value == (list[idx]));
    
    // Find the index in the list where the value of the element is the value being searched for.  Filter out the zeros so that only valid indices are returned.
    // [1, 2, 3, 4].locate(5) -> []
    // [4, 2, 3, 4].locate(4) -> [1, 4]
};

public method .columnize2() {
    arg list, cols, @rest;
    var width, lines, line, separator, linelength, x, handled_length;
    
    // turn [...] into ".   .   ."
    // rest[1]==separator; rest[2]==linelength
    [(separator ?= "   "), (linelength ?= 78)] = rest;
    width = (linelength / cols) - (separator.length());
    lines = [];
    for x in [1 .. (list.length()) / cols] {
        line = ((list.subrange((x * cols) - 1, cols)).mmap('pad, width)).join(separator);
        lines += [line];
    }
    handled_length = x * cols;
    if ((list.length()) != handled_length)
        lines += [((list.subrange(handled_length + 1)).mmap('pad, width)).join(separator)];
    return lines;
};

public method .columnize3() {
    arg list, cols, @rest;
    var width, lines, line, separator, linelength, x, handled_length, even_length;
    
    // turn [...] into ".   .   ."
    // rest[1]==separator; rest[2]==linelength
    [(separator ?= "   "), (linelength ?= 78)] = rest;
    width = (linelength / cols) - (separator.length());
    lines = [];
    handled_length = 1;
    even_length = (list.length()) / cols;
    while (handled_length < even_length) {
        line = ((list.subrange(handled_length, cols)).mmap('pad, width)).join(separator);
        lines += [line];
        handled_length += cols;
        refresh();
    }
    if ((list.length()) >= handled_length)
        lines += [((list.subrange(handled_length)).mmap('pad, width)).join(separator)];
    return lines;
};


new object $help_lib: $libraries;

var $root manager = $help_lib;
var $root created_on = 805931416;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $help_lib default_node = $help_coldcore;
var $root managed = [$help_lib];
var $help_lib indices = [$help_index_function, $help_index_objects, $help_index_subsystem, $help_index_driver, $help_index_cmds, $help_index_core];

public method .default_node() {
    return default_node;
};

public method .history_cap() {
    return 15;
};

public method .group_nodes_in_html() {
    arg nodes, noemph, @args;
    var name, names, n;
    
    names = [];
    for n in (nodes) {
        if (n in noemph)
            name = n.name();
        else
            name = .node_name_in_html(n);
        names += [name];
    }
    return names.to_english(@args);
};

public method .node_name_in_html() {
    arg node;
    
    return ((("<a href=\"/bin/help?" + node) + "\">") + (node.name())) + "</a>";
};

public method .indices() {
    return indices;
};

public method .set_indices() {
    arg @new;
    var o;
    
    (> .perms(sender()) <);
    if (filter o in (new) where ((type(o) != 'objnum) || (!(o.is($help_index)))))
        throw(~type, "Arguments must be $help_index objects.");
    
    // do this all at once so you can manage the order
    indices = new;
};


new object $misc: $core;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root manager = $misc;
var $root managed = [$misc];


new object $mail_root: $misc;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root manager = $mail_root;
var $root managed = [$mail_root];


new object $mail_lib: $libraries, $mail_root;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $mail_lib mail_system = [$mail_message, $mail_list, $mail_ui, $mail_lib, $pop3_interface];
var $root manager = $mail_lib;
var $root managed = [$mail_lib];

public method .mail_name() {
    arg obj;
    var name;
    
    if (!(obj.has_ancestor($mail_list)))
        throw(~type, "Object is not a child of $mail_recipient");
    name = (obj.name()).replace(" ", "-");
    if (obj.has_ancestor($user))
        return "~" + name;
    return "*" + name;
};

public method .has_mail_perms() {
    arg @args;
    var obj;
    
    for obj in (args) {
        if ((!(obj in mail_system)) && (!($sys.is_system(obj))))
            return 0;
    }
};

public method .match_mail_recipient() {
    arg name;
    
    catch ~namenf {
        if (name) {
            if (name == "me")
                return sender();
            if ((name[1]) == "*")
                return (> $mail_db.search(substr(name, 2)) <);
            if ((name[1]) == "~")
                return (> $user_db.search(substr(name, 2)) <);
            return (| $mail_db.search(name) |) || (> $user_db.search(name) <);
        }
    }
    throw(~listnf, ("No mail recipient found by the name \"" + name) + "\".");
};

public method .range_to_actual() {
    arg rng, current;
    var start, end, out, listm, m, x, list;
    
    list = current['list];
    listm = list.mail();
    if (type(rng[1]) == 'integer) {
        start = rng[1];
    } else {
        switch (rng[1]) {
            case 'end:
                if (type(rng[2]) != 'symbol)
                    throw(~range, "Backwards range.");
                start = ((current['list]).mail()).length();
            case 'start:
                start = 1;
            case 'current:
                start = (current['location]) in listm;
            case 'specific:
                out = [];
                for m in ((rng[2]).explode_english_list()) {
                    if ((!(x = toint(m))) || (x < 1)) {
                        sender().tell(("Ignoring list range element '" + m) + "'.");
                    } else {
                        catch ~range
                            out = setadd(out, (> listm[x] <));
                        with
                            sender().tell(((((("List range #" + x) + " is higher than the messages in ") + (list.mail_name())) + " (") + (listm.length())) + ")");
                    }
                }
                return out || throw(~range, "No elements in list range.");
        }
    }
    if (type(rng[2]) == 'integer) {
        end = rng[2];
    } else {
        switch (rng[2]) {
            case 'end:
                end = ((current['list]).mail()).length();
            case 'single:
                end = start;
            case 'start:
                throw(~range, "Backwards range.");
            case 'current:
                end = (current['location]) in ((current['list]).mail());
        }
    }
    if (start > end)
        throw(~range, "Backwards range.");
    out = [];
    for m in [start .. end] {
        catch ~range
            out = setadd(out, (> listm[m] <));
        with
            sender().tell(((((("List range #" + m) + " is higher than the messages in ") + (list.mail_name())) + " (") + (listm.length())) + ")");
    }
    return out || throw(~range, "No elements in list range.");
};

public method .indent_reply() {
    arg text;
    var l, out;
    
    out = [];
    for l in (text) {
        if (!(l.match_begin(">")))
            out += l.wrap_lines(65, "> ", 1);
        else
            out += [">" + l];
    }
    return out;
};

public method .generate_unique_id() {
    arg message;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> message.perms(sender()) <);
    return crypt(toliteral([message.time(), message.from(), message.recipients(), message.subject(), message.body()]), "POP3").subrange(9);
};


new object $foundation: $root, $dmi_data;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root manager = $foundation;
var $root managed = [$foundation];
var $foundation edit_types = 0;
var $foundation defined_msgs = 0;
var $foundation msgs = 0;

public method .configure() {
    arg set;
    
    // This is for post-creation configuration of a VR object.  It is used
    // to interactively configure the VR aspects and behaviour of an object.
    // It should be optional, any command hooking into confingure should check
    // for a -conf?igure option first (which would imply skipping configuration).
    //
    // Overriding methods should pass() first, giving priority to their
    // ancestors.  The argument 'set' is a dictionary with symbol keys
    // defining what has been set.  Use the definer's name + "_" + setting
    // as the name of the key ("name" on $has_name would be 'has_name_name).
    // If something is already in the set dictionary, do not re-set it
    // again (for instance, if the command hooking into configure accepted
    // the name of the object on it's command line it would put
    // 'has_name_name in the dictionary and $has_name.configure() would not 
    // prompt for the name).
    //
    // "@skip" should always skip the setting, and not alter it.
    // if .prompt() returns 'aborted, throw ~abort.
    //
    (> .perms(sender()) <);
    return set;
};

public method .environment() {
    return [];
};

public method .match_environment() {
    arg str;
    var obj, env, found, match, target;
    
    if (!str)
        throw(~objnf, "No object specified.", str);
    str = str.strip_article();
    
    // Handle special cases.
    if (str in ["me", "my"]) {
        return this();
    } else if (((str[1]) == "$") || ((str[1]) == "#")) {
        return (> $object_lib.to_dbref(str) <);
    } else if ((str[1]) == "~") {
        str = str.subrange(2);
        if ((str[1]) != "~")
            return $user_db.match_begin(str);
    } else if (str in ["it", "him", "her"]) {
        return (| .match_context(str) |) || throw(~context, ("I don't see " + str) + " here, do you?");
    }
    
    // Start matching
    found = [];
    env = .environment();
    
    // special case ordinal references
    if ((match = $parse_lib.ordinal_reference(str)))
        return (> env.match_nth(@match) <);
    if ((match = $parse_lib.possessive_reference(str))) {
        if ((match[1]) == "me")
            obj = this();
        else
            obj = (> env.match_object(match[1]) <);
        if (!(obj.match_name(str))) {
            catch ~objnf, ~ambig, ~range {
                env = (| obj.contents() |) || [];
                if ((found = $parse_lib.ordinal_reference(match[2])))
                    return (> env.match_nth(@found) <);
                else
                    return (> env.match_object(match[2]) <);
            } with {
                if (error() == ~objnf)
                    throw(~objnf, (((obj.name()) + " does not have ") + ((match[2]).add_indefinite())) + ".");
                else if (error() == ~ambig)
                    throw(~ambig, ((("\"" + str) + "\" can match ") + ((((traceback()[1])[3]).mmap('namef, 'ref)).to_english("", " or "))) + ".");
                else
                    throw(~objnf, (obj.name()) + "'s what?");
            }
        }
    }
    catch any {
        return (> env.match_object(str) <);
    } with {
        if (error() == ~badfrob) {
            target = (traceback()[1])[3];
            obj = frob_value(target)['location];
            obj.del_frob_from_contents(target);
            throw(~badfrob, "Cleaned up bogus frob in your environment, try again..");
        }
        if (error() == ~objnf)
            throw(~objnf, ("You do not see " + (str.add_indefinite())) + " anywhere.");
        if (error() == ~ambig) {
            found = filter obj in ((traceback()[1])[3]) where ((obj.name()) == str);
            if (listlen(found) == 1)
                return found[1];
            if (found)
                found = (found.mmap('namef, 'ref)).to_english("", " or ");
            else
                found = (((traceback()[1])[3]).mmap('namef, 'ref)).to_english("", " or ");
            throw(~ambig, ((("\"" + str) + "\" can match ") + found) + ".");
        }
        rethrow(error());
    }
};

public method .local_to_environment() {
    arg obj;
    
    return obj in (.environment());
};

public method .get_edit_types() {
    return edit_types || [];
};

public method .set_edit_types(): nooverride {
    arg t;
    
    (> .perms(sender()) <);
    if (t)
        edit_types = t;
};

public method .all_edit_types(): nooverride {
    var i, l, t;
    
    l = [];
    for i in (.ancestors()) {
        if (type((| (t = i.get_edit_types()) |)) == 'list)
            l = union(l, i.get_edit_types());
    }
    return l;
};

public method .defined_msgs(): nooverride {
    return defined_msgs || #[];
};

public method .all_defined_msgs(): nooverride {
    var msgs, m, a;
    
    msgs = #[];
    for a in ([this()] + ancestors()) {
        if (a == definer())
            break;
        catch any
            msgs = dict_union(msgs, a.defined_msgs());
    }
    return msgs;
};

public method .clear_msg(): nooverride {
    arg name, @branches;
    var messages, branch, msg;
    
    (caller() != definer()) && (> .perms(sender()) <);
    messages = msgs || #[];
    if (!dict_contains(messages, name))
        return;
    if (!branches) {
        messages = dict_del(messages, name);
    } else {
        msg = messages[name];
        for branch in (branches) {
            if (dict_contains(msg, branch))
                msg = dict_del(msg, branch);
        }
        if (!msg)
            messages = dict_del(messages, name);
    }
    if (!messages)
        clear_var('msgs);
    else
        msgs = messages;
};

public method .define_msg(): nooverride {
    arg name;
    
    (> .perms(sender()) <);
    if ((.all_defined_msgs()).contains(name))
        throw(~msgexists, ("Message \"" + name) + "\" is already defined.");
    if (!($code_lib.valid_message_id(name)))
        throw(~msgbad, ("Message \"" + name) + "\" contains invalid characters.");
    defined_msgs = (.defined_msgs()).add(name, #[['branches, ["general"]]]);
};

public method .undefine_msg(): nooverride {
    arg name;
    var d;
    
    (> .perms(sender()) <);
    if (!((.defined_msgs()).contains(name)))
        throw(~msgnf, (("Message \"" + name) + "\" is not defined by ") + this());
    
    // clear it on all descendants, then us
    for d in (.descendants()) {
        d.clear_msg(name);
        pause();
    }
    .clear_msg(name);
    
    // bye bye
    defined_msgs = dict_del(defined_msgs, name);
    if (!defined_msgs)
        clear_var('defined_msgs);
};

public method .msgs(): nooverride {
    return msgs || #[];
};

public method .get_default_msg(): nooverride {
    arg name;
    var def, b;
    
    catch any {
        return msgs[name];
    } with {
        def = $compiler.compile_cml(">>NO DEFAULT<<");
        return hash b in (.get_msg_attr(name, 'branches)) to ([b, def]);
    }
};

public method .get_msg() {
    arg name, definer;
    var get;
    
    if (!(get = (| definer.get_msg_attr(name, 'getter) |)))
        return dict_union(definer.get_default_msg(name), (| msgs[name] |) || #[]);
    return .(get)(name, definer);
};

public method .get_msg_attr(): nooverride {
    arg name, attr;
    
    return (defined_msgs[name])[attr];
};

public method .set_msg_attr(): nooverride {
    arg name, attr, value;
    var attrs;
    
    (> .perms(sender()) <);
    if ((!defined_msgs) || (!dict_contains(defined_msgs, name)))
        throw(~msgnf, (("Message \"" + name) + "\" is not defined on ") + this());
    if (attr == 'branches)
        [attrs, value] = (> ._parse_msg_branches(name, attr, value) <);
    else
        attrs = defined_msgs[name];
    if (!value)
        attrs = dict_del(attrs, attr);
    else
        attrs = dict_add(attrs, attr, value);
    defined_msgs = dict_add(defined_msgs, name, attrs);
};

public method .set_msg(): nooverride {
    arg name, branch, definer, value;
    var compiler, branches, msg, definer, b;
    
    (> .perms(sender()) <);
    compiler = (| definer.get_msg_attr(name, 'compiler) |) || $compiler;
    value = (> compiler.compile_cml(value) <);
    branch ?= "general";
    branches = definer.get_msg_attr(name, 'branches);
    if ((!find b in (branches) where (match_pattern(branch, b) != 0)) && match_pattern(branch + ".", b))
        throw(~badbranch, ("Message branch \"" + branch) + "\" is invalid.");
    msgs ?= #[];
    msg = dict_add((| msgs[name] |) || #[], branch, value);
    msgs = dict_add(msgs, name, msg);
};

public method .all_msgs() {
    arg @ms;
    var d, out, m, a, ams, av, v, b, at;
    
    out = #[];
    if (ms)
        ms = ms[1];
    else
        ms = msgs || #[];
    d = $compiler.compile_cml(">>NO DEFAULT<<");
    for a in ([this()] + ancestors()) {
        if (a == definer())
            break;
        catch any {
            ams = a.msgs();
            for m in (a.defined_msgs()) {
                [m, at] = m;
                v = (| ms[m] |);
                av = (| ams[m] |);
                if (v) {
                    if (av)
                        v = dict_union(av, v);
                    else
                        v = dict_union(hash b in (at['branches]) to ([b, d]), v);
                } else if (av) {
                    v = av;
                } else {
                    v = hash b in (at['branches]) to ([b, d]);
                }
                out = dict_add(out, m, v);
            }
        }
    }
    return out;
};

public method .msg_definer(): nooverride {
    arg name;
    var a;
    
    for a in (ancestors()) {
        if (a == definer())
            break;
        catch any {
            if ((a.defined_msgs())[name])
                return a;
        }
    }
    throw(~invmsg, ("Message \"" + name) + "\" is not defined.");
};

public method .eval_message() {
    arg name, definer, vars;
    var eval, msg, varkeys;
    
    eval = (| definer.get_msg_attr(name, 'evaluator) |) || $bs_eval;
    msg = $message_frob.new_with(.get_msg(name, definer));
    vars = dict_add(vars, 'evaluator, eval);
    if ((varkeys = (| definer.get_msg_attr(name, 'varkeys) |)))
        vars = dict_add(vars, 'varkeys, varkeys);
    else
        vars = dict_add(vars, 'varkeys, 0);
    msg = msg.set_vars(vars);
    vars = dict_add(vars, 'time, 'pre);
    return msg.eval_ctext(vars);
};

public method .gender() {
    return $gender_neuter;
};

public method .gender_context() {
    return "it";
};

public method .will_inherit(): nooverride {
    arg who;
    
    if ((this() != definer()) && (!(sender().has_ancestor(definer()))))
        throw(~perm, this() + " may only have parents who are descendants of $foundation");
    (> pass(who) <);
};

public method .get_local_msg() {
    arg name;
    
    return msgs[name];
};

public method .parse_msg(): nooverride {
    arg name, branch;
    var parser, name, def, b, parts, x, yes, m, mb, full, varkeys;
    
    if (!(def = (| .msg_definer(name) |))) {
        name = (> ._parse_msg_part(name, (.all_msgs()).keys()) <);
        def = (> .msg_definer(name) <);
    }
    if (!branch)
        return [def, name, "general"];
    if (listlen(branch) > 2)
        throw(~badmsg, "Too many message branches");
    m = [];
    varkeys = (| def.get_msg_attr(name, 'varkeys) |) || #[];
    for b in ((> def.get_msg_attr(name, 'branches) <)) {
        parts = explode(b, ".", "b");
        full = [];
        if (dict_contains(varkeys, parts[1])) {
            if ((mb = (| ._parse_msg_part(branch[1], [parts[1]]) |)))
                full += [mb] + sublist(branch, 2);
        } else if ((mb = (| ._parse_msg_part(branch[1], [parts[1]]) |))) {
            full += [mb];
        }
        if (full)
            m += [full];
    }
    branch = branch.join(".");
    if (listlen(m) == 1)
        full = m[1];
    else if (listlen(m) > 1)
        throw(~ambig, ("Multiple branches match the name '" + branch) + "'", m);
    else
        throw(~nomatch, ((("No branches of " + name) + " match '") + branch) + "'");
    if ((parser = (| def.get_msg_attr(name, 'parser) |)))
        return .(parser)(def, name, @full);
    return [def, name, join(full, ".")];
};

public method ._parse_msg_part(): nooverride {
    arg name, all;
    var m, parts, mparts, mname, yes, x;
    
    m = [];
    parts = explode(name, "-");
    for mname in (all) {
        mparts = explode(mname, "-");
        if (listlen(parts) == listlen(mparts)) {
            yes = 1;
            for x in [1 .. listlen(parts)] {
                if (!match_begin(mparts[x], parts[x])) {
                    yes = 0;
                    break;
                }
            }
            if (yes)
                m += [mname];
        }
    }
    if (listlen(m) == 1)
        name = m[1];
    else if (listlen(m) > 1)
        throw(~ambig, ("Multiple messages match the name '" + name) + "'", m);
    else
        throw(~nomatch, ("No messages match the name '" + name) + "'");
    return name;
};

private method ._parse_msg_branches(): nooverride {
    arg name, attr, value;
    var branch, p, varkeys, sub, m, attrs;
    
    if (!value)
        value = ["general"];
    attrs = defined_msgs[name];
    for branch in (value) {
        sub = explode(branch, ".");
        if (listlen(sub) > 2)
            throw(~msgbad, ("Too many message branches '" + branch) + "'.");
        for p in (sub) {
            if (((p[1]) == "(") || (p == "*"))
                varkeys++;
            else if (!($code_lib.valid_message_id(p)))
                throw(~msgbad, ("Branch '" + p) + "' contains invalid characters.");
        }
    }
    if (varkeys) {
        varkeys = #[];
        for branch in (value) {
            if (("(" in branch) || ("*" in branch)) {
                if ((m = regexp(branch, "\.\(([^)]+)\)$"))) {
                    sub = strsed(branch, "\.\(([^)]+)\)$", "");
                    value = replace(value, branch in value, sub + ".*");
                    varkeys = dict_add(varkeys, sub, m[1]);
                } else if ((branch = strsed(branch, "\.\*$", ""))) {
                    varkeys = dict_add(varkeys, branch, "$" + branch);
                } else {
                    throw(~msgbad, "Variable branch part must be last.");
                }
            }
        }
        attrs = dict_add(attrs, 'varkeys, varkeys);
    } else if (dict_contains(attrs, 'varkeys)) {
        attrs = dict_del(attrs, 'varkeys);
    }
    return [attrs, value];
};


new object $has_commands: $foundation;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $has_commands shortcuts = #[];
var $has_commands local = 0;
var $has_commands remote = 0;
var $root manager = $has_commands;
var $root managed = [$has_commands];

public method .add_command() {
    arg template, method, @type;
    var cmd, types, count, x;
    
    (> .perms(sender()) <);
    [(type ?= 'local)] = type;
    if ("*" in template)
        throw(~invcmd, "Invalid command, command templates cannot contain \"*\"!.");
    cmd = (> $command_lib.validate_command_template(template) <);
    if (!(type in ['local, 'remote]))
        throw(~type, "Command types can be either 'local or 'remote");
    if ('this in (((cmd[2]).values()).slice(1)))
        type = 'remote;
    if (type == 'remote) {
        for x in (((cmd[2]).values()).slice(1)) {
            if (x == 'this)
                count++;
        }
        if (!count)
            throw(~add_command, "Command type defined as remote with no <this> argument.");
        else if (count > 1)
            throw(~add_command, "More than one <this> argument specified in template.");
    }
    if (!get_var(type))
        set_var(type, #[]);
    set_var(type, get_var(type).setadd_elem((cmd[1])[1], [@cmd[1], template, method, cmd[2]]));
    if (type == 'remote)
        $remote_cache.add_remote_command((cmd[1])[1], this());
    else if ((.command_modules()) || filter x in (parents()) where ('general_cache in (x.flags())))
        (| .cache_client_init() |);
};

public method .all_local_commands() {
    var cmds, a, acmds;
    
    cmds = #[];
    for a in (ancestors()) {
        if (a == definer())
            break;
        if ((acmds = (| a.local_commands() |)))
            cmds = cmds.add(a, acmds);
    }
    return cmds;
};

public method .local_commands() {
    return local || #[];
};

public method .get_command_info() {
    arg type, cmd;
    var info, a, ainfo;
    
    info = [];
    for a in (ancestors()) {
        if (a == definer())
            break;
        if ((ainfo = (| a.command_info(type, cmd) |)))
            info = union(info, ainfo);
    }
    return info;
};

public method .del_command() {
    arg template, method;
    var cmd, c, d, info, type;
    
    (> .perms(sender()) <);
    cmd = template.explode();
    if (!cmd)
        throw(~type, "Invalid template.");
    cmd = cmd[1];
    info = #[['local, .get_command_info('local, cmd)]];
    info = info.add('remote, .get_command_info('remote, cmd));
    for type in (info) {
        for c in (type[2]) {
            if (((c[3]) == template) && ((c[4]) == method)) {
                set_var(type[1], get_var(type[1]).del_elem(cmd, c));
                if ((type[1]) == 'remote)
                    $remote_cache.del_remote_command(cmd, this());
                d++;
            }
        }
    }
    return d;
};

public method .remote_commands() {
    return remote || #[];
};

root method .init_has_commands() {
    local = (remote = (shortcuts = #[]));
};

root method .uninit_has_commands() {
    var c, cmd;
    
    for c in ((.remote_commands()).values()) {
        for cmd in (c)
            .del_command(cmd[3], cmd[4]);
    }
    (| clear_var('remote) |);
    (| clear_var('local) |);
    (| clear_var('shortcuts) |);
};

public method .add_shortcut() {
    arg shortcut, template, method;
    var relation;
    
    (> .perms(sender()) <);
    if ((type(shortcut) != 'string) || (type(template) != 'string))
        throw(~type, "Both shortcut and template must be strings.");
    if (type(method) != 'symbol)
        throw(~type, "Method must be submitted as a symbol.");
    relation = (> $command_lib.parse_relation(shortcut, template) <);
    shortcut = (relation[1])[1];
    relation = (relation[2])[2];
    if (!shortcuts)
        shortcuts = #[];
    shortcuts = shortcuts.add(shortcut, [method, relation]);
};

public method .del_shortcut() {
    arg shortcut;
    var value;
    
    (> .perms(sender()) <);
    
    // remove the cards, just use the raw template
    shortcut = strsed("-%1 %2", "%[0-9]+", "*");
    
    // delete it...
    value = (| shortcuts.del(shortcut) |);
    if (type(value) != 'dictionary)
        throw(~shortcutnf, ("Shortcut \"" + shortcut) + "\" is not defined on this object.");
    shortcuts = value;
};

public method .all_shortcuts() {
    var s, a, as;
    
    s = [];
    for a in (ancestors()) {
        if (a == definer())
            break;
        if ((as = (| a.shortcuts() |)))
            s += as.to_list();
    }
    return s;
};

public method .get_shortcut_info() {
    arg shortcut;
    
    return (| shortcuts[shortcut] |) || throw(~shortcutnf, ("Shortcut \"" + shortcut) + "\" is not defined on this object.", shortcut);
};

public method .shortcuts() {
    return shortcuts || #[];
};

public method .command_info() {
    arg type, cmd;
    
    return (| get_var(type)[cmd] |) || throw(~cmdnf, ("Command \"" + cmd) + "\" is not defined on this object.", cmd);
};

public method .all_remote_commands() {
    var cmds, a, acmds;
    
    cmds = #[];
    for a in (ancestors()) {
        if (a == definer())
            break;
        if ((acmds = (| a.remote_commands() |)))
            cmds = cmds.add(a, acmds);
    }
    return cmds;
};


new object $has_name: $foundation;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $has_name name = ['normal, "named object", "a named object"];
var $root manager = $has_name;
var $has_name templates = 0;
var $root managed = [$has_name];

public method .set_name() {
    arg new_name, @args;
    var type;
    
    (> .perms(sender()) <);
    [(type ?= 'normal)] = args;
    (> $code_lib.valid_name(new_name, type) <);
    switch (type) {
        case 'prop:
            new_name = [new_name, new_name];
        case 'uniq:
            new_name = [new_name, "the " + new_name];
        case 'normal:
            new_name = [new_name, new_name.add_indefinite()];
    }
    name = [type, @new_name];
};

public method .match_name() {
    arg str;
    var m, t;
    
    if (!str)
        return 0;
    if ((m = match_begin(name[2], str)))
        return m;
    for t in (templates || []) {
        if ((m = match_template(str, t)))
            return m;
    }
    return 0;
};

public method .name() {
    arg @args;
    
    if (!name)
        return tostr(this());
    if (!args)
        return name[3];
    switch (args[1]) {
        case 'type:
            return name[1];
        case 'noarticle:
            return name[2];
        default:
            return name;
    }
};

public method .name_templates() {
    return templates || [];
};

public method .namef() {
    arg type;
    
    switch (type) {
        case 'ref:
            return (((.name()) + " (") + this()) + ")";
        case 'xref:
            return ((this() + " (") + (.name())) + ")";
        case 'name:
            return .name();
        case 'noarticle:
            return .name('noarticle);
        default:
            return (> pass(type) <);
    }
};

public method .hname() {
    arg @args;
    
    return ((("<a href=\"/bin/describe?target=" + (.objname())) + "\">") + ((.name()).to_html())) + "</a>";
};

public method .add_name_template() {
    arg template;
    var p, r;
    
    (> .perms(sender()) <);
    if ((r = regexp(template, "[^a-z0-9|?_-]+")))
        throw(~invtmpl, "Template contains invalid characters (allowed: a-z, 0-9, _ and -)");
    for p in (explode(template, "|")) {
        if (match_begin(name[2], p.strip()))
            throw(~redundant, ("Redundant name template part \"" + p) + "\" already matches name.");
    }
    templates = setadd(templates || [], template);
};

public method .del_name_template() {
    arg template;
    
    (> .perms(sender()) <);
    templates = setremove(templates || [], template);
    if (!templates)
        (| clear_var('templates) |);
};

public method .init_has_name() {
    var objname;
    
    objname = tostr(this());
    if ((objname[1]) == "$")
        objname = substr(objname, 2);
    name = ['prop, objname, objname];
};

public method .match_name_exact() {
    arg str;
    
    return str == (name[2]);
};


new object $described: $has_name, $has_commands;

var $described prose = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['uniq, "Generic Described Object", "the Generic Described Object"];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $root manager = $described;
var $foundation edit_types = ["prose"];
var $dmi_data descriptions = #[];
var $root managed = [$described];

root method .init_described() {
    prose = [];
};

protected method .description() {
    arg flags;
    var out, name;
    
    out = $ctext_frob.new_with([$cml_lib.format_subj_tag(.name())]);
    if ((| flags['prose] |))
        return [out.append(.prose())];
    return [out];
};

public method .prose() {
    arg @no_default;
    
    return ((type(prose) == 'frob) ? (prose.set_var('this, this())) : prose) || (no_default ? 0 : "You see nothing special");
};

public method .set_prose() {
    arg new;
    
    (> .perms(sender()) <);
    if (new != 0) {
        switch (type(new)) {
            case 'string, 'list:
                new = (> $compiler.compile_cml(new) <);
            case 'frob:
                // we'll let this pass by unharmed -- potentially dangerous
            default:
                throw(~invalid, "Prose can be submitted as CML or Ctext");
        }
    }
    prose = new;
};

root method .uninit_described() {
    prose = 0;
};

public method .get_description(): nooverride {
    arg @dflags;
    var flags, f;
    
    flags = #[['prose, 1], ['actor, sender()]];
    if (dflags && (type(dflags[1]) == 'dictionary))
        flags = dict_union(flags, dflags[1]);
    return .description(flags);
};

public method .edit_prose() {
    var p;
    
    (> .perms(sender()) <);
    p = .prose();
    if (type(p) == 'frob)
        p = p.uncompile();
    (> sender().invoke_editor(this(), '_edit_prose_callback, p, []) <);
};

public method ._edit_prose_callback() {
    arg text, client_data;
    
    (> .perms(caller(), $editor_reference) <);
    catch ~parse
        .set_prose(text);
    with
        return ['failure, ["Error: " + ((traceback()[1])[2])]];
    return ['success, ["Description set."]];
};

public method .configure() {
    arg set;
    var p, end, ctext, s, still, type;
    
    set = (> pass(set) <);
    s = sender();
    still = ("Do you still want to describe " + (.name())) + "? [no] ";
    if (!(set.contains('described_prose))) {
        while (!end) {
            if (.is($path))
                type = "exit ";
            else if (.is($place))
                type = "place ";
            else
                type = "";
            p = s.read((("Describe " + type) + (.name())) + ", Enter \".\" to finish or \"@abort\" to abort description.");
            if (p == 'aborted) {
                end = !(s.prompt_yesno(still, 0));
            } else {
                catch any {
                    ctext = (> $compiler.compile_cml(p) <);
                    s.tell(["You submitted the following description:", ""]);
                    s.tell(ctext);
                    s.tell("");
                    if (!(end = s.prompt_yesno("Keep this description? [yes] ")))
                        ctext = 0;
                } with {
                    s.tell(["The following CML compiler error occurred:", "  ", (traceback()[1])[2]]);
                    end = !(s.prompt_yesno(still, 0));
                }
            }
        }
        if (ctext)
            .set_prose(ctext);
        set = set.add('described_prose, 1);
    }
    return set;
};

public method .get_detail() {
    arg name;
    var details, d, matches;
    
    details = (| (.prose()).get_var('details) |);
    if (!details)
        throw(~nodetail, ("No \"" + name) + "\" in your environment.");
    matches = [];
    for d in (details.keys()) {
        if (match_begin(d, name))
            matches += [d];
    }
    if (!matches)
        throw(~nodetail, ("No \"" + name) + "\" in your environment.");
    if (listlen(matches) != 1)
        throw(~ambig, (("\"" + name) + "\" can match ") + (matches.to_english()));
    return (<$ctext_frob, [details[matches[1]], #[['this, this()]]]>);
};


new object $event_handler: $foundation;

var $root manager = $event_handler;
var $root managed = [$event_handler];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850790316;
var $root inited = 1;
var $event_handler hooks = #[];
var $event_handler hooked = #[];
var $event_handler events = 0;
var $root help_node = $help_sys_events;

root method .uninit_event_handler() {
    var event, obj, update_on;
    
    for update_on in ((events || #[]).keys()) {
        for event in ((events[update_on]).keys())
            (| .deregister_event(event, update_on) |);
    }
    for obj in ((hooks || #[]).keys()) {
        for event in (hooks[obj])
            (| obj.event_hook_removed(event) |);
    }
};

public method .clear_event_hook() {
    arg event;
    var o;
    
    (> .perms(sender(), 'writer) <);
    if ((!hooks) || (!(hooks.contains(event))))
        return;
    for o in (hooks[event])
        (| o.event_hook_removed(event) |);
    hooks = dict_del(hooks, event);
    if (!hooks) {
        (| clear_var('hooks) |);
        (| clear_var('hooked) |);
    }
};

public method .event_hooks() {
    if (hooks)
        return dict_keys(hooks);
    return [];
};

public method .hook_into_event() {
    arg event;
    
    if (!hooks)
        hooks = #[];
    (> .will_hook(event, sender()) <);
    hooks = dict_add(hooks, event, setadd((| hooks[event] |) || [], sender()));
    hooked = (hooked || #[]).setadd_elem(sender(), event);
    (| .did_hook(event, sender()) |);
};

public method .unhook_from_event() {
    arg event;
    var events;
    
    if (hooks) {
        events = (| hooks[event] |) || [];
        events = setremove((| hooks[event] |) || [], sender());
        if (events)
            hooks = dict_add(hooks, event, setremove(hooks[event], sender()));
        else
            hooks = (| dict_del(hooks, event) |);
    }
    if (hooked)
        hooked = hooked.del_elem(sender(), event);
};

public method .unhook_from_all() {
    var e;
    
    if ((!hooked) || (!(hooked.contains(sender()))))
        return;
    for e in (hooked[sender()])
        hooks = dict_add(hooks, e, setremove(hooks[e], sender()));
    hooked = dict_del(hooked, sender());
};

protected method .will_hook() {
    arg event, obj;
    
};

protected method .did_hook() {
    arg event, obj;
    
};

public method .send_event() {
    arg event, @args;
    var o;
    
    // some sort of perms checking..
    if ((!hooks) || (!(hooks.contains(event))))
        return;
    for o in (hooks[event]) {
        if (!valid(o)) {
            hooks = dict_add(hooks, event, setremove(hooks[event], o));
            hooked = (hooked || #[]).del_elem(o, event);
        }
        (| o.event_notify(event, sender(), @args) |);
    }
    if (!hooked)
        (| clear_var('hooked) |);
};

public method .event_notify() {
    arg event, origin, @args;
    
    if (caller() != $event_handler)
        throw(~perm, caller() + " is not $event_handler.");
};

public method .event_hook_removed() {
    arg event;
    
    (> .perms(caller(), $event_handler) <);
};

public method .deregister_event() {
    arg event, update_on;
    var value, event, src, status;
    
    (> .perms(sender()) <);
    if ((events.contains(update_on)) && ((events[update_on]).contains(event))) {
        // clean it up first.. (ignore status)
        [status, src] = (events[update_on])[event];
        switch (src) {
            case 'location:
                (| loc.unhook_from_event(event) |);
            case 'this:
                (| .unhook_from_event(event) |);
            default:
                (| src.hook_into_event(event) |);
        }
    
        // now cleanup 'events'
        value = (events[update_on]).del(event);
        if (value)
            events = events.add(update_on, value);
        else
            events = events.del(update_on);
        if (!events)
            clear_var('events);
    }
};

public method .hook_events() {
    arg type;
    var status, source, event, l, all;
    
    if (events && (events.contains(type))) {
        all = events[type];
        events = events.del(type);
        l = .location();
        for event in (all) {
            [event, [status, source]] = event;
            switch (source) {
                case 'location:
                    l.hook_into_event(event);
                case 'this:
                    .hook_into_event(event);
                default:
                    source.hook_into_event(event);
            }
            all = all.add(event, [1, source]);
        }
        events = events.add(type, all);
    }
};

public method .register_event() {
    arg event, update_on, src;
    var value, all;
    
    (> .perms(sender()) <);
    if (!events)
        events = #[];
    
    // If/when more are added.. also update $help_sys_event_register
    if ((update_on != 'move) && (update_on != 'startup))
        throw(~type, "Update on must be either 'move or 'startup");
    if (type(src) == 'symbol) {
        if ((src != 'location) && (src != 'this))
            throw(~type, "Source types must be either 'location or 'this.");
    } else if (type(src) != 'objnum) {
        throw(~type, "Source type must be either a symbol or object.");
    } else if (!(src.is($event_handler))) {
        throw(~type, ("Source " + (src.namef('ref))) + " is not an event handler.");
    }
    if (events.contains(update_on)) {
        all = events[update_on];
        if ((events[update_on]).contains(event)) {
            value = replace(all[event], 2, src);
            events = events.add(update_on, all.add(event, value));
        } else {
            events = events.add(update_on, all.add(event, [0, src]));
        }
    } else {
        events = events.add(update_on, #[[event, [0, src]]]);
    }
};

public method .unhook_events() {
    arg type, @loc;
    var all, event, status, source;
    
    if (events && (events.contains(type))) {
        all = events[type];
        events = events.del(type);
        loc = loc ? (loc[1]) : (.location());
        for event in (all) {
            [event, [status, source]] = event;
            switch (source) {
                case 'location:
                    (| loc.unhook_from_event(event) |);
                case 'this:
                    (| .unhook_from_event(event) |);
                default:
                    (| source.hook_into_event(event) |);
            }
            all = all.add(event, [0, source]);
        }
        events = events.add(type, all);
    }
};


new object $utilities: $core;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root manager = $utilities;
var $root managed = [$utilities];


new object $lag_watcher: $utilities;

var $root manager = $lag_watcher;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $lag_watcher lags = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
var $lag_watcher last_time = 1011937114;
var $root managed = [$lag_watcher];

public method .startup() {
    arg @args;
    
    // Called by $sys.startup()
    (> .perms(sender(), 'manager) <);
    lags = [];
    last_time = time();
    $heart.add_heartbeat(14);
};

protected method .update() {
    arg lag;
    
    // Called by .pulse() every 15 minutes
    if (type(lags) != 'list)
        lags = [];
    while ((lags.length()) > 9)
        lags = lags.delete(1);
    lag = (lag > 15) ? (lag - 15) : 0;
    lags += [lag];
};

public method .lag_str() {
    return ("Current server lag is " + (.lag())) + " seconds.";
};

public method .lag() {
    var lag, total, weight, lag_i, lag_d;
    
    // the current lag floated
    total = 0;
    weight = 0;
    for lag in (lags) {
        ++weight;
        total += lag * weight;
    }
    lag_i = total / 55;
    lag_d = tostr(((total - (lag_i * 55)) * 10) / 55).subrange(1, 1);
    return (tostr(lag_i) + ".") + lag_d;
};

public method .verbose_lag_str() {
    // returns lag as a string with verbosity
    return [("Current server lag is " + (.lag())) + " seconds.", toliteral(lags)];
};

public method .value() {
    var lag, total, weight, lag_i;
    
    // unparsed lag value
    total = 0;
    weight = 0;
    for lag in (lags) {
        ++weight;
        total += lag * weight;
    }
    lag_i = total / 55;
    return lag_i;
};

public method .pulse() {
    var lag;
    
    // Called by $heart every 15 seconds
    (> .perms(sender(), $heart) <);
    lag = time() - last_time;
    last_time = time();
    .update(lag);
};

public method .shutdown() {
    // Called by $sys.shutdown();
    (> .perms(sender(), 'manager) <);
    $heart.del_heartbeat();
    last_time = 0;
    lags = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
};


new object $heart: $utilities;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $heart heart_failures = [];
var $heart hearts = [[$lag_watcher, 1011937128], [$world, 1011937370]];
var $root manager = $heart;
var $root managed = [$heart];
var $heart info = #[[$world, [600, 1011936770]], [$lag_watcher, [14, 1011937114]]];

public method .pulse() {
    var heart, h, x, new;
    
    for heart in (hearts) {
        if ((heart[2]) > time())
            break;
        if (!valid(heart[1]))
            ._del_heartbeat(heart[1]);
        catch any
            (> (heart[1]).pulse() <);
        with
            (| ((heart[1]).manager()).tell_traceback(traceback()) |);
        ._add_heartbeat(heart[1], (info[heart[1]])[1]);
    }
};

public method .add_heartbeat() {
    arg @delay;
    
    [(delay ?= 60)] = delay;
    ._add_heartbeat(sender(), delay);
};

public method .del_heartbeat() {
    if (!(._del_heartbeat(sender())))
        throw(~objnf, ("Sender (" + sender()) + ") does not have a heartbeat.");
};

public method .hearts() {
    return hearts;
};

private method ._add_heartbeat() {
    arg obj, delay;
    var when, h, values;
    
    // Only one heartbeat per object
    ._del_heartbeat(obj);
    when = delay + time();
    info = dict_add(info, obj, [delay, time()]);
    for h in [1 .. listlen(hearts)] {
        if (((hearts[h])[2]) >= when) {
            hearts = insert(hearts, h, [obj, when]);
            return;
        }
    }
    hearts += [[obj, when]];
};

private method ._del_heartbeat() {
    arg obj;
    var x, pos;
    
    if (info.contains(obj))
        info = info.del(obj);
    for x in [1 .. listlen(hearts)] {
        if (((hearts[x])[1]) == obj) {
            hearts = delete(hearts, x);
            return 1;
        }
    }
    return 0;
};

root method .core_heart(): nooverride {
    var h;
    
    for h in (hearts) {
        if (!valid(h[1]))
            ._del_heartbeat(h[1]);
    }
};


new object $scheduler: $utilities;

var $root created_on = 810294797;
var $root inited = 1;
var $root flags = ['methods, 'code, 'core];
var $scheduler task_index = 2;
var $scheduler blocked_tasks = #[];
var $scheduler task_queue = [];
var $scheduler sub_schedulers = [$heart];
var $scheduler expected_lag = 0;
var $scheduler server_lag = 0;
var $root manager = $scheduler;
var $scheduler suspended_tasks = #[];
var $root managed = [$scheduler];
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];

public method .sleep() {
    arg howlong;
    
    .add_task(howlong, 'resume_job, task_id());
    .suspend(this());
};

private method .remove_first_task() {
    // sender must be an agent, or admin.
    catch any {
        .del_from_task_queue(1);
    } with {
        // $sys.log(traceback());
    }
    if (!task_queue)
        task_index = 1;
};

public method .task_queue() {
    // sender must be system, for now
    (> .perms(sender(), 'system) <);
    return task_queue;
};

public method .del_task() {
    arg tid;
    var task, n;
    
    // sender must be system, for now.
    if (type(tid) != 'integer)
        throw(~type, "Task Identification must be an integer");
    for task in (task_queue) {
        n++;
        if ((task[1]) == tid) {
            ((sender() == (task[4])) && (caller() == (task[5]))) || (> .perms(sender(), 'system) <);
            .del_from_task_queue(n);
            return 1;
        }
    }
    throw(~tasknf, "No task found by that TID");
};

public method .add_task() {
    arg time, method, @args;
    var task, i, j, tid, flags, x, y, task_time;
    
    if ((type(time) != 'integer) || ((type(method) != 'symbol) || (type(args) != 'list)))
        throw(~type, "Arguments are not an integer, symbol, and list.");
    if (time < 0)
        throw(~time, "Time is negative.");
    if (time > 31536000)
        throw(~time, "Try to schedule a task LESS than a year from now?");
    
    // get a new db task id
    ++task_index;
    tid = task_index;
    
    // flags can be set in a system only add_task, for now set them as 'system
    flags = ['system];
    task_time = time();
    task = [tid, time + task_time, task_time, sender(), caller(), method, flags, args];
    .add_to_task_queue(task);
    return tid;
};

public method .pulse() {
    var task, sub, t;
    
    // called by $sys.heartbeat
    if (caller() != $sys)
        throw(~perm, "Sender is not system");
    t = time();
    while (task_queue && (t > ((task_queue[1])[2]))) {
        task = task_queue[1];
        .remove_first_task();
        catch any
            (> (task[4]).as_this_run(task[4], task[6], task[8]) <);
        with
            (| ((task[4]).manager()).tell_traceback(traceback()) |);
    }
    
    // call sub schedulers 
    for sub in (sub_schedulers)
        (| sub.pulse() |);
};

public method .sys_add_task() {
    arg time, method, sender, caller, flags, @args;
    var task, i, j, tid, x, y, tmpq, task_time;
    
    // use `@info $scheduler' for more information. 
    // [tid, time, time(), sender(), caller(), method, flags, args]
    //
    if (!($sys.is_agent(sender())))
        throw(~perm, "Sender is not an agent or admin, use .add_task()");
    if ((type(time) != 'integer) || ((type(method) != 'symbol) || (type(args) != 'list)))
        throw(~type, "Arguments are not an integer, symbol, and list.");
    if (time < 1)
        throw(~time, "Time is negative.");
    if (time > 31536000)
        throw(~time, "Try to schedule a task LESS than a year from now?");
    if (!valid(sender))
        throw(~type, "The argument for sender is not a valid object");
    if (!valid(caller))
        throw(~type, "The argument for caller is not a valid object");
    if (type(flags) != 'list)
        throw(~type, "Send flags as a list of symbols");
    
    //
    ++task_index;
    tid = task_index;
    task_time = time();
    
    // flags can be set in a system only add_task, for now set them as 'system
    task = [tid, task_time + time, task_time, sender, caller, method, flags, args];
    .add_to_task_queue(task);
    return tid;
};

public method .add_sub_scheduler() {
    arg object;
    
    if (!($sys.is_admin(sender())))
        throw(~perm, "Only admins may add sub schedulers.");
    if (type(object) != 'objnum)
        throw(~type, "Object must be a dbref.");
    sub_schedulers += [object];
};

public method .del_sub_scheduler() {
    arg object;
    var pos, s;
    
    if (!($sys.is_admin(sender())))
        throw(~perm, "Only admins may delete sub schedulers.");
    if (type(object) != 'objnum)
        throw(~type, "Object must be a dbref.");
    pos = object in sub_schedulers;
    if (!pos)
        throw(~objnf, "Object not a sub scheduler.");
    s = [];
    if (pos > 1)
        s += [sub_schedulers.subrange(1, pos - 1)];
    if (s < (sub_schedulers.length()))
        s += [sub_schedulers.subrange(pos + 1)];
    sub_schedulers = s;
};

public method .has_blocked_tasks() {
    arg ident;
    
    return blocked_tasks.contains(ident);
};

public method .block_task() {
    arg ident;
    var tasks;
    
    // I want to be atomic!
    // Add the task_id to the queue of blocked tasks for this identifier.
    if (blocked_tasks.contains(ident))
        tasks = (blocked_tasks[ident]) + [task_id()];
    else
        tasks = [task_id()];
    blocked_tasks = blocked_tasks.add(ident, tasks);
    
    // And go to sleep until we are woken.
    return (> suspend() <);
};

public method .unblock_task() {
    arg ident;
    var tasks;
    
    // I want to be atomic!
    // The caller should have checked first, but we will fail silently.
    if (!(.has_blocked_tasks(ident)))
        return;
    
    // Get the blocked tasks queue for this identifier.
    tasks = blocked_tasks[ident];
    
    // If this is the last blocked task, then clear the queue, otherwise
    // just delete the task_id that we are resuming.
    if ((tasks.length()) == 1)
        blocked_tasks = blocked_tasks.del(ident);
    else
        blocked_tasks = blocked_tasks.add(ident, tasks.delete(1));
    
    // Wake it up and go.
    resume(tasks[1]);
};

protected method .resume_job() {
    arg tid;
    
    (> .resume(tid) <);
};

public method .suspend() {
    arg @objs;
    
    objs += [user()];
    suspended_tasks = dict_add(suspended_tasks, task_id(), objs);
    return (> suspend() <);
};

public method .resume() {
    arg task_id, @return_value;
    var objs;
    
    if ((objs = (| suspended_tasks[task_id] |))) {
        if ((!(sender() in objs)) && (!($sys.is_system(sender()))))
            throw(~perm, (sender() + " may not resume task ") + task_id);
        suspended_tasks = dict_del(suspended_tasks, task_id);
    }
    return (> resume(task_id, @return_value) <);
};

public method .cancel() {
    arg task_id;
    var objs;
    
    // suspended tasks
    if ((objs = (| suspended_tasks[task_id] |))) {
        if ((!(sender() in objs)) && (!($sys.is_system(sender()))))
            throw(~perm, (sender() + " may not cancel task ") + task_id);
        suspended_tasks = dict_del(suspended_tasks, task_id);
    
        // preempted tasks 
    } else if (!($sys.is_system(sender()))) {
        throw(~perm, (sender() + " may not kill task ") + task_id);
    }
    return (> cancel(task_id) <);
};

public method .task_info() {
    arg @args;
    
    (> .perms(sender(), 'system) <);
    return (> task_info(@args) <);
};

public method .suspended_task() {
    arg task;
    
    return (> suspended_tasks[task] <);
};

private method .del_from_task_queue() {
    arg i;
    
    refresh();
    
    // this must *not* throw
    task_queue = $heap.del(task_queue, i, 2);
};

private method .add_to_task_queue() {
    arg task;
    
    refresh();
    
    // We don't want to run out of tics
    task_queue = $heap.push(task_queue, task, 2);
};

root method .core_scheduler() {
    suspended_tasks = #[];
    blocked_tasks = #[];
    task_queue = [];
};


new object $file: $utilities;

var $root manager = $file;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 843324817;
var $root inited = 1;
var $root managed = [$file];
var $root trusted = [$mime_lib];

public method .fstat() {
    arg @path;
    
    if (!path)
        throw(~perm, "Perm.");
    return (> fstat(@path) <);
};

public method .files() {
    arg path;
    
    return (> files(path) <);
};

public method .fwrite() {
    arg what;
    
    return fwrite(what);
};

public method .fopen() {
    arg @args;
    
    return (> fopen(@args) <);
};

public method .fclose() {
    return fclose();
};

public method .fread() {
    arg @args;
    
    return (> fread(@args) <);
};

public method .fchmod() {
    arg @args;
    
    return fchmod(@args);
};

public method .fmkdir() {
    arg @args;
    
    return fmkdir(@args);
};

public method .frmdir() {
    arg @args;
    
    return frmdir(@args);
};

public method .fremove() {
    arg @args;
    
    return fremove(@args);
};

public method .frename() {
    arg @args;
    
    return frename(@args);
};

public method .fseek() {
    arg @args;
    
    return fseek(@args);
};

public method .feof() {
    arg @args;
    
    return feof(@args);
};

public method .fflush() {
    arg @args;
    
    return fflush(@args);
};

public method .open() {
    arg @args;
    
    // add in locks... $mutex?
    return (> .fopen(@args) <);
};

public method .close() {
    // add in locks... $mutex?
    return (> .fclose() <);
};


new object $changelog: $file;

var $root manager = $changelog;
var $root managed = [$changelog];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 906983169;
var $dmi_data descriptions = #[];
var $root inited = 1;

public method .log() {
    arg entry;
    
    if (!($changelog_group.includes(caller())))
        (> .perms(sender()) <);
    
    // just silently die if logs/ isn't there
    catch any {
        .fopen("logs/changelog", ">>");
        .fwrite((("[" + time()) + "] ") + entry);
        .fclose();
    }
};


new object $web_file: $file;

var $root manager = $web_file;
var $root managed = [$web_file];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 999321766;
var $dmi_data descriptions = #[];
var $root inited = 1;


new object $compiler: $utilities;

var $root manager = $compiler;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837583518;
var $root inited = 1;
var $root managed = [$compiler];
var $compiler glue_table = ["p", "br", "ul", "ol", "dl", "table", "switch", "case", "range", "default"];

public method .parse_string_new() {
    arg vars, tokens;
    var mode, out, word, token, i, tmp, ret;
    
    if (!tokens)
        return [[], vars];
    mode = ['spaces, 'plain];
    i = 1;
    out = [];
    word = "";
    while (i <= (tokens.length())) {
        refresh();
        token = tokens[i++];
        switch (mode[1]) {
            case 'spaces:
                if (token != " ") {
                    i--;
                    mode = mode.subrange(2);
                }
            case 'plain:
                if (!(token in ["{", "["])) {
                    if (token == " ") {
                        // No scatter because .check can throw
                        if ((| (ret = ._check_glue(tokens, i)) |)) {
                            i = ret[1];
                            mode = [ret[2], @mode];
                            if (word)
                                out += [word];
                            word = "";
                            continue;
                        }
                    }
                    word += token.sed("\\\(.)", "%1", "g");
                } else {
                    if (word)
                        out += [word];
                    word = "";
                    mode = ['spaces, (token == "{") ? 'fmtname : 'genname, @mode];
                }
            case 'fmtname, 'genname:
                if (((mode[1]) == 'fmtname) && (token == "quote")) {
                    mode = mode.subrange(2);
                    out += [$format.new_tag("quote", [], [tokens[i++]])];
                    i++;
                } else {
                    if (token in glue_table)
                        mode = [mode[1], 'spaces, @mode.subrange(2)];
                    mode = ['spaces, 'flags, #[], token, @mode];
                }
            case 'flags:
                if (token in ["}", "]"]) {
                    ret = (> ._make_tag(token, mode[4], vars, mode[3], mode[2], []) <);
                    vars = ret[2];
                    out += [ret[1]];
                    mode = mode.subrange(5);
                } else if (token == "=") {
                    throw(~parse, "Value flag with no key.");
                } else if (token == ":") {
                    mode = ['spaces, 'args, out, mode[2], @mode.subrange(3)];
                    out = [];
                } else if ((| (tokens[i]) == "=" |)) {
                    mode = ['flagvalue, token, @mode];
                    i++;
                } else {
                    mode = mode.replace(2, (mode[2]).add(token, 1));
                }
            case 'flagvalue:
                if (token in ["}", "]", ":"]) {
                    mode = mode.subrange(3);
                    i--;
                } else if (token == " ") {
                    mode = mode.subrange(3);
                } else if (!(token in ["[", "{"])) {
                    mode = ['spaces, @(mode.subrange(3)).replace(2, (mode[4]).add(mode[2], token.sed("\\\(.)", "%1", "g")))];
                } else {
                    if (word)
                        out += [word];
                    word = "";
                    mode = ['spaces, (token == "{") ? 'fmtname : 'genname, 'flagset, @mode.subrange(2)];
                }
            case 'flagset:
                i--;
                mode = ['spaces, @(mode.subrange(3)).replace(2, (mode[4]).add(mode[2], out[out.length()]))];
                out = out.subrange(1, (out.length()) - 1);
            case 'args:
                if (token in ["}", "]"]) {
                    if (word) {
                        out += [word];
                        word = "";
                    }
                    ret = ._make_tag(token, mode[5], vars, mode[4], mode[3], out);
                    vars = ret[2];
                    out = (mode[2]) + [ret[1]];
                    mode = mode.subrange(6);
                } else if (token in ["{", "["]) {
                    if (word)
                        out += [word];
                    word = "";
                    mode = ['spaces, (token == "{") ? 'fmtname : 'genname, @mode];
                } else {
                    if (token == " ") {
                        if ((| (ret = ._check_glue(tokens, i)) |)) {
                            i = ret[1];
                            mode = [ret[2], @mode];
                            if (word)
                                out += [word];
                            word = "";
                            continue;
                        }
                    }
                    word += token.sed("\\\(.)", "%1", "g");
                }
        }
    }
    if (word)
        out += [word];
    while ((mode[1]) == 'spaces)
        mode = mode.subrange(2);
    if (mode != ['plain])
        throw(~parse, "Unclosed tag.");
    return [out, vars];
};

public method .tokenize() {
    arg text;
    var word, out, escaped, token, i, pre_count, open_form, str;
    
    // break text into a list of tokens.
    if (type(text) == 'string)
        text = [text];
    out = [];
    word = "";
    escaped = 0;
    
    // pre_count is 0, except inside pre, when it counts the {}'s
    pre_count = 0;
    open_form = 0;
    for str in (text) {
        str = str.explode(" ", 1);
        for token in (str) {
            refresh();
            if ((!token) && (!pre_count))
                continue;
            while ((i = token.match_regexp("[][{}=\:]"))) {
                refresh();
                i = (i[1])[1];
                if (escaped) {
                    escaped = 0;
                    word = (word + "\\") + (token.subrange(1, i));
                } else if (pre_count) {
                    if ((token[i]) == "{") {
                        pre_count++;
                        word += token.subrange(1, i);
                    } else if ((token[i]) == "}") {
                        pre_count--;
                        if (pre_count) {
                            word += token.subrange(1, i);
                        } else {
                            word += token.subrange(1, i - 1);
                            out = word ? (out + [word, token[i]]) : (out + [token[i]]);
                            word = "";
                        }
                    } else {
                        word += token.subrange(1, i);
                    }
                } else {
                    word += token.subrange(1, i - 1);
                    open_form = (token[i]) == "{";
                    if ((token[i]) == "\\") {
                        escaped = 1;
                    } else {
                        out = word ? (out + [word, token[i]]) : (out + [token[i]]);
                        word = "";
                    }
                }
                token = token.subrange(i + 1);
            }
            if (open_form && (token == "quote")) {
                pre_count = 1;
                open_form = 0;
                out += [token];
                token = "";
                continue;
            }
            word += token;
            if (escaped || pre_count) {
                escaped = 0;
                word += " ";
            } else {
                out = word ? (out + [word, " "]) : (out + [" "]);
                word = "";
            }
        }
        if (pre_count)
            word = word ? ((word.subrange(1, (word.length()) - 1)) + "\n") : "\n";
    }
    if (word)
        out += [word];
    if (out) {
        if ((out.last()) == " ")
            out = out.subrange(1, (out.length()) - 1);
        else
            out = out.replace(out.length(), (out.last()).subrange(((out.last()).length()) - 1));
    }
    return out;
};

public method ._make_tag() {
    arg token, mode, vars, name, flags, args;
    var method, class;
    
    if (mode == 'fmtname) {
        if (token != "}")
            throw(~parse, "Extra ']' encountered.");
        method = tosym("do_" + (name.strip()));
        class = $format;
    }
    if (mode == 'genname) {
        if (token != "]")
            throw(~parse, "Extra '}' encountered.");
        method = tosym("gen_" + (name.strip()));
        class = $generator;
    }
    catch ~methodnf
        return (> .(method)(vars, flags, args) <);
    with
        return (> [class.new_tag(name, flags, args), vars] <);
};

public method .compile_cml() {
    arg text;
    var vars, ret;
    
    vars = #[];
    (> (ret = .parse_string_new(vars, .tokenize(text))) <);
    return $ctext_frob.new_with(ret[1], ret[2]);
};

public method .do_link() {
    arg vars, flags, args;
    var links, item, node;
    
    if (listlen(args) == 0)
        throw(~parse, "{link} requires an argument of the link name.");
    links = (| vars['links] |) || #[];
    for item in (flags) {
        if ((type(item) == 'list) && ((item[1]) == "node")) {
            node = item[2];
            break;
        }
    }
    if (!node)
        throw(~parse, "No node for {link}.");
    if (((args.length()) != 1) || (type(args[1]) != 'string))
        throw(~parse, "{link} argument must be a string");
    links = links.add(args[1], node);
    return [$format.new_tag("link", flags, args), vars.add('links, links)];
};

public method .do_detail() {
    arg vars, flags, args;
    var dets, item, name;
    
    dets = (| vars['details] |) || #[];
    for item in (flags) {
        if ((type(item) == 'list) && ((item[1]) == "name")) {
            name = item[2];
            break;
        }
    }
    if (!name)
        throw(~parse, "No name for {detail}.");
    dets = dets.add(name, args);
    return [$format.new_tag("detail", flags, []), vars.add('details, dets)];
};

public method ._kill_spaces() {
    arg list;
    var i;
    
    return filter i in (list) where (i != " ");
};

public method .do_table() {
    arg vars, flags, args;
    
    if (!(flags.contains("cols")))
        throw(~parse, "no 'cols' flag for {table}.");
    return [$format.new_tag("table", flags, ._kill_spaces(args)), vars];
};

public method .do_tr() {
    arg vars, flags, args;
    
    return [$format.new_tag("tr", flags, ._kill_spaces(args)), vars];
};

public method .do_ul() {
    arg vars, flags, args;
    
    return [$format.new_tag("ul", flags, ._kill_spaces(args)), vars];
};

public method .do_dl() {
    arg vars, flags, args;
    
    return [$format.new_tag("dl", flags, ._kill_spaces(args)), vars];
};

public method .do_ol() {
    arg vars, flags, args;
    
    return [$format.new_tag("ol", flags, ._kill_spaces(args)), vars];
};

public method ._check_glue() {
    arg tokens, i;
    var j, bracket;
    
    // WARNING: This method can throw (it should be called with (| |)'s)
    while ((tokens[i]) == " ")
        i++;
    if ((bracket = tokens[i++]) in ["{", "["]) {
        while ((tokens[i]) == " ")
            i++;
        j = i;
        if ((tokens[i]) in glue_table)
            return [j, (bracket == "{") ? 'fmtname : 'genname];
    }
    return 0;
};

public method .gen_switch() {
    arg vars, flags, args;
    var current, d, tag, i, m, r;
    
    if (listlen(args) == 0)
        throw(~parse, "[switch] requires arguments.");
    if (!(| flags["value"] |))
        throw(~parse, "Value flag missing.");
    d = #[];
    r = [];
    tag = (current = 0);
    
    // The last default is a dummy - it forces the parser to flush current
    for i in (args + [$generator.new_tag("default", [], [])]) {
        if ((type(i) == 'frob) && ((class(i) == $generator) && ((i.name()) in ["case", "default", "range"]))) {
            if (tag != 0) {
                if (type(tag) == 'list)
                    r += [[@tag.subrange(2), current]];
                else
                    d = d.add(tag, current);
            }
            current = [];
            switch (i.name()) {
                case "case":
                    if ((((i.args()).length()) != 1) || (type((tag = (i.args())[1])) != 'string))
                        throw(~parse, "[case:...] takes only a single string as an argument.");
                case "range":
                    if ((((i.args()).length()) != 1) || (!(| ((m = ((i.args())[1]).match_pattern("*..*")).length()) == 2 |)))
                        throw(~parse, "range tag should look like [range:lower..upper].");
                    tag = ['range, @m];
                case "default":
                    tag = 'default;
            }
        } else {
            if (tag == 0)
                throw(~parse, "Expression before [case]");
            current += [i];
        }
    }
    if (r)
        d = d.add('ranges, r);
    return [$generator.new_tag("switch", flags, d), vars];
};

public method .glue_table() {
    return glue_table;
};

public method .do_switch() {
    arg vars, flags, args;
    var current, d, tag, i, m, r;
    
    if (listlen(args) == 0)
        throw(~parse, "[switch] requires arguments.");
    if (!(| flags["value"] |))
        throw(~parse, "Value flag missing.");
    d = #[];
    r = [];
    tag = (current = 0);
    
    // The last default is a dummy - it forces the parser to flush current
    for i in (args + [$generator.new_tag("default", [], [])]) {
        if ((type(i) == 'frob) && ((class(i) == $generator) && ((i.name()) in ["case", "default", "range"]))) {
            if (tag != 0) {
                if (type(tag) == 'list)
                    r += [[@tag.subrange(2), current]];
                else
                    d = d.add(tag, current);
            }
            current = [];
            switch (i.name()) {
                case "case":
                    if ((((i.args()).length()) != 1) || (type((tag = (i.args())[1])) != 'string))
                        throw(~parse, "[case:...] takes only a single string as an argument.");
                case "range":
                    if ((((i.args()).length()) != 1) || (!(| ((m = ((i.args())[1]).match_pattern("*..*")).length()) == 2 |)))
                        throw(~parse, "range tag should look like [range:lower..upper].");
                    tag = ['range, @m];
                case "default":
                    tag = 'default;
            }
        } else {
            if (tag == 0)
                throw(~parse, "Expression before [case]");
            current += [i];
        }
    }
    if (r)
        d = d.add('ranges, r);
    return [$format.new_tag("switch", flags, d), vars];
};

public method .do_obj() {
    arg vars, flags, args;
    
    if (!dict_contains(flags, "context"))
        throw(~parse, "no context flag for {obj}");
    if (!dict_contains(flags, "object"))
        throw(~parse, "no object flag for {obj}");
    if (listlen(args) == 0)
        throw(~parse, "{obj} requires an arg of the name");
    flags = flags.replace("context", tosym(flags["context"]));
    return [$format.new_tag("obj", flags, args), vars];
};

public method .do_method() {
    arg vars, flags, args;
    var m;
    
    if (!(m = (| ((flags.to_list())[1])[1] |)))
        throw(~parse, "{method} syntax: {method OBJ.METHOD:text}");
    if ((m[1]) != "$")
        m = "$" + m;
    m = (> $parse_lib.ref(m) <);
    if ((m[1]) != 'method)
        throw(~parse, "{method} target is not a method reference");
    m = (substr(tostr(m[2]), 2) + ".") + (m[4]);
    return [$format.new_tag("method", [m], args), vars];
};

public method .gen_data() {
    arg vars, flags, args;
    
    if (!(flags.contains("source")))
        throw(~parse, "no source flag for [data]");
    return [$generator.new_tag("data", flags, args), vars];
};

public method .gen_random() {
    arg vars, flags, args;
    
    if (!(flags.contains("high")))
        throw(~parse, "no high flag for [random]");
    return [$generator.new_tag("random", flags, args), vars];
};

public method .do_web() {
    arg vars, flags, args;
    
    if (!(flags.contains("src")))
        throw(~parse, "no 'src' flag for {web}");
    if (!args)
        throw(~parse, "no arguments for {web} to define name");
    return [$format.new_tag("web", flags, args), vars];
};


new object $evaluator: $utilities;

var $root manager = $evaluator;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837583637;
var $root inited = 1;
var $root managed = [$evaluator];

public method .eval_formatter() {
    arg form, vars;
    var flags, text, key;
    
    form = form.eval_flags(vars);
    catch ~methodnf {
        return .(form[4])(vars, form[2], form[3]);
    } with {
        [text, vars] = ._eval_ctext(form[3], vars);
        form = (<$format, [form[1], form[2], text, form[4]]>);
        return [[form], vars];
    }
};

public method ._eval_ctext() {
    arg data, vars;
    var out, uflags, token;
    
    out = [];
    if (type(data) != 'list)
        data = [data];
    for token in (data) {
        if (type(token) == 'frob) {
            switch (class(token)) {
                case $generator:
                    [token, vars] = .eval_generator(token, vars);
                    out += token;
                case $format:
                    [token, vars] = .eval_formatter(token, vars);
                    out += token;
                default:
                    out += [token];
            }
        } else {
            out += [token];
        }
    }
    return [out, vars];
};

public method .eval_generator() {
    arg gen, vars;
    var flags, key, value, name;
    
    gen = gen.eval_flags(vars);
    catch ~methodnf {
        return .(gen[4])(vars, gen[2], gen[3]);
    } with {
        catch ~keynf
            return [[vars[gen[1]]], vars];
        with
            return [[(">>ERROR: Unknown generator [" + (gen[1])) + "].<<"], vars];
    }
};

public method .init() {
    return #[];
};


new object $bs_eval: $evaluator;

var $root manager = $bs_eval;
var $root flags = ['variables, 'methods, 'code, 'core, 'fertile];
var $root created_on = 837583704;
var $root inited = 1;
var $root managed = [$bs_eval];

public method .gen_servername() {
    arg vars, flags, args;
    
    return [[$motd.server_name()], vars];
};

public method .gen_set() {
    arg vars, flags, args;
    
    return [[""], vars.add(((._eval_ctext(flags.getkey("var"), vars))[1])[1], ((._eval_ctext(args[1], vars))[1])[1])];
};

public method .gen_name() {
    arg vars, flags, args;
    var out, name, sep, type;
    
    [args, vars] = ._eval_ctext(args, vars);
    out = [];
    type = (| tosym(flags.getkey("type")) |) || 'name;
    if (!args)
        return [[(vars['this]).namef(type)], vars];
    sep = (| flags.getkey("separator") |) || " ";
    for name in (args) {
        switch (type(name)) {
            case 'objnum:
                name = name.namef(type);
            case 'string:
                catch ~objnf
                    name = ((vars['this]).match_environment(name)).namef(type);
                with
                    name = name;
        }
        out += [name];
    }
    return [._separate_list(sep, out), vars];
};

public method ._separate_list() {
    arg sep, l;
    
    if (sep == "none")
        return l;
    if (sep == "english")
        return [l.to_english()];
    return [l.join(sep)];
};

public method .gen_english() {
    arg vars, flags, args;
    var sep, empty, and, text, item;
    
    sep = (| flags.getkey("separator") |) || ", ";
    empty = (| flags.getkey("empty") |) || "nothing";
    and = (| flags.getkey("and") |) || " and ";
    [text, vars] = ._eval_ctext(args, vars);
    if (((vars['time]) == 'pre) || find item in (text) where (type(item) == 'frob)) {
        return [[(<$generator, ["english", flags, text, 'gen_english]>)], vars];
    } else {
        if (type(sep) == 'list)
            sep = sep[1];
        if (type(and) == 'list)
            and = and[1];
        return [[text.to_english(empty, and, sep)], vars];
    }
};

public method .gen_def() {
    arg vars, flags, args;
    var name, val;
    
    name = flags.getkey("var");
    val = args[1];
    return [[""], vars.add(name, val)];
};

public method .gen_foreach() {
    arg vars, flags, args;
    var v, list, body, out, item, sep, text;
    
    v = (| flags.getkey("var") |) || "iterator";
    list = flags.getkey("list");
    sep = (| flags.getkey("separator") |) || " ";
    out = [];
    for item in (list) {
        vars = vars.add(v, item);
        [text, vars] = ._eval_ctext(args, vars);
        if ((vars['time]) == 'post)
            out = out.affix(text);
        else
            out += [text];
    }
    if ((vars['time]) == 'pre)
        out = ._separate_list(sep, out);
    return [out, vars];
};

public method .gen_time() {
    arg vars, flags, args;
    var a, word;
    
    [args, vars] = ._eval_ctext(args, vars);
    if (!args)
        return [[tostr(time())], vars];
    return [[$time.format(args[1])], vars];
};

public method .gen_vars() {
    arg vars, flags, args;
    var out, v, sep;
    
    out = [];
    sep = (| flags.getkey("separator") |) || " ";
    for v in (vars.keys()) {
        if (type(v) == 'string)
            out += [v];
    }
    return [._separate_list(sep, out), vars];
};

public method .gen_pro() {
    arg vars, flags, args;
    var out, type, obj, key, objstr;
    
    if ((| (objstr = flags.getkey("obj")) |)) {
        while (type(objstr) == 'list)
            objstr = objstr[1];
        if (type(objstr) == 'string) {
            catch ~objnf, ~namenf
                obj = (vars['this]).match_environment(objstr);
            with
                return [[(">>ERROR: Invalid object '" + objstr) + "'.<<"], vars];
        } else {
            obj = objstr;
        }
    } else {
        obj = vars['this];
    }
    out = [];
    if ((args.length()) == 0)
        return [[">>ERROR: Must specify pronoun type.<<"], vars];
    type = (args[1]).to_symbol();
    catch ~keynf
        out = (> [(obj.gender()).pronoun(type)] <);
    with
        return [[(">>ERROR: Invalid pronoun type '" + (args[1])) + "'.<<"], vars];
    return [out, vars];
};

public method .gen_join() {
    arg vars, flags, args;
    var v, sep, item;
    
    sep = (| flags.getkey("separator") |) || " ";
    [args, vars] = ._eval_ctext(args, vars);
    if (((vars['time]) == 'pre) || find item in (args) where (type(item) == 'frob)) {
        return [[(<$generator, ["join", flags, args, 'gen_join]>)], vars];
    } else {
        if (type(sep) == 'list)
            sep = sep[1];
        return [._separate_list(sep, args), vars];
    }
};

public method .gen_servname() {
    arg vars, flags, args;
    
    return [[$motd.server_name()], vars];
};

public method .gen_switch() {
    arg vars, flags, args;
    var v, i, num, n, done;
    
    v = flags.getkey("value");
    if (type(v) == 'list)
        v = v.join("");
    if (args.contains(v))
        return ._eval_ctext(args[v], vars);
    if (args.contains('ranges)) {
        if ((num = v.is_numeric()))
            n = toint(v);
        done = 0;
        for i in (args['ranges]) {
            if ((| num && (((i[1]).is_numeric()) && ((i[2]).is_numeric())) |)) {
                if ((n >= toint(i[1])) && (n <= toint(i[2])))
                    done = 1;
            } else if ((| (v >= (i[1])) && (v <= (i[2])) |)) {
                done = 1;
            }
            if (done)
                return ._eval_ctext(i[3], vars);
        }
    }
    if (args.contains('default))
        return ._eval_ctext(args['default], vars);
    return [((vars['time]) == 'pre) ? [""] : "", vars];
};

public method .eval_formatter() {
    arg form, vars;
    var text;
    
    if ((vars['time]) == 'post) {
        [text, vars] = (vars['formatter]).eval_formatter(form, vars);
        return [[text], vars];
    }
    return pass(form, vars);
};

public method .gen_data() {
    arg vars, flags, args;
    var method, data;
    
    [args, vars] = ._eval_ctext(args, vars);
    method = (| flags.getkey("source") |);
    catch ~methodnf
        data = (vars['this]).(tosym("gen_" + method))();
    with
        return [[">>>invalid data source<<<"], vars];
    return [[data], vars];
};

public method .gen_fromliteral() {
    arg vars, flags, args;
    
    return [[(| fromliteral(((._eval_ctext(args[1], vars))[1])[1]) |)], vars];
};

public method .old_gen_set() {
    arg vars, flags, args;
    var text, name;
    
    name = flags.getkey("var");
    [text, vars] = ._eval_ctext(args[1], vars);
    return [[""], vars.add(name, text[1])];
};

public method .gen_random() {
    arg vars, flags, args;
    var range, low, high;
    
    // No need to ._eval_ctext() since there are no args.
    low = toint((| flags.getkey("low") |) || 1);
    high = toint(flags.getkey("high"));
    return [[random(high - low) + low], vars];
};

public method .gen_serverhost() {
    arg vars, flags, args;
    
    return [[$sys.server_info('server_hostname)], vars];
};


new object $place_desc_evaluator: $bs_eval;

var $root manager = $place_desc_evaluator;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 845665471;
var $root inited = 1;
var $root managed = [$place_desc_evaluator];


new object $realm_base_eval: $bs_eval;

var $root manager = $realm_base_eval;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847528368;
var $root inited = 1;
var $root managed = [$realm_base_eval];

public method .gen_hour() {
    arg vars, flags, args;
    var v, i, len, n;
    
    v = vars['daytime];
    return [[tostr(v[1])], vars];
};

public method .gen_light() {
    arg vars, flags, args;
    var v, i, len, n;
    
    v = vars['daytime];
    return [[tostr(v[2])], vars];
};

public method .gen_daynight() {
    arg vars, flags, args;
    var v, i, len, n;
    
    v = vars['daytime];
    return [[tostr(v[3])], vars];
};


new object $formatter: $evaluator;

var $root manager = $formatter;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837583776;
var $root inited = 1;
var $root managed = [$formatter];

public method .eval_generator() {
    arg gen, vars;
    
    return (vars['evaluator]).eval_generator(gen, vars);
};

public method ._eval_ctext() {
    arg data, vars;
    var out, uflags, token;
    
    out = "";
    if (type(data) != 'list)
        data = [data];
    for token in (data) {
        refresh();
        switch (type(token)) {
            case 'frob:
                switch (class(token)) {
                    case $generator:
                        [token, vars] = ((| vars['evaluator] |) || $bs_eval).eval_generator(token, vars);
                        if (type(token) == 'string) {
                            out += token;
                        } else {
                            [token, vars] = ._eval_ctext(token, vars);
                            out += token;
                        }
                    case $format:
                        [token, vars] = .eval_formatter(token, vars);
                        out += token;
                }
            case 'string:
                out += token;
            case 'list:
                [token, vars] = ._eval_ctext(token, vars);
                out += token;
            default:
                out += token;
        }
    }
    return [out, vars];
};

public method .eval_formatter() {
    arg form, vars;
    var flags, i, text;
    
    form = form.eval_flags(vars);
    catch ~methodnf {
        return .(form[4])(vars, form[2], form[3]);
    } with {
        [text, vars] = ._eval_ctext(form[3], vars);
        if ((vars['time]) == 'post)
            return [text, vars];
        form = (<$format, [form[1], form[2], text, form[4]]>);
        return [[form], vars];
    }
};

public method .do_switch() {
    arg vars, flags, args;
    var v, i, num, n, done;
    
    v = flags.getkey("value");
    if (type(v) == 'list)
        v = v.join("");
    if (type(args) == 'list)
        args = args[1];
    if (args.contains(v))
        return ._eval_ctext(args[v], vars);
    if (args.contains('ranges)) {
        if ((num = v.is_numeric()))
            n = toint(v);
        done = 0;
        for i in (args['ranges]) {
            if ((| num && (((i[1]).is_numeric()) && ((i[2]).is_numeric())) |)) {
                if ((n >= toint(i[1])) && (n <= toint(i[2])))
                    done = 1;
            } else if ((| (v >= (i[1])) && (v <= (i[2])) |)) {
                done = 1;
            }
            if (done)
                return ._eval_ctext(i[3], vars);
        }
    }
    if (args.contains('default))
        return ._eval_ctext(args['default], vars);
    return [((vars['time]) == 'pre) ? [""] : "", vars];
};

public method .do_sense() {
    arg vars, flags, args;
    
    return [(| tostr(vars[tosym(args[1])]) |) || "", vars];
};

public method .do_invoke() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [args, vars];
};

public method .do_obj() {
    arg vars, flags, args;
    
    return [flags.getkey("name"), vars];
};


new object $plain_format: $formatter;

var $root manager = $plain_format;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837583858;
var $root inited = 1;
var $root managed = [$plain_format];

public method .init() {
    return #[['header, ""], ['width, 78]];
};

public method .do_th() {
    arg vars, flags, args;
    var tblinfo, rinfo, col, cols, rows, w, n, max;
    
    rows = (| toint(flags.getkey("rowspan")) |) || 1;
    cols = (| toint(flags.getkey("colspan")) |) || 1;
    rinfo = vars['rinfo];
    tblinfo = vars['table_info];
    col = (tblinfo[2]) + 1;
    n = [];
    max = listlen(tblinfo[1]);
    while (rinfo[col]) {
        col++;
        n += [[0, (tblinfo[1])[col], []]];
    }
    w = ((tblinfo[1]).subrange(col, cols)).sum();
    tblinfo = tblinfo.replace(2, (col + cols) - 1);
    vars = (vars.add('table_info, tblinfo)).add('header, "");
    [args, vars] = .eval_indented(args, vars, 0, w);
    return [(n + [[rows, w, args.explode("\n", 1)]]) + ($list.make(cols - 1, [rows, 0, []])), vars];
};

public method .do_dl() {
    arg vars, flags, args;
    var out, token, c, cm, ind, mem;
    
    c = (| vars['columned] |) || 0;
    cm = (| flags.getkey("columned") |) || 0;
    ind = (| toint(flags.getkey("ind")) |) || 4;
    vars = vars.add('columned, cm);
    if (dict_contains(vars, 'dl_ind))
        mem = vars['dl_ind];
    vars = dict_add(vars, 'dl_ind, ind);
    [args, vars] = ._eval_ctext(args, vars);
    if (mem)
        vars = dict_add(vars, 'dl_ind, mem);
    else
        vars = dict_del(vars, 'dl_ind);
    if (c)
        vars = vars.add('columned, c);
    else if (vars.contains('columned))
        vars = vars.del('columned);
    return [args + "\n", vars];
};

public method .do_anchor() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args[1], vars);
    return [("/" + args) + "/", vars];
};

public method .do_p() {
    arg vars, flags, args;
    
    return ["\n", vars];
};

public method .do_em() {
    arg vars, flags, args;
    var out, a;
    
    return ._eval_ctext(args, vars);
};

public method .do_br() {
    arg vars, flags, args;
    
    return ["\n", vars];
};

public method .do_link() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args[1], vars);
    return [("[" + args) + "]", vars];
};

public method .do_web() {
    arg vars, flags, args;
    var href, src, listen;
    
    [args, vars] = ._eval_ctext(args, vars);
    src = flags.getkey("src");
    if ((!match_begin(src, "http")) && (!match_begin(src, "ftp"))) {
        href = "http://" + ($sys.server_info('server_hostname));
        listen = ($http_daemon.get_setting("listen", $daemon)).slice(1);
        if (!listidx(listen, 80))
            href += ":" + (listen[1]);
        src = href + src;
    }
    return [((args + " <") + src) + ">", vars];
};

public method .do_hr() {
    arg vars, flags, args;
    
    if ((| flags.getkey("sep") |))
        return ["---\n", vars];
    return [pad("\n", vars['width], "-") + "\n", vars];
};

public method .do_tt() {
    arg vars, flags, args;
    var out, a;
    
    return ._eval_ctext(args, vars);
};

public method .do_subj() {
    arg vars, flags, args;
    var out, word, l, len;
    
    [out, vars] = ._eval_ctext(args, vars);
    len = vars['width];
    switch (toint((| flags.getkey("level") |) || "4")) {
        case 1:
            out = ((("\n\n" + out) + "\n") + ("".pad(strlen(out), "="))) + "\n";
        case 2:
            out = ((("\n\n" + out) + "\n") + ("".pad(strlen(out), "-"))) + "\n";
        case 3:
            out = ("\n\n" + out) + "\n";
        default:
            out = ("\n" + out) + "\n";
    }
    return [out, vars];
};

public method .do_dd() {
    arg vars, flags, args;
    
    return .eval_indented(args, vars, (| vars['dl_ind] |) || 4);
};

public method .do_b() {
    arg vars, flags, args;
    var out, a;
    
    return ._eval_ctext(args, vars);
};

public method .do_i() {
    arg vars, flags, args;
    var out, a;
    
    return ._eval_ctext(args, vars);
};

public method .do_dt() {
    arg vars, flags, args;
    
    vars = vars.add('header, "");
    [args, vars] = ._eval_ctext(args, vars);
    if ((| vars['columned] |))
        return ["\n  ", vars.add('header, pad("  " + args, 25))];
    else
        return [("\n  " + args) + "\n", vars.add('header, "")];
};

public method .do_quote() {
    arg vars, flags, args;
    
    return [args[1], vars];
};

public method .do_table() {
    arg vars, flags, args;
    var tblinfo, i, ntbinfo, info, width, l, lr, lc, inds, ind, cwidth;
    
    tblinfo = (| vars['table_info] |) || 0;
    width = vars['width];
    if (!(| (ntbinfo = flags.getkey("cols")) |))
        throw(~flags, "Need column information.");
    ind = (| abs(toint(flags.getkey("ind"))) |) || 0;
    info = [];
    cwidth = width - ind;
    if ("%" in ntbinfo) {
        for i in (ntbinfo.explode(","))
            info += [toint(cwidth * (toint(i) / 100.0))];
    } else {
        for i in (ntbinfo.explode(","))
            info += [toint(i)];
    }
    vars = dict_union(vars, #[['table_info, [info, 0]], ['rinfo, $list.make(info.length(), 0)], ['rcont, $list.make(info.length(), [])]]);
    [args, vars] = ._eval_ctext(args, vars);
    vars = tblinfo ? (vars.add('table_info, tblinfo)) : (vars.del('table_info));
    vars = vars.add('width, width);
    return ["\n" + args, vars];
};

public method .do_tr() {
    arg vars, flags, args;
    var tblinfo, rinfo, i, l, len, s, j, col, rcont, done;
    
    tblinfo = vars['table_info];
    tblinfo = tblinfo.replace(2, 0);
    rinfo = vars['rinfo];
    rcont = vars['rcont];
    vars = vars.add('table_info, tblinfo);
    l = [];
    col = 1;
    for i in (args) {
        if (type(i) != 'frob)
            throw(~table, "Only {td} tags permitted in rows");
        switch (i.method()) {
            case 'do_td:
                [i, vars] = .do_td(vars, i.ctext_flags(), i.args());
            case 'do_th:
                [i, vars] = .do_th(vars, i.ctext_flags(), i.args());
            default:
                throw(~table, "Only {td} tags permitted in rows");
        }
        l += i;
        for j in (i) {
            rcont = rcont.replace(col, (rcont[col]) + (j[3]));
            col++;
        }
    }
    l += $list.make((rcont.length()) - (l.length()), [0, 0, []]);
    s = "";
    i = 1;
    done = 0;
    rinfo = map j in [1 .. rinfo.length()] to (((rinfo[j]) - 1) + ((l[j])[1]));
    while (!done) {
        done = 1;
        for j in [1 .. rcont.length()] {
            s += ((| (rcont[j])[i] |) || "").pad((l[j])[2]);
            done = done && ((rinfo[j]) || (i >= listlen(rcont[j])));
        }
        i++;
        s = s.trim('right);
        s += "\n";
    }
    for j in [1 .. rinfo.length()]
        rcont = rcont.replace(j, (| (rcont[j]).subrange(i) |) || []);
    vars = (vars.add('rinfo, rinfo)).add('rcont, rcont);
    return [s, vars];
};

public method .do_td() {
    arg vars, flags, args;
    var tblinfo, rinfo, col, cols, rows, w, n, max;
    
    rows = (| toint(flags.getkey("rowspan")) |) || 1;
    cols = (| toint(flags.getkey("colspan")) |) || 1;
    rinfo = vars['rinfo];
    tblinfo = vars['table_info];
    col = (tblinfo[2]) + 1;
    n = [];
    max = listlen(tblinfo[1]);
    while (rinfo[col]) {
        col++;
        n += [[0, (tblinfo[1])[col], []]];
    }
    w = ((tblinfo[1]).subrange(col, cols)).sum();
    tblinfo = tblinfo.replace(2, (col + cols) - 1);
    vars = (vars.add('table_info, tblinfo)).add('header, "");
    [args, vars] = .eval_indented(args, vars, 0, w);
    return [(n + [[rows, w, args.explode("\n", 1)]]) + ($list.make(cols - 1, [rows, 0, []])), vars];
};

public method .rewrap_lines() {
    arg vars, str, prefix;
    var s, p, n, firstline;
    
    s = [];
    n = (vars['width]) + (prefix.length());
    for str in (str.explode("\n", 1))
        s += str.wrap_lines(n, prefix, 1);
    return s.join("\n");
};

public method .eval_indented() {
    arg args, vars, i, @w;
    var width, indent;
    
    width = vars['width];
    vars = vars.add('width, (| w[1] |) || (width - i));
    [args, vars] = ._eval_ctext(args, vars);
    return [.rewrap_lines(vars, (vars['header]) + args, pad("", i)), vars.add('width, width)];
};

public method .do_dfn() {
    arg vars, flags, args;
    var ind, nobound;
    
    ind = toint((| flags.getkey("ind") |) || 8);
    nobound = (| flags.getkey("nobound") |);
    vars = vars.add('header, "");
    [args, vars] = .eval_indented(args, vars, ind);
    if (nobound)
        return ["\n" + args, vars];
    return [("\n" + args) + "\n", vars];
};

public method .do_detail() {
    arg vars, flags, args;
    
    return [("[" + (flags.getkey("name"))) + "]", vars];
};

public method .do_img() {
    arg vars, flags, args;
    var alt;
    
    alt = (| flags.getkey("plain") |) || "";
    return [alt, vars];
};

public method .format() {
    arg data, vars;
    var str, len, line, out;
    
    str = (> (._eval_ctext(data, vars))[1] <);
    if ((strlen(str) < 2) || (substr(str, strlen(str) - 1) != "\n"))
        str += "\n";
    return str_to_buf(str);
};

public method .do_np() {
    arg vars, flags, args;
    
    return ["\n\n", vars];
};

public method .do_lh() {
    arg vars, flags, args;
    var line, oheader;
    
    oheader = (| vars['header] |);
    vars = dict_add(vars, 'header, "");
    [args, vars] = .eval_indented(args, vars, 2);
    if (oheader == ~keynf)
        vars = dict_del(vars, 'header);
    else
        vars = dict_add(vars, 'header, oheader);
    return [args + "\n", vars];
};

public method .do_li() {
    arg vars, flags, args;
    var line, type, num, depth, oheader;
    
    type = (| vars['list_type] |) || 'plain;
    depth = (| vars['list_depth] |) || 1;
    oheader = (| vars['header] |);
    if (type == 'plain) {
        if (depth % 2)
            vars = dict_add(vars, 'header, "* ");
        else
            vars = dict_add(vars, 'header, "+ ");
    } else {
        num = (vars['list_last]) + 1;
        vars = dict_add(vars, 'header, num + ") ");
        vars = dict_add(vars, 'list_last, num);
    }
    depth *= 2;
    [args, vars] = .eval_indented(args, vars, depth);
    if (oheader == ~keynf)
        vars = dict_del(vars, 'header);
    else
        vars = dict_add(vars, 'header, oheader);
    return ["\n" + args, vars];
};

public method .do_ul() {
    arg vars, flags, args;
    var out, token, old, last, depth;
    
    if (dict_contains(vars, 'list_type)) {
        old = vars['list_type];
        if (old == 'ordinal)
            last = vars['list_last];
        else
            last = -1;
        vars = dict_add(vars, 'list_depth, (vars['list_depth]) + 1);
    } else {
        vars = dict_add(vars, 'list_depth, 1);
    }
    vars = dict_add(vars, 'list_type, 'plain);
    [args, vars] = ._eval_ctext(args, vars);
    if (old) {
        vars = dict_add(vars, 'list_type, old);
        if ((old == 'ordinal) && (last != (-1)))
            vars = dict_add(vars, 'list_last, last);
        vars = dict_add(vars, 'list_depth, (vars['list_depth]) - 1);
    } else {
        vars = dict_del(vars, 'list_type);
        vars = dict_del(vars, 'list_depth);
    }
    return [args, vars];
};

public method .do_ol() {
    arg vars, flags, args;
    var out, token, old, last, depth;
    
    if (dict_contains(vars, 'list_type)) {
        old = vars['list_type];
        if (old == 'ordinal)
            last = vars['list_last];
        else
            last = -1;
        vars = dict_add(vars, 'list_depth, (vars['list_depth]) + 1);
    } else {
        vars = dict_add(vars, 'list_depth, 1);
    }
    vars = dict_add(vars, 'list_type, 'ordinal);
    vars = dict_add(vars, 'list_last, 0);
    [args, vars] = ._eval_ctext(args, vars);
    if (old) {
        vars = dict_add(vars, 'list_type, old);
        if ((old == 'ordinal) && (last != (-1)))
            vars = dict_add(vars, 'list_last, last);
        vars = dict_add(vars, 'list_depth, (vars['list_depth]) - 1);
    } else {
        vars = dict_del(vars, 'list_type);
        if (dict_contains(vars, 'list_last))
            vars = dict_del(vars, 'list_last);
        vars = dict_del(vars, 'list_depth);
    }
    return [args, vars];
};

public method .do_columnize() {
    arg vars, flags, args;
    var cols;
    
    cols = (| flags.getkey("cols") |) || "*";
    [args, vars] = ._eval_ctext(args, vars);
    return [[(cols == "*") ? (args.lcolumnize()) : (args.columnize(toint(cols)))], vars];
};


new object $wrapped_format: $plain_format;

var $root manager = $wrapped_format;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848777209;
var $root inited = 1;
var $root managed = [$wrapped_format];

public method .format() {
    arg data, vars;
    var str, len, line, out;
    
    str = (> (._eval_ctext(data, vars))[1] <);
    if ((strlen(str) < 2) || (substr(str, strlen(str) - 1) != "\n"))
        str += "\n";
    
    // ugly and inneficient--use a client people
    len = (vars['receiver]).linelen();
    out = "";
    for line in (explode(str, "\n"))
        out += (line.wrap_line(len, " ")) + "\n";
    return str_to_buf(out);
};


new object $flat_format: $wrapped_format;

var $root manager = $flat_format;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858615622;
var $root inited = 1;
var $root managed = [$flat_format];

public method .do_link() {
    arg vars, flags, args;
    
    return ._eval_ctext(args[1], vars);
};

public method .format() {
    arg data, vars;
    var str, len, line, out;
    
    str = (> (._eval_ctext(data, vars))[1] <);
    if ((strlen(str) < 2) || (substr(str, strlen(str) - 1) != "\n"))
        str += "\n";
    
    // ugly and inneficient--use a client people
    len = (vars['receiver]).linelen();
    out = "";
    for line in (explode(str, "\n", 1))
        out += (line.wrap_line(len, "")) + "\n";
    return str_to_buf(out);
};

public method .do_th() {
    arg vars, flags, args;
    var tblinfo, rinfo, col, cols, rows, w, n, max;
    
    rows = (| toint(flags.getkey("rowspan")) |) || 1;
    cols = (| toint(flags.getkey("colspan")) |) || 1;
    rinfo = vars['rinfo];
    tblinfo = vars['table_info];
    col = (tblinfo[2]) + 1;
    n = [];
    max = listlen(tblinfo[1]);
    while (rinfo[col]) {
        col++;
        n += [[0, (tblinfo[1])[col], []]];
    }
    w = ((tblinfo[1]).subrange(col, cols)).sum();
    tblinfo = tblinfo.replace(2, (col + cols) - 1);
    vars = (vars.add('table_info, tblinfo)).add('header, "");
    [args, vars] = .eval_indented(args, vars, 0, w);
    return [(n + [[rows, w, args.explode("\n", 1)]]) + ($list.make(cols - 1, [rows, 0, []])), vars];
};


new object $tagged_format: $plain_format;

var $root manager = $tagged_format;
var $root managed = [$tagged_format];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 888336074;
var $dmi_data descriptions = #[];
var $root inited = 1;

public method .do_dt() {
    arg vars, flags, args;
    
    vars = vars.add('header, "");
    [args, vars] = ._eval_ctext(args, vars);
    if ((| vars['columned] |))
        return ["\n  ", vars.add('header, pad("  " + args, 25 + ((args.length()) - ((.tag_text(args)).length()))))];
    else
        return [("\n  " + args) + "\n", vars.add('header, "")];
};

public method .tag_text() {
    arg text;
    
    throw(~override, "Override me!!!");
};


new object $tkmoo_format: $tagged_format;

var $root manager = $tkmoo_format;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 888299262;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $root managed = [$tkmoo_format];

public method .do_method() {
    arg vars, flags, args;
    var out, vars, m;
    
    m = (flags[1])[1];
    [out, vars] = ._eval_ctext(args, vars);
    return [((("{link {command \"@list $" + m) + "\"} {text \"") + out) + "\"}}", vars];
};

public method .do_link() {
    arg vars, flags, args;
    var node;
    
    [args, vars] = ._eval_ctext([args[1]], vars);
    node = (| flags.getkey("node") |);
    if (node)
        return [.build_link_tag("@help " + node, args), vars];
    return [">>ERROR: Invalid help node<<", vars];
};

public method .tag_text() {
    arg tag;
    var match;
    
    match = tag.match_pattern("* \{text \"*\"\}*");
    if (match)
        return match[2];
    return tag;
    
    // this used to throw:
    // throw(~invtag, "Tag had no text field.");
};

public method .build_link_tag() {
    arg command, text;
    
    command = (((toliteral(command).replace("\\", "\\\\")).replace("{", "\{")).replace("}", "\}")).replace("\\", "\\\\");
    text = (((toliteral(text).replace("\\", "\\\\")).replace("{", "\{")).replace("}", "\}")).replace("\\", "\\\\");
    return ((("{link {command " + command) + "} {text ") + text) + "}}";
};

public method ._eval_ctext() {
    arg data, vars, @unexpand;
    var out, uflags, token;
    
    out = "";
    if (type(data) != 'list)
        data = [data];
    for token in (data) {
        refresh();
        switch (type(token)) {
            case 'frob:
                switch (class(token)) {
                    case $generator:
                        [token, vars] = ((| vars['evaluator] |) || $bs_eval).eval_generator(token, vars);
                        if (type(token) == 'string) {
                            out += token;
                        } else {
                            [token, vars] = ._eval_ctext(token, vars, 1);
                            out += token;
                        }
                    case $format:
                        [token, vars] = .eval_formatter(token, vars);
                        out += token;
                }
            case 'string:
                out += unexpand ? token : (.escape(token));
            case 'list:
                [token, vars] = ._eval_ctext(token, vars, @unexpand);
                out += token;
            default:
                out += token;
        }
    }
    return [out, vars];
};

public method .do_detail() {
    arg vars, flags, args;
    var det;
    
    det = flags.getkey("name");
    return [.build_link_tag("look at " + det, det), vars];
};

public method .do_obj() {
    arg vars, flags, args;
    var gateway, argname, output, context, object, name, options, command, text;
    
    name = flags.getkey("name");
    [name, vars] = ._eval_ctext([name], vars);
    context = flags.getkey("context");
    options = (| flags.getkey("options") |);
    object = args[1];
    if (type(context) == 'string)
        context = tosym(context);
    if (options && (type(options) == 'string))
        options = tosym(options);
    switch (context) {
        case 'look:
            if (options) {
                switch (options) {
                    case 'exit:
                        command = object.name('noarticle);
                        text = name;
                    case 'contained:
                        command = (("look " + ((object.location()).name('noarticle))) + "'s ") + (object.name('noarticle));
                        text = name;
                }
            } else {
                command = "look " + (object.name('noarticle));
                text = name;
            }
        case 'display:
            command = "go " + (object.name());
            text = name;
            command = "@display " + object;
            text = name;
        case 'exit:
            command = "go " + (object.name());
            text = name;
    }
    return [.build_link_tag(command, text), vars];
};

public method .escape() {
    arg token;
    
    return (token.replace("{", "\{")).replace("}", "\}");
};


new object $ansi_format: $tagged_format;

var $root manager = $ansi_format;
var $ansi_format colors = #[["black", "30"], ["red", "31"], ["green", "32"], ["yellow", "33"], ["blue", "34"], ["magenta", "35"], ["cyan", "36"], ["white", "37"]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863402529;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $ansi_format bcolors = #[["black", "40"], ["red", "41"], ["green", "42"], ["yellow", "43"], ["blue", "44"], ["magenta", "45"], ["cyan", "46"], ["white", "47"]];
var $root managed = [$ansi_format];

public method .format() {
    arg data, vars;
    var str, len, line;
    
    str = (> (._eval_ctext(data, vars))[1] <);
    if ((strlen(str) < 2) || (substr(str, strlen(str) - 1) != "\n"))
        str += "\n";
    
    // ugly and inneficient--use a client people
    // out = str_to_buf(str);
    // out = out.bufsub(`[92, 65], `[27, 91]);
    return str_to_buf(str).bufsub(`[92, 65], `[27, 91]);
};

public method .do_font() {
    arg vars, flags, args;
    var color, bcolor, code, nested, current;
    
    // allow other .do_* methods to call this with a specific code
    if (dict_contains(vars, 'ansi_code)) {
        code = vars['ansi_code];
        vars = dict_del(vars, 'ansi_code);
    } else {
        color = (| flags.getkey("color") |);
        bcolor = (| flags.getkey("bcolor") |);
        code = (color ? (| ($cml_color.get_color(color))[2] |) : "") || "";
        code += (bcolor ? (code ? (| ";" + (($cml_color.get_color(bcolor))[3]) |) : (| ($cml_color.get_color(bcolor))[3] |)) : "") || "";
    }
    if (code) {
        code = ("\A" + code) + "m";
    
        // handle existing nesting
        if (dict_contains(vars, 'ansi_color)) {
            current = vars['ansi_color];
            nested++;
        }
        vars = dict_add(vars, 'ansi_color, code);
    }
    [args, vars] = ._eval_ctext(args, vars);
    if (code) {
        if (nested) {
            args = ((("\A0m" + code) + args) + "\A0m") + current;
            vars = dict_add(vars, 'ansi_color, current);
        } else {
            args = (code + args) + "\A0m";
            vars = dict_del(vars, 'ansi_color);
        }
    }
    return [args, vars];
};

public method .do_detail() {
    arg vars, flags, args;
    
    return [("\A1;4m" + (flags.getkey("name"))) + "\A0m", vars];
};

public method .do_link() {
    arg vars, flags, args;
    
    vars = dict_add(vars, 'ansi_code, "1;4");
    return .do_font(vars, flags, args);
};

public method .hold_wrap_lines() {
    arg str, len, @stuff;
    var prefix, firstline, split_str, ansi_parts, output, plen, hide_len, x, tlen, cutoff, tstr;
    
    // takes string and wraps it by words, compared to length, returns a list. 
    [(prefix ?= ""), (firstline ?= 0)] = stuff;
    split_str = .explode_ansi(str);
    str = "";
    x = 1;
    tlen = 1;
    ansi_parts = [];
    while (x < (split_str.length())) {
        str += split_str[x];
        ansi_parts = ansi_parts.add([tlen, split_str[x + 1]]);
        tlen += strlen(str);
        x += 2;
    }
    if (firstline)
        str = prefix + str;
    output = [];
    plen = strlen(prefix);
    while (strlen(str) > len) {
        cutoff = stridx(substr(str, 1, len), " ", -1);
        if (cutoff <= plen) {
            tstr = substr(str, 1, len);
            str = prefix + substr(str, len + 1);
        } else {
            tstr = substr(str, 1, cutoff - 1);
            str = prefix + substr(str, cutoff + 1);
        }
        output += tstr;
    }
    return output + [str];
};

public method .hold_rewrap_lines() {
    arg vars, str, prefix;
    var s, p, n, firstline;
    
    s = [];
    n = (vars['width]) + (prefix.length());
    for str in (str.explode("\n", 1))
        s += .wrap_lines(str, n, prefix, 1);
    return s.join("\n");
};

public method .explode_ansi() {
    arg line;
    var m, out;
    
    out = [];
    while (line) {
        if ((m = match_regexp(line, "\\\A[^a-z]+[a-z]"))) {
            m = m[1];
            out += [substr(line, 1, (m[1]) - 1), substr(line, m[1], m[2])];
            line = substr(line, (m[1]) + (m[2]));
        } else {
            out += [line];
            break;
        }
    }
    return out;
};

public method .weed_ansi() {
    arg str;
    var out;
    
    out = str.global_regexp("[\]A[0-9A-LN-Za-ln-z;]+m");
    return out;
    return str.global_regexp("\\\A[0-9A-Ln-z;a-ln-z;]+[a-z]");
};

public method .tag_text() {
    arg str;
    var mode, token;
    
    return map token in (.weed_ansi(str)) to ((mode = !mode) ? token : "").join("");
};

public method .ansi_wrap_line() {
    arg str, len, @stuff;
    var output, cutoff, firstline, prefix, plen, x, ansilist, lengthvals, counter, elem, wordlist, wordsum, flag;
    
    // Thanks Scott for letting me port this back from TEC.
    //   - Bruce
    // takes string and wraps it by words, compared to length, returns a list. 
    [(prefix ?= ""), (firstline ?= 0)] = stuff;
    output = "";
    if (firstline)
        str = prefix + str;
    plen = strlen(prefix);
    while (strlen(str) > len) {
        refresh();
        flag = "\n";
        counter = 0;
    
        // Check for ansi codes first
        ansilist = .weed_ansi(str);
    
        // If there are ansi codes, do the spiel, otherwise do a regular
        // line wrap (this can happen on a segment by segment basis)
        if (listlen(ansilist) > 1) {
            // create a word-only list w/o the ansi codes, and a letter-count
            // list both for the entire list and for the word-only list
            lengthvals = map x in (ansilist) to (strlen(x));
            wordlist = ansilist.odds();
            wordsum = map x in (wordlist) to (strlen(x)).sum();
    
            // wordsum = lengthvals.odds().sum();
            // if the letter-count for the word-only list is greater than the 
            // line length, then we'll need to hack it up, otherwise, we'll
            // just use the length of the entire line, codes and all
            if (wordsum > len) {
                // We've got too many letters. Have to find out where in
                // the word (non-ansi-code) part of the string the len is.
                // we mark its spot in the master list, but only count its
                // letter value if it's really a word. We also need to
                // remember how many letters we've gone through before
                // possibly hitting a big chunk of string (counter).
                elem = find x in (ansilist) where ((x in wordlist) && ((counter += strlen(x)) > len));
                if (elem)
                    counter -= strlen(x);
    
                // Going to establish where to cut the string. Take the
                // sum of the letter-count list up to the marker we just found
                cutoff = (lengthvals.subrange(1, elem - 1)).sum();
    
                // We already know the string is too long for a line, or we
                // wouldn't be here. If the counter is less than our line length
                // it probably means the next element was too long to add, 
                // (a big chunk of string with no codes) so we'll tack on the
                // len - our counter value.
                if (counter < len)
                    cutoff += len - counter;
                cutoff = stridx(substr(str, 1, cutoff), " ", -1);
            } else {
                cutoff = lengthvals.sum();
                flag = "";
            }
        } else {
            cutoff = stridx(substr(str, 1, len), " ", -1);
        }
    
        // The rest of this has been tweaked slightly. The main goal was to
        // get cutoff vals that this section of the code will be happy with.
        if (cutoff <= plen) {
            output += "\n" + substr(str, 1, len);
            str = prefix + substr(str, len + 1);
        } else {
            output += "\n" + substr(str, 1, cutoff);
            str = prefix + substr(str, cutoff + 1);
        }
    }
    
    // Here's the tweak and the pain in the ass I'd like solved. When the
    // length of the word value of the string matches the line length, the
    // extra "\n" a the end causes extra spacing for .atelln()
    return (output ? ((output.subrange(3)) + flag) : "") + str;
};

public method .rewrap_lines() {
    arg vars, str, prefix;
    var s, p, n, firstline;
    
    s = [];
    n = (vars['width]) + (prefix.length());
    for str in (str.explode("\n", 1))
        s += .ansi_wrap_lines(str, n, prefix, 1);
    return s.join("\n");
};

public method .ansi_wrap_lines() {
    arg str, len, @stuff;
    var output, cutoff, firstline, prefix, plen, x, ansilist, lengthvals, counter, elem, wordlist, wordsum, flag;
    
    // Thanks Scott for letting me port this back from TEC.
    //   - Bruce
    // takes string and wraps it by words, compared to length, returns a list. 
    [(prefix ?= ""), (firstline ?= 0)] = stuff;
    output = [];
    if (firstline)
        str = prefix + str;
    plen = strlen(prefix);
    while (strlen(str) > len) {
        refresh();
        flag = "\n";
        counter = 0;
    
        // Check for ansi codes first
        ansilist = .weed_ansi(str);
    
        // If there are ansi codes, do the spiel, otherwise do a regular
        // line wrap (this can happen on a segment by segment basis)
        if (listlen(ansilist) > 1) {
            // create a word-only list w/o the ansi codes, and a letter-count
            // list both for the entire list and for the word-only list
            lengthvals = map x in (ansilist) to (strlen(x));
            wordlist = ansilist.odds();
            wordsum = map x in (wordlist) to (strlen(x)).sum();
    
            // wordsum = lengthvals.odds().sum();
            // if the letter-count for the word-only list is greater than the 
            // line length, then we'll need to hack it up, otherwise, we'll
            // just use the length of the entire line, codes and all
            if (wordsum > len) {
                // We've got too many letters. Have to find out where in
                // the word (non-ansi-code) part of the string the len is.
                // we mark its spot in the master list, but only count its
                // letter value if it's really a word. We also need to
                // remember how many letters we've gone through before
                // possibly hitting a big chunk of string (counter).
                elem = find x in (ansilist) where ((x in wordlist) && ((counter += strlen(x)) > len));
                if (elem)
                    counter -= strlen(x);
    
                // Going to establish where to cut the string. Take the
                // sum of the letter-count list up to the marker we just found
                cutoff = (lengthvals.subrange(1, elem - 1)).sum();
    
                // We already know the string is too long for a line, or we
                // wouldn't be here. If the counter is less than our line length
                // it probably means the next element was too long to add, 
                // (a big chunk of string with no codes) so we'll tack on the
                // len - our counter value.
                if (counter < len)
                    cutoff += len - counter;
                cutoff = stridx(substr(str, 1, cutoff), " ", -1);
            } else {
                cutoff = lengthvals.sum();
                flag = "";
            }
        } else {
            cutoff = stridx(substr(str, 1, len), " ", -1);
        }
    
        // The rest of this has been tweaked slightly. The main goal was to
        // get cutoff vals that this section of the code will be happy with.
        if (cutoff <= plen) {
            output += [substr(str, 1, len)];
            str = prefix + substr(str, len + 1);
        } else {
            output += [substr(str, 1, cutoff)];
            str = prefix + substr(str, cutoff + 1);
        }
    }
    
    // Here's the tweak and the pain in the ass I'd like solved. When the
    // length of the word value of the string matches the line length, the
    // extra "\n" a the end causes extra spacing for .atelln()
    return output + [str];
};


new object $html_format: $formatter;

var $root manager = $html_format;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837902808;
var $root inited = 1;
var $root managed = [$html_format];

public method .do_hr() {
    arg vars, flags, args;
    
    return ["\n<hr size=1 noshade>\n", vars];
};

public method .do_ul() {
    arg vars, flags, args;
    var out, header, line, token;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [("\n<ul>\n" + args) + "\n</ul>\n", vars];
};

public method .do_th() {
    arg vars, flags, args;
    var f, n, c, width;
    
    c = vars['table_col];
    vars = vars.add('table_col, c + 1);
    width = (| (vars['table_cols])[c] |);
    f = "";
    if ((n = (| flags.getkey("rowspan") |)))
        f += " rowspan=" + n;
    if ((n = (| flags.getkey("colspan") |)))
        f += " colspan=" + n;
    if (width)
        f += (" width=\"" + width) + "\"";
    [args, vars] = ._eval_ctext(args, vars);
    return [((("\n<th align=left valign=top" + f) + ">") + args) + "</td>", vars];
};

public method .do_dl() {
    arg vars, flags, args;
    var out, token, c, cm;
    
    c = (| vars['columned] |);
    cm = (| flags.getkey("columned") |) || 0;
    vars = vars.add('columned, cm);
    [args, vars] = ._eval_ctext(args, vars);
    if (c)
        vars = vars.add('columned, c);
    else if (vars.contains('columned))
        vars = vars.del('columned);
    if (cm)
        return [("\n<blockquote><table cols=2 border=0>\n" + args) + "\n</table></blockquote>\n", vars];
    return [("\n<dl>\n" + args) + "\n</dl>\n", vars];
};

public method .do_anchor() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext([args[1]], vars);
    return [[("/" + (args[1])) + "/"], vars];
};

public method .do_p() {
    arg vars, flags, args;
    
    return ["\n<p>\n", vars];
};

public method .do_em() {
    arg vars, flags, args;
    var out, a;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [("<em>" + args) + "</em>", vars];
};

public method .do_br() {
    arg vars, flags, args;
    
    return ["\n<br>", vars];
};

public method .do_link() {
    arg vars, flags, args;
    var node;
    
    [args, vars] = ._eval_ctext([args[1]], vars);
    node = (| flags.getkey("node") |);
    if (node)
        return [((("<a href=\"/bin/help?node=" + node) + "\">") + args) + "</a>", vars];
    return ["&gt;&gt;ERROR: Invalid node&lt;&lt;", vars];
};

public method .do_web() {
    arg vars, flags, args;
    var src, href, listen;
    
    [args, vars] = ._eval_ctext(args, vars);
    src = flags.getkey("src");
    if ((!match_begin(src, "http")) && (!match_begin(src, "ftp"))) {
        href = "http://" + ($sys.server_info('server_hostname));
        listen = ($http_daemon.get_setting("listen", $daemon)).slice(1);
        if (!listidx(listen, 80))
            href += ":" + (listen[1]);
        src = href + src;
    }
    return [((("<a href=\"" + src) + "\">") + args) + "</a>", vars];
};

public method .do_tt() {
    arg vars, flags, args;
    var out, a;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [("<tt>" + args) + "</tt>", vars];
};

public method .do_subj() {
    arg vars, flags, args;
    var out, word, l;
    
    [args, vars] = ._eval_ctext(args, vars);
    l = (| flags.getkey("level") |) || "4";
    return [((((("<h" + l) + ">") + args) + "</h") + l) + ">\n", vars];
};

public method .do_dd() {
    arg vars, flags, args;
    var c;
    
    c = (| vars['columned] |);
    [args, vars] = ._eval_ctext(args, vars);
    if (c)
        return [("<td>" + args) + "</td></tr>", vars];
    return ["<dd>" + args, vars];
};

public method .do_b() {
    arg vars, flags, args;
    var out, a;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [("<b>" + args) + "</b>", vars];
};

public method .do_i() {
    arg vars, flags, args;
    var out, a;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [("<i>" + args) + "</i>", vars];
};

public method .do_dt() {
    arg vars, flags, args;
    var term, c;
    
    c = (| vars['columned] |);
    [args, vars] = ._eval_ctext(args, vars);
    if (c)
        return [("\n<tr><td>" + args) + "</td>", vars];
    return ["\n<dt>" + args, vars];
};

public method .do_li() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return ["\n<li>" + args, vars];
};

public method .do_lh() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return ["\n<lh>" + args, vars];
};

public method .do_tr() {
    arg vars, flags, args;
    
    vars = vars.add('table_col, 1);
    [args, vars] = ._eval_ctext(args, vars);
    return [("\n<tr>" + args) + "</tr>", vars];
};

public method .do_td() {
    arg vars, flags, args;
    var f, n, c, width, align;
    
    c = vars['table_col];
    vars = vars.add('table_col, c + 1);
    width = (| (vars['table_cols])[c] |);
    f = " " + join(flags.mmap('join, "="), " ");
    if (!(| flags.getkey("valign") |))
        f += " valign=top";
    if (width)
        f += (" width=\"" + width) + "\"";
    [args, vars] = ._eval_ctext(args, vars);
    return [((("\n<td " + f) + ">") + args) + "</td>", vars];
};

public method .do_table() {
    arg vars, flags, args;
    var cols, tcs, tc;
    
    tcs = (| vars['table_cols] |);
    tc = (| vars['table_col] |);
    if ((cols = (| flags.getkey("cols") |)) && ("%" in cols))
        vars = vars.add('table_cols, cols.explode(","));
    [args, vars] = ._eval_ctext(args, vars);
    vars = tcs ? (vars.add('table_cols, tcs)) : (vars.del('table_cols));
    vars = tc ? (vars.add('table_col, tc)) : (vars.del('table_col));
    return [("\n<table border=0>" + args) + "\n</table>\n", vars];
};

public method .do_dfn() {
    arg vars, flags, args;
    var out, a;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [("\n<blockquote>" + args) + "</blockquote>", vars];
};

public method .do_quote() {
    arg vars, flags, args;
    
    return [("<pre>" + ((((args[1]).replace("&", "&amp;")).replace("<", "&lt;")).replace(">", "&gt;"))) + "</pre>", vars];
};

public method .do_detail() {
    arg vars, flags, args;
    var det;
    
    det = flags.getkey("name");
    return [((((("<a href=\"/bin/describe?target=" + ((vars['this]).objname())) + "&detail=") + ($http.encode(det))) + "\">") + det) + "</a>", vars];
};

public method .do_invoke() {
    arg vars, flags, args;
    var object, method, eacharg;
    
    [args, vars] = ._eval_ctext(args, vars);
    object = flags.getkey("object");
    method = flags.getkey("method");
    return [((((("<a href=\"/" + (object.subrange(2))) + "/") + method) + "\">") + args) + "</a>", vars];
};

public method ._eval_ctext() {
    arg data, vars, @unexpand;
    var out, uflags, token;
    
    out = "";
    if (type(data) != 'list)
        data = [data];
    for token in (data) {
        refresh();
        switch (type(token)) {
            case 'frob:
                switch (class(token)) {
                    case $generator:
                        [token, vars] = ((| vars['evaluator] |) || $bs_eval).eval_generator(token, vars);
                        if (type(token) == 'string) {
                            out += token;
                        } else {
                            [token, vars] = ._eval_ctext(token, vars, 1);
                            out += token;
                        }
                    case $format:
                        [token, vars] = .eval_formatter(token, vars);
                        out += token;
                }
            case 'string:
                out += unexpand ? token : (token.to_html());
            case 'list:
                [token, vars] = ._eval_ctext(token, vars, @unexpand);
                out += token;
            default:
                out += token;
        }
    }
    return [out, vars];
};

public method .format() {
    arg data, vars;
    var str, len, line, out;
    
    str = (> (._eval_ctext(data, vars))[1] <) + "<br>";
    return str_to_buf(str + "\n");
    if ((strlen(str) < 2) || (substr(str, strlen(str) - 1) != "\n"))
        str += "\n";
    return str_to_buf(str + "<br>\n");
};

public method .do_ol() {
    arg vars, flags, args;
    var out, header, line, token;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [("\n<ol>\n" + args) + "\n</ol>\n", vars];
};

public method .do_np() {
    arg vars, flags, args;
    
    return ["\n<p>\n", vars];
};

public method .eval_formatter() {
    arg form, vars;
    var flags, i, text;
    
    form = form.eval_flags(vars);
    catch ~methodnf {
        return .(form[4])(vars, form[2], form[3]);
    } with {
        [text, vars] = ._eval_ctext(form[3], vars);
        if ((vars['time]) == 'post)
            return ["<%l%l>%l</%l>".format(form[1], map i in (form[2]) to ((((" " + (i[1])) + "=\"") + (i[2])) + "\"").join(""), text, form[1]), vars];
        form = (<$format, [form[1], form[2], text, form[4]]>);
        return [[form], vars];
    }
};

public method .do_columnize() {
    arg vars, flags, args;
    var cols, l, out, i;
    
    cols = (| flags.getkey("cols") |) || "*";
    [args, vars] = ._eval_ctext(args, vars);
    out = "\n<table border=0>\n";
    while (args) {
        if ((args.length()) > cols)
            [l, args] = [args.subrange(1, cols), args.subrange(cols + 1)];
        else
            [l, args] = [args, []];
        out += ("<tr><td>" + (l.join("</td><td>"))) + "</td></tr>\n";
    }
    out += "</table>\n";
    return [out, vars];
};

public method .do_method() {
    arg vars, flags, args;
    var out, vars, m;
    
    m = (flags[1])[1];
    [out, vars] = ._eval_ctext(args, vars);
    return [((("<a href=\"/bin/method?target=" + m) + "\"><tt>") + out) + "</tt></a>", vars];
};

public method .do_obj() {
    arg vars, flags, args;
    var href, context, object, name, options;
    
    context = flags.getkey("context");
    options = (| flags.getkey("options") |);
    name = flags.getkey("name");
    object = args[1];
    if (type(context) == 'string)
        context = tosym(context);
    if (options && (type(options) == 'string))
        options = tosym(options);
    if (type(object) == 'frob)
        return [name.to_html(), vars];
    switch (context) {
        case 'look:
            href = "/bin/describe?target=";
            if (options == 'exit)
                object = object.dest(args[2]);
        case 'set:
            href = "/set/set_list?target=";
        default:
            href = "/bin/display?target=";
    }
    object = toliteral(object).to_html();
    name = name.to_html();
    return [(((("<a href=\"" + href) + object) + "\">") + name) + "</a>", vars];
};

public method .do_passthru() {
    arg vars, flags, args;
    
    args = args[1];
    return [args, vars];
};

public method .do_option() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [(("\n<option " + ((flags.mmap('join, "=")).join(" "))) + ">") + args, vars];
};

public method .do_input() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [(("\n<input " + ((flags.mmap('join, "=")).join(" "))) + ">") + args, vars];
};


new object $pueblo_format: $html_format;

var $root manager = $pueblo_format;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 862777021;
var $root inited = 1;
var $root managed = [$pueblo_format];

public method .format() {
    arg data, vars;
    var str, len, line, out, base, port;
    
    base = "http://" + ($dns.hostname(""));
    port = $http_daemon.current_port();
    if (port != 80)
        base += ":" + port;
    vars = dict_add(vars, 'base_url, base);
    str = (> (._eval_ctext(data, vars))[1] <);
    if ((strlen(str) < 2) || (substr(str, strlen(str) - 1) != "\n"))
        str += "\n";
    return str_to_buf(str + "<br>\n");
};

public method .do_link() {
    arg vars, flags, args;
    var node;
    
    [args, vars] = ._eval_ctext([args[1]], vars);
    node = (| flags.getkey("node") |);
    if (node)
        return [((("<a xch_cmd=\"@help " + node) + "\">") + args) + "</a>", vars];
    return ["&gt;&gt;ERROR: Invalid node&lt;&lt;", vars];
};

public method .do_img() {
    arg vars, flags, args;
    var src, html, alt;
    
    src = flags.getkey("src");
    alt = (| ("alt=\"" + (flags.getkey("alt"))) + "\"" |) || "";
    if (!match_regexp(src, "^(http|ftp):"))
        src = (vars['base_url]) + src;
    return [((("<img src=\"" + src) + "\" align=left hspace=10 ") + alt) + ">", vars];
};

public method .do_detail() {
    arg vars, flags, args;
    var det;
    
    det = flags.getkey("name");
    return [((((((("<a href=\"" + (vars['base_url])) + "/bin/describe?target=") + ((vars['this]).objname())) + "&detail=") + ($http.encode(det))) + "\">") + det) + "</a>", vars];
};

public method .do_table() {
    arg vars, flags, args;
    
    [args, vars] = $plain_format.do_table(vars, flags, args);
    return [("<pre>" + args) + "</pre>", vars];
};

public method .do_tr() {
    arg vars, flags, args;
    
    return $plain_format.do_tr(vars, flags, args);
};

public method .do_td() {
    arg vars, flags, args;
    
    return $plain_format.do_td(vars, flags, args);
};

public method .init() {
    return #[['width, 78]];
};

public method .do_obj() {
    arg vars, flags, args;
    var gateway, argname, output, context, object, name, options;
    
    name = flags.getkey("name");
    [name, vars] = ._eval_ctext([name], vars);
    context = flags.getkey("context");
    options = (| flags.getkey("options") |);
    object = args[1];
    if (type(context) == 'string)
        context = tosym(context);
    if (options && (type(options) == 'string))
        options = tosym(options);
    switch (context) {
        case 'look:
            if (options) {
                switch (options) {
                    case 'exit:
                        output = [((("<a xch_cmd=\"" + (object.name('noarticle))) + "\">") + name) + "</a>", vars];
                    case 'contained:
                        output = [((((("<a xch_cmd=\"look " + ((object.location()).name('noarticle))) + "'s ") + (object.name('noarticle))) + "\">") + name) + "</a>", vars];
                }
            } else {
                output = [((("<a xch_cmd=\"look " + (object.name('noarticle))) + "\">") + name) + "</a>", vars];
            }
        case 'display:
            [gateway, argname] = ["display", "target"];
        case 'exit:
            output = [((("<a xch_cmd=\"go " + (object.name())) + "\">") + name) + "</a>", vars];
    }
    if (output)
        return output;
    return [((((((((("<a href=\"" + (vars['base_url])) + "/bin/") + gateway) + "?") + argname) + "=") + tostr(object)) + "\">") + name) + "</a>", vars];
};

public method .do_dl() {
    arg vars, flags, args;
    
    [args, vars] = ._do_dl(vars, flags, args);
    return [("<pre>" + args) + "</pre>", vars];
};

public method .do_dt() {
    arg vars, flags, args;
    
    return ._do_dt(vars, flags, args);
};

public method .do_dd() {
    arg vars, flags, args;
    
    return ._do_dd(vars, flags, args);
};

public method ._do_dl() {
    arg vars, flags, args;
    var out, token, c, cm, ind, mem;
    
    c = (| vars['columned] |) || 0;
    cm = (| flags.getkey("columned") |) || 0;
    ind = (| toint(flags.getkey("ind")) |) || 4;
    vars = vars.add('columned, cm);
    if (dict_contains(vars, 'dl_ind))
        mem = vars['dl_ind];
    vars = dict_add(vars, 'dl_ind, ind);
    [args, vars] = ._eval_ctext(args, vars);
    if (mem)
        vars = dict_add(vars, 'dl_ind, mem);
    else
        vars = dict_del(vars, 'dl_ind);
    if (c)
        vars = vars.add('columned, c);
    else if (vars.contains('columned))
        vars = vars.del('columned);
    return [args + "\n", vars];
};

public method ._do_dt() {
    arg vars, flags, args;
    
    vars = vars.add('header, "");
    [args, vars] = ._eval_ctext(args, vars);
    if ((| vars['columned] |))
        return ["\n  ", vars.add('header, pad("  " + args, 25 + ((args.length()) - ((.strip_tags(args)).length()))))];
    else
        return [("\n  " + args) + "\n", vars.add('header, "")];
};

public method ._do_dd() {
    arg vars, flags, args;
    
    return .eval_indented(args, vars, (| vars['dl_ind] |) || 4);
};

public method .eval_indented() {
    arg args, vars, i, @w;
    var width, indent;
    
    width = vars['width];
    vars = vars.add('width, (| w[1] |) || (width - i));
    [args, vars] = ._eval_ctext(args, vars);
    return [.rewrap_lines(vars, (vars['header]) + args, pad("", i)), vars.add('width, width)];
};

public method .rewrap_lines() {
    arg vars, str, prefix;
    var s, p, n, firstline;
    
    s = [];
    n = (vars['width]) + (prefix.length());
    for str in (str.explode("\n", 1))
        s += str.wrap_lines(n, prefix, 1);
    return s.join("\n");
};

public method .strip_tags() {
    arg string;
    var mode, chunk;
    
    return map chunk in (string.global_regexp("<[^<>]+>")) to ((mode = !mode) ? chunk : "").join("");
};


new object $uncompiler: $evaluator;

var $root manager = $uncompiler;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837583986;
var $root inited = 1;
var $root managed = [$uncompiler];

public method .quote() {
    arg s;
    
    return s.sed("([][{}\])", "\%1", "g");
};

public method .eval_generator() {
    arg gen, vars;
    var out, flags, key, value, text;
    
    catch ~methodnf {
        return .(gen.method())(vars, gen.ctext_flags(), gen.args());
    } with {
        out = ["[" + (gen.name())];
        flags = gen.ctext_flags();
        for key in (flags) {
            if ((key[2]) == 1) {
                out = out.affix(" " + (key[1]));
            } else {
                [text, vars] = (> ._eval_ctext([key[2]], vars, 1) <);
                out = (out.affix((" " + (key[1])) + "=")).affix(text);
            }
        }
        if (gen.args()) {
            out = out.affix(":");
            for key in (gen.args()) {
                [text, vars] = (> ._eval_ctext([key], vars) <);
                out = out.affix(text);
            }
        }
        return [out.affix("]"), vars];
    }
};

public method ._eval_ctext() {
    arg data, vars, @quote_all;
    var out, uflags, token, prev, next, t;
    
    out = [];
    if (type(data) != 'list)
        data = [data];
    prev = 0;
    token = 0;
    for next in (data + [0]) {
        t = token;
        switch (type(token)) {
            case 'integer:
            case 'frob:
                if (class(token) == $generator) {
                    [token, vars] = (> .eval_generator(token, vars) <);
                    out = out.affix(token);
                } else if (class(token) == $format) {
                    [token, vars] = (> .eval_formatter(token, vars) <);
                    out = out.affix(token);
                }
            case 'string:
                token = quote_all ? (.quote_all(token)) : (.quote(token));
                token = ._spaces(token, prev, 'prev);
                token = ._spaces(token, next, 'next);
                out = out.affix(token);
            default:
                out = out.affix(toliteral(token));
        }
        prev = t;
        token = next;
    }
    return [out, vars];
};

public method .eval_formatter() {
    arg gen, vars;
    var out, flags, key, value, text;
    
    catch ~methodnf {
        return .(gen.method())(vars, gen.ctext_flags(), gen.args());
    } with {
        out = ["{" + (gen.name())];
        flags = gen.ctext_flags();
        for key in (flags) {
            if ((key[2]) == 1) {
                out = out.affix(" " + (key[1]));
            } else {
                [text, vars] = ._eval_ctext(key[2], vars, 1);
                out = (out.affix((" " + (key[1])) + "=")).affix(text);
            }
        }
        if (gen.args()) {
            out = out.affix(":");
            for key in (gen.args()) {
                [text, vars] = ._eval_ctext([key], vars);
                out = out.affix(text);
            }
        }
        out = out.affix("}");
        return [out, vars];
    }
};

public method .quote_all() {
    arg s;
    
    return s.sed("([][{}\:= ])", "\%1", "g");
};

public method .do_quote() {
    arg vars, flags, args;
    
    return [(["{quote "].affix((args[1]).explode("\n", 1))).affix("}"), vars];
};

public method .do_detail() {
    arg vars, flags, args;
    
    return .eval_formatter((<$format, ["detail", flags, (| (vars['details])[flags.getkey("name")] |) || ["UNKNOWN"], 'DO_NOT_CALL_THIS]>), vars);
};

public method .do_p() {
    arg vars, flags, args;
    
    return [["", "{p}"], vars];
};

public method .do_dl() {
    arg vars, flags, args;
    var dl, token;
    
    if ((| flags.getkey("columned") |))
        dl = "{dl columned";
    else
        dl = "{dl";
    if ((| flags.getkey("ind") |))
        dl += " ind=" + (flags.getkey("ind"));
    dl += ":";
    [args, vars] = ._eval_ctext(args, vars);
    return [((["", dl].affix(args.prefix("  "))).affix("}")) + [""], vars];
};

public method .do_dt() {
    arg vars, flags, args;
    var dl, token;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [(["", "{dt: "].affix(args)).affix("}"), vars];
};

public method .do_dd() {
    arg vars, flags, args;
    var token;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [(["", "{dd: "].affix(args)).affix("}"), vars];
};

public method .do_dfn() {
    arg vars, flags, args;
    var nobound, ind, dfn;
    
    ind = (| flags.getkey("ind") |) || 8;
    nobound = (| flags.getkey("nobound") |);
    dfn = "{dfn";
    if (nobound)
        dfn += " nobound";
    if (ind && (ind != 8))
        dfn += " ind=" + ind;
    [args, vars] = ._eval_ctext(args, vars);
    if (nobound)
        return [(["", ("    " + dfn) + ":"].affix(args)).affix(["}"]), vars];
    return [(["", "", ("    " + dfn) + ":"].affix(args)).affix(["}"]), vars];
};

public method .do_subj() {
    arg vars, flags, args;
    var out, word, l;
    
    [args, vars] = ._eval_ctext(args, vars);
    l = toint((| flags.getkey("level") |) || "4");
    return [(["", "", ("{subj level=" + l) + ":"].affix(args)).affix(["}"]), vars];
};

public method .do_ul() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [((["", "{ul:"].affix(args.prefix("  "))).affix("}")) + [""], vars];
};

public method .do_li() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [(["", "{li:"].affix(args)).affix("}"), vars];
};

public method .do_td() {
    arg vars, flags, args;
    var opts, value;
    
    if ((value = (| toint(flags.getkey("rowspan")) |)))
        opts = " rowspan=" + value;
    else
        opts = "";
    if ((value = (| toint(flags.getkey("colspan")) |)))
        opts += " colspan=" + value;
    [args, vars] = ._eval_ctext(args, vars);
    return [(["", ("  {td" + opts) + ":"].affix(args)).affix("}"), vars];
};

public method .do_tr() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [(["", "{tr:"].affix(args)).affix("}"), vars];
};

public method .do_lh() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [(["", "{lh:"].affix(args)).affix("}"), vars];
};

public method .gen_switch() {
    arg vars, flags, args;
    var i, j, out, def, ret, val, l, lower, upper, val;
    
    def = [""];
    [val, vars] = ._eval_ctext(flags.getkey("value"), vars);
    out = [""];
    for i in (args) {
        [ret, vars] = ._eval_ctext(i[2], vars);
        if ((i[1]) == 'default) {
            def = ["", "[default]", ""].affix(ret.prefix("  "));
        } else if ((i[1]) == 'ranges) {
            for j in (i[2]) {
                [lower, upper, ret] = j;
                [ret, vars] = ._eval_ctext(ret, vars);
                out = (out.affix(["", ((("[range:" + lower) + "..") + upper) + "]", ""])).affix(ret.prefix("  "));
            }
        } else {
            out = (out.affix(["", ("[case:" + (i[1])) + "]", ""])).affix(ret.prefix("  "));
        }
    }
    return [(((["", "[switch value="].affix(val)).affix(":")).affix((out.affix(def)).prefix("  "))).affix(["]", ""]), vars];
};

public method ._spaces() {
    arg token, other, dir;
    var m, i;
    
    if ((type(other) == 'frob) && ((other.name()) in ($compiler.glue_table()))) {
        if (dir == 'prev) {
            m = ((token.regexp("^ *"))[1]).length();
            return ("".pad(m * 2, "\ ")) + (token.subrange(m + 1));
        } else {
            m = ((token.regexp(" *$"))[1]).length();
            return (token.subrange(1, (token.length()) - m)) + ("".pad(m * 2, "\ "));
        }
    }
    return token;
};

public method .do_th() {
    arg vars, flags, args;
    var opts, value;
    
    if ((value = (| toint(flags.getkey("rowspan")) |)))
        opts = " rowspan=" + value;
    else
        opts = "";
    if ((value = (| toint(flags.getkey("colspan")) |)))
        opts += " colspan=" + value;
    [args, vars] = ._eval_ctext(args, vars);
    return [(["", ("  {th" + opts) + ":"].affix(args)).affix("}"), vars];
};

public method .do_np() {
    arg vars, flags, args;
    
    return [["", "", "{np}"], vars];
};

public method .do_br() {
    arg vars, flags, args;
    
    return [["", "{br}"], vars];
};

public method .do_switch() {
    arg vars, flags, args;
    var i, j, out, def, ret, val, l, lower, upper, val;
    
    def = [""];
    [val, vars] = ._eval_ctext(flags.getkey("value"), vars);
    out = [""];
    for i in (args) {
        [ret, vars] = ._eval_ctext(i[2], vars);
        if ((i[1]) == 'default) {
            def = ["", "[default]", ""].affix(ret.prefix("  "));
        } else if ((i[1]) == 'ranges) {
            for j in (i[2]) {
                [lower, upper, ret] = j;
                [ret, vars] = ._eval_ctext(ret, vars);
                out = (out.affix(["", ((("[range:" + lower) + "..") + upper) + "]", ""])).affix(ret.prefix("  "));
            }
        } else {
            out = (out.affix(["", ("[case:" + (i[1])) + "]", ""])).affix(ret.prefix("  "));
        }
    }
    return [(((["", "{switch value="].affix(val)).affix(":")).affix((out.affix(def)).prefix("  "))).affix(["}", ""]), vars];
};


new object $housekeeper: $utilities;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $housekeeper;
var $root managed = [$housekeeper];

public method .did_disconnect() {
    var task_queue, task, realm, delay;
    
    if (caller() != $user)
        throw(~perm, "Permission denied");
    
    // Are we removing users?
    if (($world.get_setting("cleanup-disconnected-users", $world)) == 0) {
        return;
    } else {
        // because of guests
        if (!valid(sender()))
            return;
        catch any
            delay = ((sender().location()).realm()).get_setting("housekeeper-delay", $realm);
        with
            delay = 300;
        $scheduler.add_task(delay, 'move_user_home, sender());
    }
};

public method .move_user_home() {
    arg who;
    var home, curloc;
    
    who.poll_semaphore('cleanup);
    if (who.connected())
        return;
    (| who.cleanup_sessions() |);
    curloc = who.location();
    home = who.home();
    if (curloc == home)
        return;
    (| who.move_to(home) |) || (> who.move_to($body_cave) <);
    curloc.did_housekeep(who);
    who.release_semaphore('cleanup);
};


new object $word: $utilities;

var $root manager = $word;
var $word syllables = #[[2, 3], [3, 4]];
var $root flags = ['variables, 'methods, 'code, 'core, 'fertile];
var $root created_on = 856377068;
var $root inited = 1;
var $word syllable_pat = #[[["V"], 2], [["V", "LC"], 6], [["C", "V"], 8]];
var $word firstcons = #[["th", 1], ["b", 5], ["f", 9], ["qu", 10]];
var $word vowels = #[["a", 10], ["e", 20], ["i", 30]];
var $root help_node = $help_sys_word;
var $word lastcons = #[["bh", 1], ["d", 5], ["b", 9]];
var $root managed = [$word];

public method .set_chances() {
    arg what, value;
    var out, last, v, chance;
    
    (> .perms(sender()) <);
    
    // chances are received as a #[["what", chance]] dict
    // which is converted where the chance is a cumulative range of the total
    out = #[];
    for v in (value) {
        chance = v[2];
        out = dict_add(out, v[1], chance + last);
        last += chance;
    }
    set_var(what, out);
    return get_var(what);
};

public method .vowels() {
    return vowels;
};

public method .lastcons() {
    return lastcons;
};

public method .firstcons() {
    return firstcons;
};

public method .syllables() {
    return syllables;
};

public method .syllable_pat() {
    return syllable_pat;
};

public method .pick_value() {
    arg name;
    var top, pick, v, last;
    
    top = dict_values(get_var(name)).last();
    pick = random(top);
    for v in (get_var(name)) {
        if ((v[2]) > pick)
            return v[1];
        last = v[1];
    }
    return last;
};

public method .generate() {
    var x, y, out, pat, p;
    
    out = "";
    for x in [1 .. .pick_value('syllables)] {
        pat = .pick_value('syllable_pat);
        for p in (pat) {
            switch (p) {
                case "V":
                    out += .pick_value('vowels);
                case "C":
                    out += .pick_value('firstcons);
                case "LC":
                    out += .pick_value('lastcons);
                default:
                    throw(~invpat, "Invalid syllable pattern: " + pat);
            }
        }
    }
    return out.capitalize();
};

public method .submit_chances() {
    arg lines;
    var line, linec, s, sp, v, fc, lc, val, chance, vsp, part;
    
    s = (sp = (v = (fc = (lc = #[]))));
    for line in (lines) {
        linec++;
        if (match_regexp(line, " *#"))
            continue;
        line = line.explode_quoted();
        if (!line)
            continue;
        if (listlen(line) != 3)
            throw(~bad, (("Line " + linec) + ": Invalid config: ") + (line.join()));
        chance = toint(line[3]);
        if (!chance)
            throw(~bad, ("Line " + linec) + ": Chance must be one or more.");
        switch (line[1]) {
            case "S":
                val = toint(line[2]);
                if (!val)
                    throw(~bad, ("Line " + linec) + ": Syllables must be one or more.");
                s = s.add(val, chance);
            case "SP":
                val = line[2];
                val = explode(uppercase(strsed(val, "[^CVL-]+", "")), "-");
                if (filter part in (val) where (!(part in ["C", "V", "LC"])))
                    throw(~bad, ("Line " + linec) + ": Invalid syllable pattern");
                sp = sp.add(val, chance);
            case "C":
                if (!(line[2]))
                    throw(~bad, ("Line " + linec) + ": Invalid consanant");
                fc = fc.add(line[2], chance);
            case "LC":
                if (!(line[2]))
                    throw(~bad, ("Line " + linec) + ": Invalid consanant");
                lc = lc.add(line[2], chance);
            case "V":
                if (!(line[2]))
                    throw(~bad, ("Line " + linec) + ": Invalid vowel");
                v = v.add(line[2], chance);
            default:
                throw(~bad, (("Line " + linec) + ": Invalid directive: ") + (line[1]));
        }
        refresh();
    }
    .set_chances('syllables, s);
    .set_chances('syllable_pat, sp);
    .set_chances('firstcons, fc);
    .set_chances('lastcons, lc);
    .set_chances('vowels, v);
};

public method .format_chances() {
    return ((((((((.format_dict(syllables, "S")) + [""]) + (.format_dict(syllable_pat, "SP"))) + [""]) + (.format_dict(vowels, "V"))) + [""]) + (.format_dict(firstcons, "C"))) + [""]) + (.format_dict(lastcons, "LC"));
};

public method .format_dict() {
    arg dict, cmd;
    var out, v, last, num;
    
    out = [];
    for v in (dict) {
        num = (v[2]) - last;
        last = v[2];
        if ((type(v[1]) == 'string) && (" " in (v[1])))
            out += [(((cmd + " \"") + (v[1])) + "\" ") + num];
        if (type(v[1]) == 'list)
            out += [(((cmd + " ") + ((v[1]).join("-"))) + " ") + num];
        else
            out += [(((cmd + " ") + (v[1])) + " ") + num];
    }
    return out;
};


new object $lovecraft_word: $word;

var $root manager = $lovecraft_word;
var $word vowels = #[["a", 580], ["aa", 598], ["ae", 600], ["ah", 611], ["ai", 643], ["au", 657], ["aw", 658], ["ay", 660], ["e", 847], ["ea", 848], ["ee", 857], ["eh", 860], ["ei", 872], ["eu", 874], ["i", 1110], ["ie", 1113], ["ih", 1114], ["ii", 1115], ["o", 1423], ["oh", 1424], ["oi", 1432], ["oo", 1447], ["ou", 1473], ["ow", 1475], ["oy", 1476], ["u", 1590], ["uh", 1591], ["uu", 1594], ["y", 1638], ["ya", 1651], ["ye", 1652], ["yeh", 1653], ["yi", 1657], ["yo", 1667], ["yoh", 1668], ["yu", 1674]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856378321;
var $root inited = 1;
var $word lastcons = #[["b", 20], ["bn", 21], ["c", 42], ["ch", 48], ["d", 74], ["f", 79], ["g", 107], ["gh", 110], ["gn", 111], ["j", 112], ["k", 133], ["l", 214], ["lf", 215], ["ll", 216], ["lp", 217], ["lt", 219], ["lth", 220], ["m", 278], ["mb", 279], ["mh", 280], ["mr", 281], ["ms", 283], ["n", 434], ["nd", 437], ["ng", 449], ["ngh", 451], ["nn", 452], ["ns", 453], ["nt", 457], ["nth", 458], ["p", 464], ["ph", 469], ["ps", 471], ["q", 473], ["qh", 474], ["r", 608], ["rc", 609], ["rd", 611], ["rg", 613], ["rgh", 614], ["rh", 616], ["rn", 619], ["rp", 620], ["rph", 621], ["rrh", 622], ["rt", 623], ["rth", 628], ["s", 730], ["sh", 734], ["sht", 735], ["sk", 739], ["st", 742], ["t", 767], ["th", 820], ["tl", 821], ["v", 823], ["x", 830], ["z", 842]];
var $word firstcons = #[["b", 58], ["bh", 59], ["bhl", 60], ["br", 63], ["c", 117], ["ch", 137], ["chth", 138], ["cl", 141], ["cr", 145], ["cth", 148], ["d", 218], ["dh", 221], ["djh", 223], ["dl", 224], ["dr", 227], ["dw", 229], ["dz", 230], ["f", 245], ["fr", 247], ["g", 297], ["gh", 308], ["ghl", 309], ["gl", 310], ["gn", 314], ["gr", 316], ["h", 360], ["hl", 361], ["hs", 362], ["j", 370], ["k", 404], ["kh", 406], ["kl", 408], ["kr", 409], ["kth", 410], ["l", 557], ["ll", 558], ["m", 669], ["mh", 670], ["ml", 671], ["mm", 672], ["mn", 673], ["mth", 674], ["n", 781], ["ngr", 782], ["nh", 783], ["nl", 785], ["p", 819], ["ph", 838], ["phl", 839], ["phr", 840], ["pn", 844], ["pr", 846], ["ps", 847], ["pt", 848], ["qu", 864], ["r", 977], ["rh", 980], ["rl", 982], ["rr", 983], ["s", 1048], ["sf", 1049], ["sh", 1065], ["sk", 1066], ["sn", 1068], ["sng", 1069], ["st", 1070], ["str", 1072], ["t", 1143], ["th", 1199], ["thr", 1202], ["tl", 1203], ["tn", 1204], ["tr", 1207], ["ts", 1211], ["tsch", 1212], ["v", 1254], ["vhl", 1255], ["vl", 1256], ["vr", 1257], ["w", 1266], ["x", 1275], ["z", 1318], ["zh", 1323], ["zk", 1324]];
var $word syllable_pat = #[[["V"], 1], [["V", "LC"], 2], [["C", "V"], 6], [["C", "V", "LC"], 10]];
var $word syllables = #[[1, 3], [2, 8], [3, 13], [4, 16], [5, 17]];
var $root managed = [$lovecraft_word];


new object $password: $word;

var $root manager = $password;
var $word syllables = #[[3, 1], [4, 2]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856543004;
var $root inited = 1;
var $word syllable_pat = #[[["V"], 2], [["V", "C"], 7], [["C", "V"], 12], [["C", "V", "C"], 13]];
var $word firstcons = #[["b", 50], ["c", 100], ["d", 150], ["bd", 160], ["f", 210], ["g", 260], ["h", 310], ["j", 360], ["k", 410], ["l", 460], ["m", 510], ["n", 560], ["p", 610], ["qu", 640], ["q", 650], ["r", 700], ["s", 750], ["t", 800], ["v", 803], ["w", 813], ["x", 814], ["y", 821], ["z", 822], ["th", 847]];
var $word lastcons = #[];
var $word vowels = #[["a", 500], ["aa", 501], ["ae", 547], ["ai", 585], ["ao", 587], ["au", 621], ["ah", 629], ["ay", 643], ["e", 1143], ["ea", 1242], ["ee", 1281], ["ei", 1307], ["eo", 1348], ["eu", 1376], ["ey", 1384], ["i", 1884], ["ia", 2034], ["ie", 2073], ["ii", 2077], ["io", 2229], ["iu", 2246], ["o", 2646], ["oa", 2670], ["oe", 2687], ["oi", 2727], ["ou", 2855], ["oy", 2860], ["u", 2985], ["ua", 3012], ["ue", 3031], ["ui", 3056], ["y", 3101]];
var $root managed = [$password];

public method .generate() {
    var out, v, c;
    
    return lowercase(pass());
    out = lowercase(pass());
    for v in [1 .. strlen(out)] {
        if (random(4) == 1) {
            if (random(2) == 1) {
                c = uppercase(out[v]);
                out = (substr(out, 1, v - 1) + c) + substr(out, v + 1);
            } else {
                out = (substr(out, 1, v) + (random(10) - 1)) + substr(out, v + 1);
            }
        }
    }
    return out;
};


new object $settings: $utilities;

var $root manager = $settings;
var $root managed = [$settings];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 857619568;
var $root inited = 1;

public method .is_type() {
    arg value, type, @subtypes;
    var i;
    
    if (type(value) == type)
        return value;
    switch (type) {
        case 'list:
            value = fromliteral(value);
            if (type(value) != 'list)
                throw(~type, "Value is unparsable as list.");
            if (subtypes)
                value = map i in (value) to ((> .is_type(i, subtypes[1]) <));
            return value;
        case 'dictionary:
            value = fromliteral(value);
            if (type(value) != 'dictionary)
                throw(~type, "Value is unparsable as dictionary.");
            if (subtypes)
                value = hash i in (value) to ((> [.is_type(i, subtypes[1]), .is_type(i, subtypes[2])] <));
            return value;
        case 'integer:
            if (value.is_numeric())
                return toint(value);
            else
                throw(~type, "Value is unparsable as integer.");
        case 'symbol:
            if ((type(value) == 'string) && (((value.length()) > 1) && ((value[1]) == "'")))
                value = value.subrange(2);
            if (type((| tosym(value) |)) == 'symbol)
                return tosym(value);
            else
                throw(~type, "Value is unparsable as a symbol.");
        case 'objnum:
            return (> $object_lib.to_dbref(value) <);
        default:
            return value;
    }
};

public method .format_boolean() {
    arg value;
    
    if (value)
        return "yes";
    else
        return "no";
};

public method .is_boolean() {
    arg value;
    var bool;
    
    if ((bool = value.is_boolean()) == (-1))
        throw(~invtype, ("Value \"" + value) + "\" is not boolean.");
    return bool;
};

public method .format_onoff() {
    arg value;
    
    if (value)
        return "on";
    else
        return "off";
};

public method .format_object() {
    arg value;
    
    return value.namef('xref);
};

public method .is_propagator() {
    arg value;
    
    return (> $propagator.new_with(value) <);
};

public method .format_propagator() {
    arg value;
    
    return (type(value) == 'frob) ? (value.format()) : "no";
};

public method .is_valid_type() {
    arg type;
    
    return ($data_lib.is_valid_type(type)) || (type in (.valid_types()));
};

public method .valid_types() {
    return ['boolean, 'itemlist];
};

public method .parse_itemlist() {
    arg value, method, @args;
    var action, list, item, out;
    
    if (value && ((value[1]) in ["+", "-"])) {
        if ((value[1]) == "-")
            action = 'del;
        else
            action = 'add;
        list = [substr(value, 2)];
    } else {
        action = 'set;
        list = value.explode_english_list();
    }
    out = [];
    for item in (list) {
        if (method) {
            catch ~methodnf
                item = (> sender().(method)(item, action, @args) <);
            with
                item = (> .(method)(item, action, @args) <);
        }
        out += [item];
    }
    if (action == 'set)
        return [action, out];
    else
        return [action, out[1]];
};

public method .format_itemlist() {
    arg data;
    
    return data.join(", ");
};

public method .parse_object() {
    arg value, @args;
    var obj;
    
    catch any {
        return $object_lib.to_dbref(value);
    } with {
        if (!user())
            rethrow(error());
    }
    return (> user().match_environment(value) <);
};


new object $world: $utilities, $event_handler;

var $root manager = $world;
var $world last_weather_change = 1011936170;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850845715;
var $root inited = 1;
var $root managed = [$world];
var $event_handler events = 0;
var $event_handler hooks = #[];
var $event_handler hooked = #[];
var $root trusted = [$realm];
var $root defined_settings = #[["starting-place", #[['parse, ['is_type, 'objnum]]]], ["heartbeat-rate", #[['parse, ['parse_heartbeat_rate]], ['get, ['get_heartbeat_rate]], ['set, ['set_heartbeat_rate]], ['format, ['fmt_heartbeat_rate]]]], ["weather-rate", #[['parse, ['parse_weather_rate]], ['get, ['get_weather_rate]], ['set, ['set_weather_rate]], ['format, ['fmt_weather_rate]]]], ["realms", #[['get, ['get_realms]], ['set, ['set_realms]], ['parse, ['parse_itemlist, 'parse_realms]], ['format, ['format_itemlist]]]], ["cleanup-disconnected-users", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $root settings = #[["starting-place", $the_pit], ["weather-rate", 5000], ["cleanup-disconnected-users", 1]];
var $world realms = [$realm_of_creation];
var $world heartbeat_rate = 600;
var $world weather_rate = 5400;

public method .starting_place() {
    return (| .get_setting("starting-place", $world) |) || $body_cave;
};

public method .startup() {
    arg @args;
    
    (> .perms(sender(), 'manager) <);
    if (heartbeat_rate > 0)
        $heart.add_heartbeat(heartbeat_rate);
    last_weather_change = 0;
};

public method .shutdown() {
    (> .perms(sender(), 'manager) <);
    $heart.del_heartbeat();
};

public method .send_event() {
    arg @args;
    
    (> .perms(caller(), 'trusts) <);
    pass(@args);
};

public method .pulse() {
    var i, d, weather_ticked, t;
    
    (> .perms(sender(), $heart) <);
    t = time();
    weather_ticked = 0;
    if (t >= (last_weather_change + weather_rate)) {
        weather_ticked = 1;
        last_weather_change = t;
    }
    for i in (realms) {
        pause();
        catch any {
            i.advance_weather(weather_ticked);
        } with {
            (| (i.manager()).tell_traceback(traceback()) |);
            (| (i.manager()).tell(("Weather change failed for " + i) + ".") |);
        }
    }
};

root method .core_world() {
    .set_setting("realms", $world, "$realm_of_creation");
    .set_setting("starting-place", $world, $the_pit);
};

public method .parse_realms() {
    arg value, action, @args;
    var obj, list;
    
    obj = (> $object_lib.to_dbref(value) <);
    if (!(obj.is($realm)))
        throw(~set, ("The object '" + obj) + "' is not a realm object.");
    return obj;
};

public method .get_realms() {
    arg @ignored;
    
    return realms;
};

protected method .set_realms() {
    arg name, definer, value;
    
    switch (value[1]) {
        case 'set:
            realms = value[2];
        case 'add:
            realms = setadd(realms, value[2]);
        case 'del:
            realms = setremove(realms, value[2]);
        default:
            throw(~type, "Unknown action: " + (value[1]));
    }
};

public method .fmt_heartbeat_rate() {
    arg data;
    
    return $time.to_english(data);
};

public method .get_heartbeat_rate() {
    arg @args;
    
    return heartbeat_rate;
};

public method .parse_heartbeat_rate() {
    arg value, @args;
    
    value = (> $time.from_english(value) <);
    if (value < 1)
        throw(~set, "You cannot set the heartbeat rate to less than 1 second");
    return value;
};

protected method .set_heartbeat_rate() {
    arg name, definer, value;
    
    heartbeat_rate = value;
    if (heartbeat_rate > 0)
        $heart.add_heartbeat(heartbeat_rate);
};

public method .fmt_weather_rate() {
    arg data;
    
    return $time.to_english(data);
};

public method .get_weather_rate() {
    arg @args;
    
    return weather_rate;
};

public method .parse_weather_rate() {
    arg value, @args;
    
    value = (> $time.from_english(value) <);
    if (value < 1)
        throw(~set, "You cannot set the weather rate to less than 1 second");
    return value;
};

protected method .set_weather_rate() {
    arg name, definer, value;
    
    weather_rate = value;
};


new object $cml_color: $utilities;

var $root manager = $cml_color;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863559837;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $cml_color colors = #[["black", ["000000", "30", "40"]], ["red", ["ff0000", "31", "41"]], ["green", ["00ff00", "32", "42"]], ["yellow", ["ffff00", "33", "43"]], ["blue", ["0000ff", "34", "44"]], ["magenta", ["ff00ff", "35", "45"]], ["cyan", ["00ffff", "36", "46"]], ["white", ["ffffff", "37", "47"]]];
var $root managed = [$cml_color];

public method .get_color() {
    arg color;
    
    return colors[color];
};

public method .fmt_colors() {
    var c, out;
    
    out = ["COLOR        RGB     ANSI"];
    for c in (colors)
        out += [strfmt("%12s #%6l %3l", c[1], @c[2])];
    return out;
};


new object $physical: $described, $event_handler;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $described prose = [];
var $physical visibility = 0;
var $has_name name = ['uniq, "Generic Physical Object", "the Generic Physical Object"];
var $root manager = $physical;
var $root defined_settings = #[["visibility", #[['get, ['visibility]], ['set, ['set_visibility]], ['parse, ['is_type, 'integer]]]]];
var $root managed = [$physical];

public method .set_visibility() {
    arg name, definer, value, @args;
    
    (> .perms(sender()) <);
    visibility = value;
};

public method .visibility() {
    arg @args;
    
    return visibility;
};

public method .is_visible_to() {
    arg whom;
    
    return (.visibility()) >= ((whom.location()).darkness());
};

public method .vr_examine();

public method .check_location() {
    arg sender;
    
    if ((.location()) != (sender.location()))
        throw(~location, "It's too far away!");
};


new object $located: $physical;

var $located inited = 0;
var $located location = $nowhere;
var $located obvious = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $described prose = [];
var $has_name name = ['uniq, "Generic Located Object", "the Generic Located Object"];
var $root manager = $located;
var $root managed = [$located];

root method .init_located() {
    location = $void;
    location.add_sender_to_contents();
    obvious = 1;
};

public method .uninit_guest_guest() {
    if (caller() != $root)
        throw(~perm, "Caller is not root.");
    location.del_sender_from_contents();
    location = 0;
};

public method .environment() {
    var env;
    
    env = setremove(location.environment(), this());
    return [this()] + env;
};

public method .match_environment() {
    arg str;
    var thing, matches;
    
    if (str == "here")
        return location;
    return (> pass(str) <);
};

public method .location() {
    return location || $void;
};

public method .will_move() {
    arg mover, place;
    
};

protected method .did_move() {
    arg mover, old_place;
    
    // cleanup events  
    .unhook_events('move, old_place);
    old_place.send_event('movement, 'leave, location);
    location.send_event('movement, 'arrive, old_place);
    .hook_events('move);
};

public method .realm() {
    return (.location()).realm();
};

root method .uninit_located() {
    var location;
    
    location = .location();
    if (valid(location)) {
        location.del_sender_from_contents();
        location.did_leave(this(), $nowhere);
    }
};

public method .move_to(): nooverride {
    arg place;
    var old, mover;
    
    // Don't do anything if we're already here.
    if (place == location)
        return;
    if (!(place.has_ancestor($location)))
        throw(~type, (place.namef('ref)) + " is not a location.");
    old = place;
    old = place;
    while (1) {
        if (old == this())
            throw(~move, "You cannot move something into itself.");
        old = (| old.location() |);
        if (!old)
            break;
    }
    if (!valid(location))
        location = $nowhere;
    mover = sender();
    (> .will_move(mover, place) <);
    (> location.will_leave(mover, place) <);
    (> place.will_arrive(mover, location) <);
    
    // Set location.
    old = location;
    location = place;
    old.del_sender_from_contents();
    place.add_sender_to_contents();
    
    // Notify involved parties of completed move, in reverse order.
    place.did_arrive(mover, old);
    old.did_leave(mover, place);
    .did_move(mover, old);
};

public method .match_environment_all() {
    arg s;
    
    if (s == "here")
        return [location, @(> pass(@args) <)];
    else
        return (> pass(s) <);
};

public method .obvious() {
    return obvious;
};

public method .set_obvious() {
    arg obv;
    
    .perms(sender());
    obvious = obv;
};

public method .realm_name() {
    arg @args;
    
    return (.location()).realm_name(@args);
};

public method .is_obvious_to() {
    arg whom;
    
    return .is_visible_to(whom);
};

public method .eject(): nooverride {
    arg @args;
    var old, mover, place;
    
    [(place ?= $nowhere)] = args;
    if (!($sys.is_system(sender()))) {
        if (sender() == location)
            place = (.has_ancestor($body)) ? ($world.starting_place()) : $nowhere;
        else
            throw(~perm, ("Only system objects and " + (.name())) + "'s current location may call .eject()");
    }
    
    // Don't do anything if we're already here.
    if (place == location)
        return;
    if (!(place.has_ancestor($location)))
        throw(~type, (place.namef('ref)) + " is not a location.");
    if (place == this())
        throw(~move, "You cannot move something into itself.");
    if (!valid(location))
        location = $nowhere;
    mover = sender();
    
    // Set location.
    old = location;
    location = place;
    old.del_sender_from_contents();
    place.add_sender_to_contents();
    
    // Notify involved parties of completed move, in reverse order.
    place.did_arrive(mover, old);
    old.did_leave(mover, place);
    .did_move(mover, old);
};


new object $thing: $located;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $located location = $void;
var $located obvious = 1;
var $described prose = [];
var $has_name name = ['normal, "thing", "a thing"];
var $has_commands shortcuts = #[];
var $has_commands remote = #[["@boot", [["@boot", "*", "@boot <this>", 'boot_cmd, #[[1, ['this, []]]]]]]];
var $has_commands local = #[];
var $thing lock = <$true_lock_frob, []>;
var $root settings = #[["home", $lost_and_found]];
var $root manager = $thing;
var $root defined_settings = #[["home", #[['get, ['home]], ['parse, ['parse_home]]]], ["gender", #[['get, ['gender]], ['set, ['set_gender]], ['parse, ['parse_gender_setting]]]], ["lock", #[['get, ['get_lock]], ['set, ['set_lock]], ['parse, ['parse_lock]], ['format, ['format_lock]]]]];
var $thing gender = $gender_neuter;
var $root managed = [$thing];
var $foundation defined_msgs = #[["desc-integrated", #[['branches, ["general"]]]]];
var $foundation msgs = #[["desc-integrated", #[["general", <$ctext_frob, [[], #[]]>]]]];

public method .boot_cmd() {
    arg cmdstr, cmd, this;
    var loc, dest, exit;
    
    loc = .location();
    if (!(| loc.perms(sender(), 'manager) |)) {
        (| .tell((((sender().name()) + " tried to boot you from ") + (loc.name())) + "!") |);
        loc.announce((((((sender().name()) + " tried to boot ") + (.name())) + " from ") + (loc.name())) + "!", sender(), this());
        return ((("Only " + ((loc.manager()).name())) + " can boot people from ") + (loc.name())) + "!";
    }
    dest = .home();
    catch any {
        sender().tell(("You boot " + (.name())) + ".");
        loc.announce((((((sender().name()) + " boots ") + (.name())) + " from ") + ((.location()).name())) + ".", this(), sender());
        if ((sender().location()) != loc)
            (sender().location()).announce((((((sender().name()) + " boots ") + (.name())) + " from ") + ((.location()).name())) + ".", this(), sender());
        (> .move_to(dest) <);
    } with {
        return (traceback()[1])[2];
    }
};

public method .lock() {
    return lock;
};

public method .lock_cmd() {
    arg cmdstr, cmd, this;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    lock = $false_lock_frob.new();
    return "You lock " + (.name());
};

public method .lock_with_cmd() {
    arg cmdstr, cmd, this, prep, str;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    catch ~objnf, ~parse {
        lock = $lock_frob.parse(str, sender());
        return ((((("You lock " + (.name())) + " ") + prep) + " ") + (lock.lock_name('thing))) + ".";
    } with {
        switch (error()) {
            case ~objnf:
                return "Object not found in lock string.";
            case ~parse:
                return "Invalid lock string.";
        }
    }
};

public method .unlock_cmd() {
    arg cmdstr, cmd, this;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    lock = $true_lock_frob.new();
    return "You unlock " + (.name());
};

public method .will_move() {
    arg mover, place;
    
    (> pass(mover, place) <);
    if (mover.is($housekeeper))
        return;
    if (lock && ((mover != $path) && ((mover != $location) && (!(lock.try(mover))))))
        throw(~locked, ((((.name()).capitalize()) + " is locked to ") + (lock.lock_name('thing))) + ".");
    
    //else if (!.trusts(mover))
    //    throw(~move, "You cannot move " + this());
    //
    // If this is left in (and fixed as above, used to be sender() instead of
    // mover), then nothing can move anything that doesn't trust the mover.
    // --Sean 1999.08.27
};

public method .home() {
    arg @args;
    var home;
    
    home = .get_local_setting("home", $thing);
    if (home)
        return home;
    if ((.manager()).is($user))
        return .manager();
    return $lost_and_found;
};

public method .try_lock() {
    arg mover;
    
    return lock && ((mover != $path) && (lock.try(mover)));
};

public method .directed_tell() {
    arg @args;
    
};

public method .parse_home() {
    arg value, @args;
    var home;
    
    home = (| .match_environment(value) |) || (> $place_db.search(value) <);
    if ((!(home.is_writable_by(user()))) && ((!(home.trusts(sender()))) && (!(home.get_setting("public-home", $place)))))
        throw(~notpublic, ("You do not have permission to make " + (home.name())) + " your home.");
    return home;
};

public method .parse_gender_setting() {
    arg value, @args;
    var g, gs;
    
    gs = $sys.get_valid_genders();
    g = value in (gs.mmap('name));
    if (!g)
        throw(~set, "Gender must be one of: " + ((gs.mmap('name)).to_english("", " or ")));
    return gs[g];
};

protected method .set_gender() {
    arg name, definer, value;
    
    (> .perms(sender()) <);
    gender = value;
};

public method .gender() {
    arg @args;
    
    return gender;
};

root method .init_thing() {
    gender = $gender_neuter;
};

public method .gender_context() {
    return gender.pronoun('po);
};

public method .get_lock() {
    arg name, definer;
    
    return lock || (<$true_lock_frob, []>);
};

protected method .set_lock() {
    arg name, definer, value;
    
    if (class(value) == $true_lock_frob)
        (| clear_var('lock) |);
    else
        lock = value;
};

public method .parse_lock() {
    arg value;
    
    if (value in ["lock", "locked"])
        value = "no";
    else if (value in ["unlock", "unlocked"])
        value = "yes";
    return (> $lock_frob.parse(value, user() || this()) <);
};

root method .format_lock() {
    arg value;
    var unparse;
    
    unparse = value.unparse();
    if (unparse == "yes")
        return "unlocked";
    else if (unparse == "no")
        return "locked";
    return unparse;
};


new object $command_cache: $has_commands;

var $root manager = $command_cache;
var $command_cache commands = 0;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874602916;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $root inited = 1;
var $command_cache shortcuts = 0;
var $command_cache modules = [];
var $root managed = [$command_cache];
var $root help_node = $help_obj_command_cache;
var $root defined_settings = #[["command-modules", #[['get, ['command_modules]], ['set, ['set_command_modules]], ['parse, ['parse_itemlist, 'parse_command_module]], ['format, ['format_itemlist]]]]];

protected method .set_command_modules() {
    arg name, definer, value;
    var m;
    
    switch (value[1]) {
        case 'set:
            for m in (modules.set_difference(value[2]))
                .del_command_module(m);
            for m in ((value[2]).set_difference(modules))
                .add_command_module(m);
        case 'add:
            .add_command_module(value[2]);
        case 'del:
            .del_command_module(value[2]);
        default:
            throw(~type, "Unknown action: " + (value[1]));
    }
};

protected method .cache_client_uninit() {
    var p;
    
    if (sender() != this())
        (> .perms(sender()) <);
    if (.is($place)) {
        for p in (.contents()) {
            if (p.is($command_cache))
                return;
        }
    }
    for p in (([this()] + parents()) + modules)
        (| p.cache_server_uninit() |);
};

public method .cache_client_init() {
    var p;
    
    if (sender() != this())
        (> .perms(sender()) <);
    modules ?= [];
    for p in (([this()] + parents()) + modules)
        (| p.cache_server_init() |);
};

public method .del_command_module() {
    arg module;
    
    (> .perms(sender()) <);
    modules = setremove(modules || [], module);
    module.cache_server_uninit();
};

public method .add_command_module() {
    arg module;
    
    (> .perms(sender()) <);
    if (!('general_cache in (module.flags())))
        throw(~notcache, module + " is not marked as a general_cache");
    modules = setadd(modules || [], module);
    module.cache_server_init();
};

public method .match_shortcut() {
    arg str, @ignore;
    var s, match, obj, args;
    
    for obj in (([this()] + filter s in (parents()) where (s.has_ancestor($command_cache))) + modules) {
        for s in ((obj.shortcut_cache()) || []) {
            if ((match = match_pattern(str, s[1])) != 0) {
                args = $command_lib.handle_shortcut_fields((s[2])[2], match);
                return ['shortcut, [(s[2])[1], [str, @args]]];
            }
        }
    }
    return 0;
};

public method .cache_server_uninit() {
    var user;
    
    if (caller() != $command_cache)
        throw(~perm, "Caller is not of the command subsystem.");
    
    // see if anybody still needs us, otherwise purge
    if (.is_general_cache()) {
        for user in ($user_db.connected()) {
            if ((user.has_ancestor(this())) || (this() in (user.command_modules())))
                return;
        }
    }
    .purge_cache();
};

public method .cache_server_init() {
    if (!(sender().has_ancestor(definer())))
        throw(~nochild, ((sender() + " is not a descendant of ") + definer()) + ".");
    if (type(commands) != 'dictionary)
        .rehash_cache();
};

public method .is_general_cache() {
    return 'general_cache in (.flags());
};

protected method .del_from_cache() {
    arg command, definer;
    var part, cmd, c;
    
    if (type(commands) != 'dictionary)
        commands = #[];
    cmd = command.word(1);
    for part in (cmd.explode_template_word()) {
        for c in ((| commands[part] |) || []) {
            if (c == [command, definer])
                commands = commands.del_elem(part, [command, definer]);
        }
    }
};

protected method .add_to_cache() {
    arg command, definer;
    var part, cmd;
    
    if (type(commands) != 'dictionary)
        commands = #[];
    cmd = command.word(1);
    for part in (cmd.explode_template_word())
        commands = commands.setadd_elem(part, [cmd, definer]);
};

public method .match_command() {
    arg str, cmd, args;
    var command, m, matched, templates, info, cdef, def, cmds, c, p;
    
    templates = (matched = []);
    cmds = #[];
    if (dict_contains(commands, cmd))
        cmds = #[[this(), commands[cmd]]];
    for def in (parents() + modules) {
        if ((c = def.command_cache()) && dict_contains(c, cmd))
            cmds = dict_add(cmds, def, c[cmd]);
    }
    if (!cmds)
        return 0;
    for def in (cmds) {
        if ((def[1]) in parents())
            p = this();
        else
            p = def[1];
        for command in (def[2]) {
            if (!(info = (command[2]).command_info('local, command[1])))
                continue;
            for cdef in (info) {
                if ((m = match_template(args, cdef[2])) != 0)
                    matched += [[listlen(m), [str, cmd, @m], p, @sublist(cdef, 3)]];
            }
            templates = union(templates, info.slice(3));
            refresh();
        }
    }
    if (matched) {
        info = [matched[1]];
        matched = delete(matched, 1);
        for m in (matched) {
            if ((m[1]) > ((info[1])[1]))
                info = [m];
            else if ((m[1]) == ((info[1])[1]))
                info += [m];
        }
        return ['command, info];
    }
    if (!templates)
        return 0;
    return ['partial, templates];
};

public method .rehash_cache() {
    var cmd, obj, part, element, info;
    
    (> .perms(sender()) <);
    (| .purge_cache() |);
    if (!(.is_general_cache())) {
        // if we are not an official cache, just cache commands we define
        commands = #[];
        for cmd in (.local_commands()) {
            for part in (cmd[2])
                .add_to_cache(part[1], this());
        }
        shortcuts = (.shortcuts()).to_list();
    } else {
        // otherwise cache all defined commands
        if ((info = .all_local_commands())) {
            for element in (info) {
                [obj, element] = element;
                for part in (element)
                    .add_to_cache(part[1], obj);
            }
        }
        shortcuts = .all_shortcuts();
    }
};

root method .core_command_cache() {
    .purge_cache();
};

public method .purge_cache() {
    (caller() == definer()) || (> .perms(sender()) <);
    (| clear_var('commands) |) || (commands = 0);
    (| clear_var('shortcuts) |) || (shortcuts = 0);
};

root method .uninit_command_cache() {
    var m;
    
    (| .purge_cache() |);
    for m in (modules || [])
        m.cache_server_uninit();
};

public method .shortcut_cache() {
    return shortcuts;
};

public method .command_cache() {
    return commands;
};

public method .command_modules() {
    arg @args;
    
    return modules || [];
};

public method .match_remote_command() {
    arg str, cmd, args;
    var command, m, matched, templates, info, cdef, def, cmds, c;
    
    if (this() != $remote_cache)
        throw(~perm, "This should only be used on $remote_cache");
    templates = (matched = []);
    if (commands && dict_contains(commands, cmd))
        cmds = commands[cmd];
    else
        return 0;
    for command in (cmds) {
        if (!(info = (command[2]).command_info('remote, command[1])))
            continue;
        for cdef in (info) {
            if ((m = match_template(args, cdef[2])) != 0)
                matched += [[listlen(m), command[2], [str, cmd, @m], @sublist(cdef, 3)]];
        }
        templates = union(templates, info.slice(3));
        refresh();
    }
    if (matched)
        return ['remote, matched];
    if (!templates)
        return 0;
    return ['partial, templates];
};

public method .parse_command_module() {
    arg value, action, @args;
    
    value = (> $object_lib.to_dbref(value) <);
    if (!(value.is($user_interfaces)))
        throw(~failed, (value.namef('ref)) + " is not a child of $user_interfaces");
    if (!('general_cache in (value.flags())))
        throw(~failed, (value.namef('ref)) + " is not set as a general cache");
    if (action == 'del) {
        if (!(value in modules))
            throw(~failed, ("The module '" + value) + "' is not set, and thus cannot be removed");
        return value;
    }
    return value;
};


new object $remote_cache: $command_cache;

var $root manager = $remote_cache;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874702845;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $root inited = 1;
var $command_cache modules = [];
var $root managed = [$remote_cache];
var $command_cache commands = 0;

public method .rehash_cache() {
    var def, cmd;
    
    (> .perms(sender()) <);
    
    // oof, this is big and nasty.  We will need to pick through the
    // whole db to find all remotely defined commands.  Dont do this
    // often--it should keep itself up to date when they are added
    // or removed.
    for def in ($has_commands.descendants()) {
        for cmd in ((def.remote_commands()).keys())
            .add_to_cache(cmd, def);
        refresh();
    }
};

public method .del_remote_command() {
    arg @args;
    
    if (caller() != $has_commands)
        throw(~perm, "Only $has_commands may call this method.");
    return .del_from_cache(@args);
};

public method .add_remote_command() {
    arg @args;
    
    if (caller() != $has_commands)
        throw(~perm, "Only $has_commands may call this method.");
    return .add_to_cache(@args);
};


new object $user_interfaces: $command_cache;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $has_commands shortcuts = #[];
var $command_cache modules = [];
var $root manager = $user_interfaces;
var $root managed = [$user_interfaces];
var $user_interfaces links = 0;
var $command_cache shortcuts = 0;
var $command_cache commands = 0;


new object $mail_list: $mail_root, $has_name;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables, 'fertile];
var $has_name name = ['uniq, "mail_list", "the mail_list"];
var $mail_list notify = [];
var $mail_list last_received_on = 0;
var $mail_list senders = [];
var $mail_list mail = [];
var $mail_list readers = [];
var $root trusted_by = [$mail_db];
var $root manager = $mail_list;
var $root managed = [$mail_list];
var $root defined_settings = #[["inet-list", #[['parse, ['parse_inet_list_setting]]]], ["mail-readers", #[['get, ['get_maillist_setting]], ['set, ['set_maillist_setting]], ['parse, ['parse_maillist_setting]], ['format, ['fmt_maillist_setting]]]], ["mail-senders", #[['get, ['get_maillist_setting]], ['set, ['set_maillist_setting]], ['parse, ['parse_maillist_setting]], ['format, ['fmt_maillist_setting]]]], ["mail-notify", #[['get, ['get_maillist_setting]], ['set, ['set_maillist_setting]], ['parse, ['parse_maillist_setting]], ['format, ['fmt_maillist_setting]]]]];
var $root settings = #[["inet-list", ""]];
var $root help_node = $help_obj_mail_list;

public method .del_sender_from_notification() {
    var who;
    
    who = sender();
    if (!(who.has_ancestor($user)))
        throw(~type, "Sender is not a user.");
    if (!(.has_flag('sender, who)))
        throw(~perm, ((who.name()) + " cannot read ") + (.mail_name()));
    notify = notify.setremove(who);
};

public method .add_sender_to_notification() {
    var who;
    
    if (caller() != $mail_ui)
        throw(~perm, "Permission Denied");
    who = sender();
    if (!(who.has_ancestor($user)))
        throw(~type, "Sender is not a user.");
    if (!(.list_is_readable_by(who)))
        throw(~perm, ((who.name()) + " cannot read ") + (.mail_name()));
    notify = setadd(notify, who);
};

public method .list_is_sendable_by() {
    arg who;
    
    if (.is_writable_by(who))
        return 1;
    if (type(senders) == 'list)
        return who in senders;
    return senders;
};

public method .list_is_readable_by() {
    arg who;
    
    if (.is_writable_by(who))
        return 1;
    if (type(readers) == 'list)
        return who in readers;
    return readers;
};

public method .set_name() {
    arg new_name, @args;
    var old_name;
    
    old_name = .name('noarticle);
    if (new_name && ((new_name[1]) == "*"))
        new_name = new_name.subrange(2);
    (> pass(new_name, @args) <);
    (| $mail_db.key_changed(old_name, new_name) |);
};

public method .start() {
    if (!(.list_is_readable_by(sender())))
        throw(~perm, ("Sender cannot read " + (.mail_name())) + ".");
    if (mail)
        return mail[1];
    return 0;
};

public method .last_received_on() {
    return last_received_on;
};

public method .recent_mail() {
    arg @diff;
    
    if (!(.list_is_readable_by(sender())))
        throw(~perm, ("Sender cannot read " + (.mail_name())) + ".");
    [(diff ?= 20)] = diff;
    if ((mail.length()) < diff)
        return [0, mail];
    return [((mail.length()) - diff) - 1, mail.subrange((mail.length()) - diff)];
};

public method .set_notify() {
    arg new_value;
    
    (> .perms(sender(), 'manager) <);
    if ((type(new_value) != 'integer) && (type(new_value) != 'list))
        throw(~type, "new value must be submitted as a list of users or boolean integer.");
    notify = new_value;
};

public method .set_senders() {
    arg new_value;
    
    (> .perms(sender(), 'manager) <);
    if ((type(new_value) != 'integer) && (type(new_value) != 'list))
        throw(~type, "new value must be submitted as a list of users or boolean integer.");
    senders = new_value;
};

public method .notify() {
    (> .perms(sender(), 'manager) <);
    return notify;
};

public method .del_mail() {
    arg old_mail, @reason;
    
    [(reason ?= 0)] = reason;
    if ((caller() == $mail_message) && (reason == 'mail_destroyed)) {
        // being called by $mail_message.uninit_mail_message()
    } else if (sender() == this()) {
        // this is ok too
    } else if (caller() == $pop3_interface) {
        // so is this--ugh, hardcoding
    } else if ((!(| old_mail.perms(sender()) |)) && (!(| .perms(sender()) |))) {
        throw(~perm, ((sender().namef('ref)) + " cannot remove mail from ") + (.mail_name()));
    }
    if (old_mail == (mail.last()))
        last_received_on = (| (mail[(mail.length()) - 1]).time() |) || 0;
    (| old_mail.del_recipient(this()) |);
    mail = mail.del(old_mail);
};

protected method ._announce_new_mail() {
    arg new_mail;
    var line, who, n;
    
    if (!notify)
        return;
    line = ((((.mail_name()) + " has been sent new mail by ") + ((new_mail.from()).name())) + ": ") + (new_mail.subject());
    for who in (notify)
        (| who.tell(line.chop(who.linelen())) |);
};

public method .mail() {
    //  if (!.list_is_sendable_by(sender()))
    //      throw(~perm, "Sender cannot read " + .mail_name() + ".");
    return mail;
};

public method .add_mail() {
    var new_mail;
    
    (> .perms(caller(), $mail_message) <);
    last_received_on = time();
    new_mail = sender();
    
    // make sure we do not already have it
    if (new_mail in mail)
        return;
    
    // add it
    mail = mail.add(new_mail);
    ._announce_new_mail(new_mail);
};

public method .senders() {
    (> .perms(sender(), 'manager) <);
    return senders;
};

public method .mail_name() {
    return $mail_lib.mail_name(this());
};

root method .init_mail_list() {
    mail = [];
    senders = 1;
    if (!(.has_ancestor($user))) {
        readers = 1;
        notify = [];
        (| $mail_db.insert(.name(), this()) |);
    } else {
        readers = [.manager()];
        notify = [.manager()];
    }
};

root method .uninit_mail_list() {
    var m;
    
    for m in (mail)
        .del_mail(m);
    mail = [];
    senders = 1;
    readers = [.manager()];
    notify = [];
    if (!(.has_ancestor($user)))
        (| $mail_db.remove(.name()) |);
    $smtp.remove_aliases();
};

public method .mail_list_next() {
    arg cur;
    
    if (!(.list_is_readable_by(sender())))
        throw(~perm, "Sender cannot read this list.");
    return (> mail[(cur in mail) + 1] <);
};

public method .mail_list_prev() {
    arg cur;
    
    if (!(.list_is_readable_by(sender())))
        throw(~perm, "Sender cannot read this list.");
    return (> mail[(cur in mail) - 1] <);
};

public method .notify_bad_mail() {
    arg badmail;
    
    // this is a hack, we shouldn't ever get bad mail if things worked right
    (> .perms(caller(), $mail_ui) <);
    mail = setremove(mail, badmail);
};

root method .core_mail_list() {
    var o;
    
    if (type(senders) == 'list)
        senders = filter o in (senders) where (valid(o));
    if (type(notify) == 'list)
        notify = filter o in (notify) where (valid(o));
    if (type(readers) == 'list)
        readers = filter o in (readers) where (valid(o));
};

public method .list_is_inet() {
    return (.get_setting("inet-list", $mail_list)) ? 1 : 0;
};

public method .parse_inet_list_setting() {
    arg value, @args;
    
    if (!($sys.is_system(user())))
        throw(~nope, "Only administrators can set internet mail list proxies.");
    return value;
};

public method .get_maillist_setting() {
    arg name, definer;
    
    name = tosym(substr(name, 6));
    if ((name == 'readers) || ((name == 'senders) || (name == 'notify)))
        return get_var(name);
    throw(~perm, "Permission Denied");
};

protected method .set_maillist_setting() {
    arg name, definer, value;
    var action;
    
    name = tosym(substr(name, 6));
    [action, value] = value;
    if ((name != 'readers) && ((name != 'senders) && (name != 'notify)))
        throw(~perm, "Permission Denied");
    switch (action) {
        case 'set:
            set_var(name, value);
        case 'add:
            set_var(name, setadd(get_var(name), value));
        case 'del:
            set_var(name, setremove(get_var(name), value));
    }
};

public method .parse_maillist_setting() {
    arg value;
    var action, list, item, out;
    
    value = value.trim();
    if (value.is_positive())
        return ['set, 1];
    else if ((value.is_negative()) || (value == "writers"))
        return ['set, 0];
    if (value && ((value[1]) in ["+", "-"])) {
        if ((value[1]) == "-")
            action = 'del;
        else
            action = 'add;
        list = [substr(value, 2)];
    } else {
        action = 'set;
        list = value.explode_english_list();
    }
    out = [];
    for item in (list)
        out += [(> $object_lib.to_dbref(item) <)];
    if (action == 'set)
        return [action, out];
    else
        return [action, out[1]];
};

public method .fmt_maillist_setting() {
    arg data;
    
    if (type(data) == 'list)
        return join(data, ", ");
    else if (data)
        return "anybody";
    else
        return "writers";
};


new object $mail_ui: $mail_list, $user_interfaces;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $mail_ui subscribed = #[];
var $mail_ui current = 0;
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list senders = 1;
var $mail_list readers = [];
var $mail_list notify = [$mail_ui];
var $mail_list last_letter = 0;
var $mail_list mail = [];
var $has_commands local = #[["@sub?scribed", [["@sub?scribed", "*", "@sub?scribed <any>", 'subscribe_cmd, #[[1, ['any, []]]]]]], ["@unsub?scribed", [["@unsub?scribed", "*", "@unsub?scribed <any>", 'unsubscribe_cmd, #[[1, ['any, []]]]]]], ["@mail-list?s", [["@mail-list?s", "", "@mail-list?s", 'mail_lists_cmd, #[]]]], ["@read", [["@read", "*", "@read <any>", 'mail_read_cmd, #[[1, ['any, []]]]]]], ["@remove-m?ail|@rmm?ail", [["@remove-m?ail|@rmm?ail", "*", "@remove-m?ail|@rmm?ail <any>", 'mail_remove_cmd, #[[1, ['any, []]]]]]], ["@mail", [["@mail", "*", "@mail <any>", 'mail_on_cmd, #[[1, ['any, []]]]]]], ["@reply", [["@reply", "*", "@reply <any>", 'reply_cmd, #[[1, ['any, []]]]]]], ["@send", [["@send", "*", "@send <any: +e?dit>", 'send_to_cmd, #[[1, ['any_opt, ["e?dit"]]]]]]], ["@nn|@next-new", [["@nn|@next-new", "*", "@nn|@next-new <any>", 'next_new_cmd, #[[1, ['any, []]]]]]]];
var $has_commands shortcuts = #[];
var $has_name name = ['prop, "Mail User Interface", "Mail User Interface"];
var $root manager = $mail_ui;
var $root managed = [$mail_ui];
var $root help_node = $help_mail;
var $root defined_settings = #[["@send-editor", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $root settings = #[["@send-editor", 1]];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;

protected method .send_to_cmd() {
    arg cmdstr, cmd, str;
    var subj, lists, note, list, x, mail, text, args, edit;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template((str[1]).join(" "), "* to *"))) {
        note = args[1];
        args = args[3];
    } else {
        note = "";
        args = (str[1]).join(" ");
    }
    if (args) {
        if (!(lists = .parse_mail_recipient_list(args)))
            return "No (valid) lists specified.";
    } else {
        lists = [current['list]];
        .tell(("No recipient specified, using current recipient (" + ((lists[1]).mail_name())) + ")");
    }
    edit = "e?dit" in ((str[2]).slice(1));
    edit = edit ? (((str[2])[edit])[3]) : (.get_setting("@send-editor", $mail_ui));
    
    // get the text of the message
    if ((!note) && edit) {
        if (.active_editor()) {
            .tell("Storing active editor..");
            .store_editor();
        }
        subj = "";
        text = [];
        (> .invoke_editor(this(), '_edit_mail_callback, text, ['mail, lists, subj, 0, 0]) <);
        if (.active_editor()) {
            .tell(("Editor invoked with " + ((.active_editor()).session_name())) + ".");
            .tell("Type 'help' for available commands.");
        }
    } else {
        if (note) {
            text = (> (.match_env_nice(note)).get_raw_text() <);
        } else {
            text = .read("-- Enter text for mail message, \".\" when done or \"@abort\" to abort --");
            if (text == 'aborted)
                return;
            if (text == 'engaged)
                return "** Already reading - mail send aborted **";
        }
        subj = (> .prompt("Subject: ") <);
        mail = $mail_message.new_mail();
        mail.set_subject(subj);
        mail.set_text(text);
        catch any
            mail.send(@lists);
        with
            return (traceback()[1])[2];
        return "Mail sent.";
    }
};

protected method .mail_read_cmd() {
    arg cmdstr, cmd, str;
    var mail, m, args, opts, lname, list, rng, args, meta;
    
    (> .perms(caller(), 'command) <);
    [args, opts] = (> $parse_lib.opt(str, "m?eta") <);
    str = args.join(" ");
    meta = [];
    if ((m = "m?eta" in (opts.slice(1)))) {
        if ((opts[m])[3])
            meta = [1];
    }
    if ((args = match_template(str, "* on *"))) {
        rng = args[1];
        catch ~listnf, ~ambig {
            list = (> $mail_lib.match_mail_recipient(args[3]) <);
        } with {
            if (error() == ~listnf) {
                return (traceback()[1])[2];
            } else {
                // error == ~ambig
                return ((("The list '" + (args[3])) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".";
            }
        }
    } else {
        rng = str;
        list = current['list];
    }
    catch ~perm
        (> .new_list(list) <);
    with
        return (traceback()[1])[2];
    if (((list.mail()).length()) == 0)
        return ("There is no mail on " + (list.mail_name())) + ".";
    if (!rng)
        return ("You must specify a message to read on " + (list.mail_name())) + ".";
    catch ~range {
        if (rng == "next") {
            .read_mail((> list.mail_list_next((subscribed[list])[2]) <), list, @meta);
        } else if (rng == "prev") {
            .read_mail((> list.mail_list_prev((subscribed[list])[2]) <), list, @meta);
        } else {
            for m in ($mail_lib.range_to_actual($parse_lib.range(rng), current))
                .read_mail(m, list, @meta);
        }
    } with {
        return ((("Mail message " + rng) + " does not exist on ") + (list.mail_name())) + ".";
    }
};

protected method .mail_remove_cmd() {
    arg cmdstr, cmd, str;
    var mail, args, lmail, list, rng, m, x, name, lname, offset, ans;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "* on|from *"))) {
        rng = args[1];
        list = args[3];
    } else if (!str) {
        return "You must specify a message and list.";
    } else {
        // grr, be hacky
        args = explode(str);
        if ((args.length()) > 1) {
            list = args.last();
            if (!(| $mail_lib.match_mail_recipient(list) |)) {
                rng = str;
                list = "";
            } else {
                rng = (args.delete(args.length())).join();
            }
        } else {
            rng = str;
            list = "";
        }
    }
    if (!rng)
        return ("You must specify a message to remove from " + lname) + ".";
    if (!list) {
        list = current['list];
        ans = (> .prompt(((("Remove mail " + rng) + " from ") + (list.mail_name())) + "?  ") <);
        if (match_regexp(ans, "no|n"))
            return "Ok, aborting..";
    } else {
        catch ~listnf, ~ambig {
            list = (> $mail_lib.match_mail_recipient(list) <);
        } with {
            if (error() == ~listnf)
                return (traceback()[1])[2];
            else
                return ((("The list '" + list) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".";
        }
    }
    lname = list.mail_name();
    catch any
        (> .new_list(list) <);
    with
        return (traceback()[1])[2];
    if (rng == "$") {
        mail = (> $mail_lib.range_to_actual(['end, 'single], current) <);
    } else if (rng && ((rng[1]) == "$")) {
        catch ~namenf
            mail = [(> $object_lib.to_dbref(rng) <)];
        with
            return (traceback()[1])[2];
    } else {
        catch ~range
            mail = (> $mail_lib.range_to_actual($parse_lib.range(rng), current) <);
        with
            return (traceback()[1])[2];
    }
    lmail = list.mail();
    if ((mail[1]) != (| lmail[1] |)) {
        offset = (mail[1]) in lmail;
        lmail = sublist(lmail, offset);
        offset--;
    }
    for m in (mail) {
        catch ~perm {
            x = (m in lmail) + offset;
            name = ((((("#" + x) + " \"") + (m.subject())) + "\" (") + m) + ")";
            list.del_mail(m);
            .tell(((("Removed message " + name) + " from ") + (list.mail_name())) + ".");
        } with {
            .tell((traceback()[1])[2]);
        }
    }
};

protected method .read_mail() {
    arg mail, list, @metainfo;
    var loc, out;
    
    loc = mail in (list.mail());
    out = $ctext_frob.new_with([strfmt("Message %l (%l) on %s:", loc, mail.name(), list.mail_name())]);
    .tell(out.append(mail.format(@metainfo)));
    mail.did_read();
    if (subscribed.contains(list))
        subscribed = subscribed.add(list, [time(), mail]);
};

protected method .subscribed() {
    return subscribed;
};

protected method .unsubscribe_cmd() {
    arg cmdstr, cmd, str;
    var list, line, mname;
    
    (> .perms(caller(), 'command) <);
    if (!str)
        return .mail_lists_cmd();
    catch ~listnf, ~ambig {
        list = (> $mail_lib.match_mail_recipient(str) <);
    } with {
        if (error() == ~listnf)
            return (traceback()[1])[2];
        else
            return ((("The list '" + str) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".";
    }
    if (list == this())
        return "You cannot unsubscribe yourself.";
    mname = list.mail_name();
    if (!(list in (subscribed.keys())))
        return "You are not subscribed to " + mname;
    .unsubscribe(list);
    return ("Successfully unsubscribed from " + mname) + ".";
};

protected method .subscribe_cmd() {
    arg cmdstr, cmd, str;
    var list, mname, l, args, line, len, out;
    
    (> .perms(caller(), 'command) <);
    
    // this is ugly bad bad
    args = (> $parse_lib.opt(str, "n?ew") <);
    if (!(args[1])) {
        if ("n?ew" in ((args[2]).slice(1))) {
            out = [];
            for l in ((subscribed.keys()).setremove(this())) {
                if ((l.last_received_on()) > ((subscribed[l])[1]))
                    out += ["  " + (l.mail_name())];
            }
            if (out)
                .tell(["New mail on:"] + out);
            else
                .tell(["No new mail on the lists you are subscribed to."]);
            return;
        }
        .tell("Currently Subscribed Lists:");
        len = (.linelen()) / 3;
        for l in ((subscribed.keys()).setremove(this())) {
            if (!valid(l)) {
                subscribed = dict_del(subscribed, l);
            } else {
                line = "  " + (l.mail_name());
                if ((l.last_received_on()) > ((subscribed[l])[1]))
                    line += " (new mail)";
                .tell(line);
            }
        }
        .tell("---");
        return;
    }
    catch ~listnf, ~ambig {
        list = $mail_lib.match_mail_recipient(str);
    } with {
        if (error() == ~listnf)
            return (traceback()[1])[2];
        else
            return ((("The list '" + str) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".";
    }
    mname = $mail_lib.mail_name(list);
    if (list in (subscribed.keys()))
        return .tell(("You are already subscribed to " + mname) + ".");
    if (!(list.list_is_readable_by(this())))
        return .tell(mname + " is not subscribeable by you.");
    .subscribe(list);
    .tell(("Successfully subscribed to " + mname) + ".");
};

protected method .subscribe() {
    arg list;
    
    if (!subscribed)
        subscribed = #[];
    subscribed = subscribed.add(list, [time(), 0]);
    (| list.add_sender_to_notification() |);
};

protected method .unsubscribe() {
    arg list;
    
    subscribed = subscribed.del(list);
    (| list.del_sender_from_notification() |);
};

protected method .mail_lists_cmd() {
    arg @args;
    var l, output;
    
    if (caller() != $mail_ui)
        (> .perms(caller(), 'command) <);
    output = map l in (($mail_db.database()).values()) to ($cml_lib.format_tr_tag($cml_lib.format_td_tag(l.mail_name()), $cml_lib.format_td_tag(dict_contains(subscribed, l) ? "[subscribed]" : " "), $cml_lib.format_td_tag((l.list_is_sendable_by(this())) ? "[sendable]" : " "), $cml_lib.format_td_tag((l.list_is_readable_by(this())) ? "[readable]" : " ")));
    return $ctext_frob.new_with(["All Available Mail Lists:", $cml_lib.format_table_tag("53%,17%,15%,15%", @output), $cml_lib.format_sep_tag()]);
};

protected method .new_list() {
    arg list;
    
    // check here so we can assume later that this error will not bite us
    if (!(list.list_is_readable_by(this())))
        throw(~perm, "You cannot read mail on " + (list.mail_name()));
    
    // set the current list
    if (list != (current['list]))
        current = current.add('list, list);
};

root method .init_mail_ui() {
    current = #[['list, this()]];
    .subscribe(this());
    .new_list(this());
    (| .subscribe($mail_list_news) |);
    
    // now change the 'news' subscription so it notifies them NOW
    subscribed = subscribed.add($mail_list_news, [0, 0]);
};

protected method .mail_on_cmd() {
    arg cmdstr, cmd, str;
    var args, lmail, mail, rng, start, end, line, list, len, out, m, rows, o, from, subj, now_read;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "* on *"))) {
        rng = args[1];
        list = args[3];
    } else if (match_template(str, "* to *")) {
        return "Please use the @send command instead.";
    } else {
        rng = "";
        list = str;
    }
    if (!list) {
        list = current['list];
    } else {
        catch ~listnf, ~perm, ~ambig, ~objnf {
            list = (> $mail_lib.match_mail_recipient(list) <);
            (> .new_list(list) <);
        } with {
            if (error() == ~ambig)
                return ((("The list '" + list) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".";
            else
                return (traceback()[1])[2];
        }
    }
    if (!rng) {
        mail = list.mail();
        end = mail.length();
    
        // minus two for the head and tail
        rows = (.get_rows()) - 2;
        if (end > rows) {
            if (0 == (| ((.subscribed())[list])[2] |)) {
                now_read = 1;
            } else {
                now_read = 1;
                for m in (mail) {
                    if (m == (| ((.subscribed())[list])[2] |))
                        break;
                    else
                        now_read++;
                }
            }
            if ((now_read + rows) > end)
                start = end - rows;
            else if (now_read > (rows / 2))
                start = now_read - (rows / 2);
            else
                start = 1;
            end = (start + rows) - 1;
            mail = sublist(mail, start, rows);
        } else {
            start = 1;
        }
        rng = (start + "-") + end;
    } else {
        catch ~range
            mail = $mail_lib.range_to_actual($parse_lib.range(rng), current);
        with
            return (traceback()[1])[2];
    }
    if (!mail)
        return "No mail on " + (list.mail_name());
    len = (.linelen()) - 36;
    out = [((("Mail from " + rng) + " on ") + (list.mail_name())) + ":"];
    lmail = list.mail();
    o = [];
    for m in (mail) {
        if (!valid(m)) {
            list.notify_bad_mail(m);
        } else {
            from = $object_lib.get_name(m.from(), 'name);
            if ((args = regexp(from, "<([^>]+)>")))
                from = explode(args[1], "@")[1];
            subj = m.subject();
            subj = strsed(subj, "^\[[^]]+\] *", "");
            o += [$cml_lib.format_tr_tag($cml_lib.format_td_tag((m == (| (subscribed[list])[2] |)) ? "=>" : " "), $cml_lib.format_td_tag(m in lmail), $cml_lib.format_td_tag((m.has_read(this())) ? " " : "!"), $cml_lib.format_td_tag(subj), $cml_lib.format_td_tag(from), $cml_lib.format_td_tag(m.lines()), $cml_lib.format_td_tag($time.format("%d-%h-%Y", m.time())))];
        }
    }
    return $ctext_frob.new_with((out + [$cml_lib.format_table_tag("5%,5%,2%,50%,17%,5%,15%", o)]) + [$cml_lib.format_sep_tag()]);
};

protected method .next_new_cmd() {
    arg cmdstr, cmd, str;
    var mail, list, keys, start;
    
    (> .perms(caller(), 'command) <);
    str = strsed(str, "^ *on +", "");
    if (str) {
        catch any {
            list = (> $mail_lib.match_mail_recipient(str) <);
        } with {
            if (error() == ~ambig)
                return ((("The list '" + str) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".";
            else
                return (traceback()[1])[2];
        }
        .new_list(list);
        mail = (| list.mail_list_next((subscribed[list])[2]) |);
        while (mail && (mail.has_read(this()))) {
            refresh();
            mail = (| list.mail_list_next(mail) |);
        }
        if (!mail)
            return ("No new mail on " + ($mail_lib.mail_name(list))) + ".";
        .read_mail(mail, list);
    } else {
        keys = dict_keys(subscribed);
        if (!keys)
            return "You are not subscribed to any lists.";
        if (!((current['list]) in keys))
            current = current.add('list, keys[1]);
        start = (list = current['list]);
        while (1) {
            // anything left on this list?
            mail = (| list.mail_list_next((subscribed[list])[2]) |);
            while (mail && (mail.has_read(this()))) {
                refresh();
                mail = (| list.mail_list_next(mail) |);
            }
            if (mail)
                break;
    
            // pick a new list
            catch any
                list = (> keys[(list in keys) + 1] <);
            with
                list = (| keys[1] |);
    
            // die?
            if ((!list) || (list == start))
                return "No new mail.";
        }
        .new_list(list);
        .read_mail(mail, list);
    }
};

root method .uninit_mail_ui() {
    var l;
    
    for l in ((subscribed || #[]).keys())
        (| .unsubscribe(l) |);
};

public method .old_mail_lists_cmd() {
    arg @args;
    var l, line;
    
    if (caller() != $mail_ui)
        (> .perms(caller(), 'command) <);
    for l in (($mail_db.database()).values()) {
        line = "";
        if (l.list_is_readable_by(this()))
            line = "[Readable]";
        if (l.list_is_sendable_by(this()))
            line = ("[Sendable]" + (line ? " " : "")) + line;
        .tell((((l.mail_name()).pad(((.linelen()) - (line.length())) - 1)) + " ") + line);
    }
};

public method .old_mail_on_cmd() {
    arg cmdstr, cmd, str;
    var args, lmail, mail, rng, start, end, line, list, len, out, m, rows;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "* on *"))) {
        rng = args[1];
        list = args[3];
    } else if (match_template(str, "* to *")) {
        return (> .send_to_cmd(cmdstr, cmd, str) <);
    } else {
        rng = "";
        list = str;
    }
    if (!list) {
        list = current['list];
    } else {
        catch ~listnf, ~perm {
            list = (> $mail_lib.match_mail_recipient(list) <);
            (> .new_list(list) <);
        } with {
            return (traceback()[1])[2];
        }
    }
    if (!rng) {
        mail = list.mail();
        end = mail.length();
    
        // minus two for the head and tail
        rows = (.get_rows()) - 2;
        if (end > rows) {
            start = end - rows;
            mail = sublist(mail, start);
        } else {
            start = 1;
        }
        rng = (start + "-") + end;
    } else {
        catch ~range
            mail = $mail_lib.range_to_actual($parse_lib.range(rng), current);
        with
            return (traceback()[1])[2];
    }
    if (!mail)
        return "No mail on " + (list.mail_name());
    len = (.linelen()) - 36;
    out = [((("Mail from " + rng) + " on ") + (list.mail_name())) + ":"];
    lmail = list.mail();
    for m in (mail) {
        if (!valid(m))
            list.notify_bad_mail(m);
        else
            out += [strfmt("%s%3r:%s%*L %12L%5l%11l", (m == (| (subscribed[list])[2] |)) ? "=>" : "  ", m in lmail, (m.has_read(this())) ? " " : "!", len, m.subject(), $object_lib.get_name(m.from(), 'name), m.lines(), $time.format("%d-%h-%Y", m.time()))];
    }
    .tell(out + ["------"]);
};

public method .old_read_mail() {
    arg mail, list;
    var loc;
    
    loc = mail in (list.mail());
    .tell(strfmt("Message %l (%l) on %s:", loc, mail.name(), list.mail_name()));
    .tell(mail.format());
    mail.did_read();
    subscribed = subscribed.add(list, [time(), mail]);
};

protected method .reply_cmd() {
    arg cmdstr, cmd, str;
    var list, msg, args, i, subj, text, recip;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "to *")))
        str = args[2];
    if ((args = match_template(str, "* on *")))
        [msg, str, list] = args;
    else
        msg = str;
    if (!list) {
        list = current['list];
    } else {
        catch ~listnf, ~perm, ~ambig {
            list = (> $mail_lib.match_mail_recipient(list) <);
            (> .new_list(list) <);
        } with {
            if (error() == ~ambig)
                return ((("The list '" + list) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".";
            else
                return (traceback()[1])[2];
        }
    }
    if (!msg) {
        if (!valid((msg = (| (subscribed[list])[2] |))))
            return "No current message to reply to.";
    } else {
        catch ~range
            msg = $mail_lib.range_to_actual($parse_lib.range(msg), current);
        with
            return (traceback()[1])[2];
        msg = msg[1];
    }
    i = msg in (list.mail());
    if (list.is($user))
        recip = msg.from();
    else
        recip = list;
    if (!(recip.is($mail_list)))
        return (list.namef('ref)) + " is not a valid mail recipient.";
    .tell(((("Replying to message " + i) + " on ") + (list.mail_name())) + ".");
    text = msg.body();
    if (text == ["", "(no message)", ""])
        text = [];
    text = $mail_lib.indent_reply(text);
    text = [((("On " + ($time.format("%d-%b-%Y", msg.time()))) + " ") + ((msg.from()).namef('ref))) + " said: "] + text;
    if (.active_editor()) {
        .tell("Storing active editor..");
        .store_editor();
    }
    subj = msg.subject();
    if (!(subj.match_begin("Re:")))
        subj = "Re: " + subj;
    (> .invoke_editor(this(), '_edit_mail_callback, text, ['mail, [recip], subj, i, msg]) <);
    if (.active_editor()) {
        .tell(("Editor invoked with " + ((.active_editor()).session_name())) + ".");
        .tell("Type 'help' for available commands.");
    }
};

protected method .parse_mail_recipient_list() {
    arg str;
    var recip, lists;
    
    lists = [];
    for recip in (str.explode_english_list()) {
        catch ~listnf, ~ambig {
            recip = (> $mail_lib.match_mail_recipient(recip) <);
            if (recip.list_is_sendable_by(this()))
                lists += [recip];
            else
                .tell("You cannot send to " + (recip.mail_name()));
        } with {
            if (error() == ~listnf)
                .tell(("The recipient \"" + recip) + "\" is invalid.");
            else
                .tell(((("The list '" + recip) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".");
        }
    }
    return lists;
};


new object $location: $physical, $command_cache;

var $location contents = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $described prose = [];
var $has_name name = ['uniq, "Generic Container Object", "the Generic Container Object"];
var $command_cache modules = [];
var $has_commands shortcuts = #[];
var $root manager = $location;
var $root managed = [$location];

root method .init_location() {
    contents = [];
};

root method .uninit_location() {
    var obj;
    
    for obj in (contents)
        (| obj.eject() |);
};

public method .contents() {
    return contents || [];
};

public method .contains() {
    arg obj;
    
    return (obj in (.contents())) ? 1 : 0;
};

public method .find_in_contents() {
    arg str;
    var obj;
    
    for obj in (.contents()) {
        if (obj.match_name(str))
            return obj;
    }
    return 0;
};

public method .will_arrive() {
    arg mover, old_place;
    
    if (caller() != $located)
        throw(~perm, "Caller is not $located.");
};

public method .will_leave() {
    arg mover, place;
    
    if (caller() != $located)
        throw(~perm, "Caller is not $located.");
};

public method .did_arrive() {
    arg mover, place;
    
    if (caller() != $located)
        throw(~perm, "Caller is not $located.");
};

public method .did_leave() {
    arg mover, place;
    
    if (caller() != $located)
        throw(~perm, "Caller is not $located.");
};

public method .add_sender_to_contents(): nooverride {
    if (caller() != $located)
        throw(~perm, "Caller is not $located.");
    if ((sender().location()) != this())
        throw(~location, "Sorry, but you're not here.");
    contents = setadd(contents, sender());
};

public method .del_sender_from_contents() {
    if (caller() != $located)
        throw(~perm, "Caller not an agent of located protocol.");
    contents = setremove(contents, sender());
};

public method .validate_contents() {
    var obj, newcont;
    
    if (!(.is_writable_by(sender())))
        throw(~perm, "Must be a writer to validate contents");
    newcont = [];
    for obj in (contents) {
        if (valid(obj) && ((obj.has_ancestor($located)) && ((obj.location()) == this())))
            newcont = newcont.setadd(obj);
    }
    contents = newcont;
};

public method .environment() {
    return [this()] + contents;
};

public method .add_to_contents(): nooverride {
    arg what;
    
    if (caller() != $located)
        throw(~perm, "Caller is not $located.");
};

public method .contents_accept_mail() {
    return 1;
};

public method .realm() {
    arg @args;
    var loc;
    
    loc = "";
    if ((| .location() |))
        loc = (.location()).realm();
    return ((loc + "[") + (.name())) + "]";
};

public method .realm_name() {
    return "";
};

public method .add_frob_to_contents() {
    arg frob;
    
    if (!(sender().is($thing_frob)))
        throw(~perm, "Caller is not $thing_frob.");
    if (type(frob) != 'frob)
        throw(~type, "Argument is not a frob.");
    if ((frob.location()) != this())
        throw(~location, "Sorry, but you're not here.");
    contents = (.contents()).setadd(frob);
};

public method .del_frob_from_contents() {
    arg frob;
    
    (sender().is($thing_frob)) || ((caller() != $foundation) && (> .perms(sender()) <));
    if (type(frob) != 'frob)
        throw(~type, "Argument not a frob.");
    contents = contents.setremove(frob);
};

public method .announce() {
    arg str, @except;
    var obj, part, s;
    
    if ((type(str) == 'frob) && ((class(str) == $message_frob) && (this() in (str.parts()))))
        str = str.change_entry(this(), "general");
    s = sender();
    for obj in (.contents()) {
        if (!(obj in except))
            (| obj.tell(str, s) |);
    }
};


new object $located_location: $thing, $location;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $location contents = [];
var $located location = $void;
var $located obvious = 1;
var $described prose = [];
var $has_name name = ['uniq, "Generic Located Location", "the Generic Located Location"];
var $command_cache modules = [];
var $has_commands remote = #[];
var $root manager = $located_location;
var $root managed = [$located_location];
var $thing gender = $gender_neuter;
var $command_cache shortcuts = 0;
var $command_cache commands = 0;

public method .environment() {
    return (.contents()) + pass();
};

public method .description() {
    arg flags;
    var desc, out, c;
    
    // type is either 'on' or 'in'
    if (!(flags.contains('type)))
        return (> pass(flags) <);
    out = [];
    for c in (.contents())
        out += [c.name()];
    return (> pass(flags) <) + [((((("There is " + (out.to_english())) + " ") + (flags['type])) + " ") + (.name())) + "."];
};

public method .will_arrive() {
    arg mover, old_place;
    
    (> pass(mover, old_place) <);
    if (sender() == (.location()))
        throw(~perm, ((sender().namef('ref)) + " is holding ") + (.namef('ref)));
};


new object $body: $located_location;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core, 'general_cache];
var $location contents = [];
var $located location = $void;
var $located obvious = 1;
var $body body_parts = #[];
var $body available_body_parts = 0;
var $body wearing = [];
var $body remote_command_cache = 0;
var $described prose = [];
var $has_name name = ['uniq, "Generic Body", "the Generic Body"];
var $body last_traceback = 0;
var $command_cache modules = [];
var $root manager = $body;
var $root managed = [$body];
var $body interaction = 0;
var $has_commands shortcuts = #[["|*", ['quote_cmd, ["quote ", 1]]], ["\"*", ['say_cmd, ["say ", 1]]], ["%*", ['think_cmd, ["think ", 1]]], ["!*", ['spoof_cmd, ["spoof ", 1]]], [",*,*", ['esay_cmd, ["esay ", 1, " with ", 2]]], [":*", ['emote_cmd, ["emote ", 1]]], [".*", ['pose_cmd, ["pose ", 1]]], ["''*", ['to_say_cmd, ["to ", "", " say ", 1]]], ["'* *", ['to_say_cmd, ["to ", 1, " say ", 2]]]];
var $has_commands local = #[["wh?isper", [["wh?isper", "* to *", "wh?isper <any> to <any>", 'whisper_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["say", [["say", "*", "say <any>", 'say_cmd, #[[1, ['any, []]]]]]], ["to", [["to", "* say *", "to <any> say <any>", 'to_say_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["emote", [["emote", "*", "emote <any>", 'emote_cmd, #[[1, ['any, []]]]]]], ["quote", [["quote", "*", "quote <any>", 'quote_cmd, #[[1, ['any, []]]]]]], ["spoof", [["spoof", "*", "spoof <any>", 'spoof_cmd, #[[1, ['any, []]]]]]], ["think", [["think", "*", "think <any>", 'think_cmd, #[[1, ['any, []]]]]]], ["pose", [["pose", "*", "pose <any>", 'pose_cmd, #[[1, ['any, []]]]]]], ["get|take", [["get|take", "*", "get|take <descendant of $thing>", 'get_cmd, #[[1, ['descendant, [$thing]]]]], ["get|take", "* from *", "get|take <any> from <descendant of $location>", 'get_from_cmd, #[[1, ['any, []]], [3, ['descendant, [$location]]]]]]], ["drop", [["drop", "*", "drop <descendant of $thing>", 'drop_cmd, #[[1, ['descendant, [$thing]]]]]]], ["give|put", [["give|put", "* to|in|on *", "give|put <descendant of $thing> to|in|on <descendant of $thing>", 'give_to_cmd, #[[1, ['descendant, [$thing]]], [3, ['descendant, [$thing]]]]]]]];
var $thing gender = $gender_neuter;
var $body actions = 0;
var $body last_command = 0;
var $command_cache shortcuts = 0;
var $command_cache commands = 0;

public method .tell() {
    arg @args;
    
};

public method .set_body_part() {
    arg part, frob, param;
    
    if (sender().has_ancestor($wearable))
        throw(~perm, "Sender must be $wearable.");
    body_parts = body_parts.add(frob.new_with(part, param));
};

public method .wearing() {
    arg @args;
    
    return wearing || [];
};

public method .body_parts() {
    return body_parts;
};

public method .namef() {
    arg type;
    var str;
    
    switch (type) {
        case 'doing, 'nactivity, 'activity, 'titled:
            return .name();
        default:
            return (> pass(type) <);
    }
};

public method .available_body_parts() {
    return available_body_parts || ['head, 'rleg, 'lleg, 'rarm, 'larm, 'torso];
};

public method .wear() {
    if (caller() != $wearable)
        throw(~wear, "You can only wear descendants of $wearable.");
    wearing = setadd(wearing || [], sender());
};

public method .shed() {
    if (caller() != $wearable)
        throw(~wear, "You can only wear descendants of $wearable.");
    wearing = setremove(wearing, sender());
};

public method .will_move() {
    arg mover, place;
    
    // exits should always be able to pull "bodies" through them
    // this becomes sortof a big override returning, but ... *shrug*
    if (mover.is($path))
        return;
    (> pass(mover, place) <);
};

public method .description() {
    arg flags;
    var ctext, what, w, o;
    
    o = [];
    ctext = (> pass(flags) <);
    if ((w = .wearing()))
        o += [((((.gender()).pronoun('psc)) + " is wearing ") + ((w.mmap('name)).to_english())) + "."];
    
    //   else
    //       o += [.gender().pronoun('psc) + " is naked, baring it all to the world."];
    if (o != [])
        ctext += [$ctext_frob.new_with(o)];
    return ctext;
};

protected method .parse_interaction_reference() {
    arg targets, what, @userdb;
    var recip, target, msg, out;
    
    [(userdb ?= 0)] = userdb;
    targets = (targets && (targets.explode_list())) || [];
    if (!targets) {
        if (!(targets = (| interaction['objs] |)))
            throw(~stop, ("You must direct your " + what) + " to a target.");
        out = targets[2];
    } else {
        out = [];
        for recip in (targets) {
            target = 0;
            if (userdb)
                target = (| $user_db.match_begin(recip) |);
            if (!target) {
                catch ~objnf, ~namenf, ~invdbref, ~context, ~ambig
                    target = (> .match_environment(recip) <);
                with
                    throw(~stop, (traceback()[1])[2]);
            }
            if (!(target.is($body)))
                throw(~stop, (target.namef('ref)) + " is not a valid recipient.");
            out = setadd(out, target);
        }
    }
    return filter target in (out) where (valid(target));
};

protected method .add_interaction() {
    arg key, value;
    
    if (!interaction)
        interaction = #[];
    if (type(value) != 'list)
        value = [value];
    value = [time(), value];
    interaction = interaction.add(key, value);
};

protected method .whisper_cmd() {
    arg cmdstr, com, what, prep, who;
    var loc, targets, t, msg, recips;
    
    (> .perms(caller(), $user, $body) <);
    targets = (> .parse_interaction_reference(who, "whisper") <);
    .add_interaction('objs, targets);
    loc = .location();
    if (((targets.mmap('location)).compress()) != [loc]) {
        who = filter t in (targets) where ((t.location()) != loc);
        return ("You must be in the same place as " + (who.english_name_list())) + ", to whisper to them.";
    }
    msg = (((.name()) + " whispers, \"") + what) + "\"";
    for t in (targets)
        (| t.directed_tell(msg, 'whisper) |);
    recips = (targets.mmap('name)).to_english();
    loc.announce((((.name()) + " whispers to ") + recips) + ".", this(), @targets);
    .tell(((("You whisper, \"" + what) + "\" to ") + recips) + ".");
};

protected method .think_cmd() {
    arg cmdstr, cmd, what;
    
    (> .perms(caller(), $user, $body) <);
    (.location()).announce((((.name()) + " . o O ( ") + what) + " )");
};

protected method .emote_cmd() {
    arg cmdstr, com, what;
    
    (> .perms(caller(), $user, $body) <);
    if (what && ((what[1]) == ":"))
        (.location()).announce((.name()) + (what.subrange(2)));
    else
        (.location()).announce(((.name()) + " ") + what);
};

protected method .say_cmd() {
    arg cmdstr, cmd, what;
    var type, how, idx;
    
    (> .perms(caller(), 'command) <);
    if (what)
        how = $code_lib.punctuation_type(what);
    else
        how = "say";
    (.location()).announce((((((.name()) + " ") + how) + "s, \"") + what) + "\"");
};

protected method .esay_cmd() {
    arg cmdstr, cmd, how, prep, what;
    
    (> .perms(caller(), $user, $body) <);
    (.location()).announce((((((.name()) + " ") + (how.trim())) + ", \"") + (what.trim())) + "\"");
};

protected method .spoof_cmd() {
    arg cmdstr, cmd, what;
    var name;
    
    (> .perms(caller(), $user, $body) <);
    name = .name();
    if (!(((name + " ") in what) || ((" " + name) in what)))
        what = (what + "     -- ") + name;
    (.location()).announce(what);
};

protected method .to_say_cmd() {
    arg cmdstr, com, who, prep, message;
    var targets, target, line, invobj, here;
    
    (> .perms(caller(), $user, $body) <);
    catch ~ambig
        targets = (> .parse_interaction_reference(who, "say") <);
    with
        return (traceback()[1])[2];
    here = .location();
    if ((invobj = filter target in (targets) where ((target.location()) != here)))
        return .tell(((invobj.to_english()) + (((invobj.length()) > 1) ? " are " : " is ")) + "not here in this location.");
    .add_interaction('objs, targets);
    line = (((.name()) + " (to ") + ((targets.mmap('name)).to_english())) + ") ";
    if (message)
        line += ((message[1]) == ":") ? (message.subrange(2)) : (((($code_lib.punctuation_type(message)) + "s, \"") + message) + "\"");
    else
        line += "says, \"\"";
    for target in (targets)
        target.directed_tell(line, 'tosay);
    (.location()).announce(line, @targets);
};

public method .pose_cmd() {
    arg cmdstr, cmd, args;
    var shortwords, preword_punct_chars, postword_punct_chars, preword_punct_expr, postword_punct_expr, pronouns, ant_pronouns, selfmsg, othersmsg, recips, antecedent, prepunct, postpunct, word, oword, things, who, aliases, msg, cap, name, wname, m, w, quoted, msgdict, posessive, name_expr;
    
    (> .perms(caller(), $user, $body) <);
    args = explode("." + (args.trim()));
    if (args == ["."]) {
        (.location()).announce(.name());
        return;
    }
    
    // ------------
    shortwords = ["a", "an", "the", "to", "for", "out", "of", "on", "at", "and"];
    preword_punct_chars = "[\"'`([{]";
    postword_punct_chars = "[]})\"',.!?:;]";
    
    // ------------
    preword_punct_expr = ("^" + preword_punct_chars) + "+";
    postword_punct_expr = postword_punct_chars + "+$";
    pronouns = (.gender()).pronouns();
    ant_pronouns = $gender_neuter.pronouns();
    selfmsg = (othersmsg = (recips = (antecedent = [])));
    quoted = 0;
    for word in (args) {
        if ((m = match_regexp(word, preword_punct_expr))) {
            prepunct = substr(word, @m[1]);
            word = substr(word, ((m[1])[2]) + 1);
        } else {
            prepunct = "";
        }
        if ((m = match_regexp(word, postword_punct_expr))) {
            postpunct = substr(word, @m[1]);
            word = substr(word, 1, ((m[1])[1]) - 1);
        } else {
            postpunct = "";
        }
        oword = word;
        quoted = (quoted + (((prepunct + word).sed("[^\"]+", "", "g")).length())) % 2;
        if ((!quoted) && ((word.length()) > 0)) {
            if ((word[1]) == "\\") {
                oword = (word = word.subrange(2));
            } else if (word in shortwords) {
                // don't match against common short words.
            } else if (word in ["me", "myself"]) {
                word = "yourself";
                oword = pronouns['pr];
            } else if (word == "I") {
                word = "you";
                oword = pronouns['ps];
            } else if (word == "my") {
                word = "your";
                oword = pronouns['pp];
            } else if (word == "mine") {
                word = "yours";
                oword = pronouns['pq];
            } else if (word in [ant_pronouns['ps], "%s"]) {
                word = ant_pronouns['ps];
                oword = antecedent ? [antecedent, word, "you"] : word;
            } else if (word in [ant_pronouns['po], "%o"]) {
                word = ant_pronouns['po];
                oword = antecedent ? [antecedent, word, "you"] : word;
            } else if (word in [ant_pronouns['pp], "%p"]) {
                word = ant_pronouns['pp];
                oword = antecedent ? [antecedent, word, "your"] : word;
            } else if (word in [ant_pronouns['pr], "%r"]) {
                word = ant_pronouns['pr];
                oword = antecedent ? [antecedent, word, ((antecedent.length()) > 1) ? "yourselves" : "yourself"] : word;
            } else if (word in [ant_pronouns['pq], "%q"]) {
                word = ant_pronouns['pq];
                oword = antecedent ? [antecedent, word, "yours"] : word;
            } else if ((word[1]) == ".") {
                // verb to conjugate
                word = substr(word, 2);
                if (match_regexp(word, "(ch|sh|s)$"))
                    oword = word + "es";
                else if (match_regexp(word, "[^a]y$"))
                    oword = substr(word, 1, strlen(word) - 1) + "ies";
                else
                    oword = word + "s";
            } else if ((word[1]) == ":") {
                // a verb for antecedent, to conjugate
                word = substr(word, 2);
                if (match_regexp(word, "es$"))
                    oword = substr(word, 1, strlen(word) - 2);
                else if (match_regexp(word, "ies$"))
                    oword = substr(word, 1, strlen(word) - 3) + "y";
                else if (match_regexp(word, "s$"))
                    oword = substr(word, 1, strlen(word) - 1);
                if ((antecedent.length()) < 2)
                    oword = [antecedent, word, oword];
                else
                    word = oword;
            } else {
                if ((| substr(word, (word.length()) - 1, 2) |) == "'s") {
                    posessive = "'s";
                    word = (oword = substr(word, 1, (word.length()) - 2));
                } else {
                    posessive = "";
                }
    
                // match_environment had a bug where you could send
                // nothing, and it would match everything, but no more,
                // so we need to find another way for this to work.
                // if (word[word.length()] == "*" || word in ["everyone", "everything"]) {
                if ((word[word.length()]) == "*") {
                    // look for matching things..
                    //  if (word in ["everyone", "everything"]) {
                    //      things = word == "everything";
                    //      word = "";
                    //  } else
                    if (((word.length()) > 1) && ((word[(word.length()) - 1]) == "*")) {
                        // match things too.
                        word = substr(word, 1, (word.length()) - 2);
                        things = 1;
                    } else {
                        // just match people.
                        things = 0;
                        word = substr(word, 1, (word.length()) - 1);
                    }
                    catch ~ambig, ~objnf {
                        who = [.match_environment(word)];
                    } with {
                        if ((error() == ~objnf) && word) {
                            who = [];
                        } else {
                            catch ~ambig, ~objnf {
                                who = [(.environment()).match_object(word)];
                            } with {
                                if (error() == ~ambig)
                                    who = (traceback()[1])[3];
                                else
                                    throw(~stop, ("Object '" + word) + "' not found.");
                            }
                        }
                    }
                    who = setremove(who, this());
                    if (!things)
                        who = filter w in (who) where (w.is($body));
                    else
                        who = filter w in (who) where (w.is($thing));
                    if (who) {
                        word = map w in (who) to ((w.name()) + posessive).to_english();
                        recips = union(recips, who);
                    } else {
                        word = (things ? "nothing" : "nobody") + posessive;
                    }
                    oword = word;
                    posessive = "";
                    antecedent = who;
                    ant_pronouns = ((antecedent.length()) == 1) ? (((antecedent[1]).gender()).pronouns()) : ($gender_plural.pronouns());
                } else if ((| (who = .match_environment((w = word))) |) && (who.is($body))) {
                    // Might be a valid match for a username..
                    if ((wname = who.name()) == w) {
                        // full name match.  Make sure it's capitalized right.
                        word = (oword = wname);
                        recips = setadd(recips, who);
                        antecedent = [who];
                        ant_pronouns = (who.gender()).pronouns();
                    } else {
                        aliases = who.name_templates();
                        aliases = map w in (aliases) to (explode(w, "|")).flatten();
                        aliases = map w in (aliases) to (strsub(w, "?", ""));
                        if (word in aliases) {
                            word = (oword = wname);
                            recips = setadd(recips, who);
                            antecedent = [who];
                            ant_pronouns = (who.gender()).pronouns();
                        }
                    }
                }
                word += posessive;
                oword += posessive;
            }
        }
        quoted = (quoted + ((postpunct.sed("[^\"]+", "", "g")).length())) % 2;
        selfmsg += [(prepunct + word) + postpunct];
        if (type(oword) == 'string)
            othersmsg += [(prepunct + oword) + postpunct];
        else
            othersmsg += [[oword[1], (prepunct + (oword[2])) + postpunct, (prepunct + (oword[3])) + postpunct]];
        refresh();
    }
    msg = "";
    cap = 0;
    for word in (selfmsg) {
        word = cap ? ("  " + (word.capitalize())) : (" " + word);
        msg += word;
        cap = match_regexp(word, "[.!?:][^A-Za-z0-9_]*$");
        refresh();
    }
    msgdict = #[[this(), (<$ctext_frob, [[("You" + msg) + (cap ? "" : ".")], #[]]>)]];
    name = .name();
    for w in (recips + [0]) {
        wname = w ? (w.name()) : 0;
        cap = 0;
        msg = "";
        name_expr = ((((("( |^)" + preword_punct_chars) + "*(") + ((w.name()).regexp_escape())) + ")('s)?") + postword_punct_chars) + "*( |$)";
        for word in (othersmsg) {
            switch (type(word)) {
                case 'string:
                    if (w && (wname != "you")) {
                        while ((m = word.match_regexp(name_expr))) {
                            if ((m[4])[1])
                                word = ((word.subrange(1, ((m[3])[1]) - 1)) + "your") + (word.subrange(((m[4])[1]) + ((m[4])[2])));
                            else
                                word = ((word.subrange(1, ((m[3])[1]) - 1)) + "you") + (word.subrange(((m[3])[1]) + ((m[3])[2])));
                        }
                    }
                    word = cap ? ("  " + (word.capitalize())) : (" " + word);
                case 'list:
                    if (w in (word[1]))
                        word = cap ? ("  " + ((word[3]).capitalize())) : (" " + (word[3]));
                    else
                        word = cap ? ("  " + ((word[2]).capitalize())) : (" " + (word[2]));
            }
            msg += word;
            cap = match_regexp(word, "[.!?:][^A-Za-z0-9_]*$");
            refresh();
        }
        msg = (name + msg) + (cap ? "" : ".");
        msgdict = msgdict.add(w || "general", (<$ctext_frob, [[msg], #[]]>));
    }
    (.location()).announce((<$message_frob, msgdict>));
};

protected method .quote_cmd() {
    arg cmdstr, cmd, what;
    
    (.location()).announce(((.name()) + " | ") + what);
};

public method .ptell() {
    arg what, flags;
    
    .tell(what);
};

protected method .handle_parser_result() {
    arg line, action, @more;
    var r, c;
    
    switch (action) {
        case 'error:
            ._tell(more[1]);
        case 'match, 'command:
            r = (> (more[1]).(more[2])(@more.subrange(3)) <);
            if (type(r) in ['list, 'frob, 'string])
                .ptell(r, #[['type, 'parser], ['command, more[2]]]);
        case 'failed:
            for c in (($place_lib.coordinate_shortcuts()).keys()) {
                if (line.match_template(c)) {
                    .tell(("There is no exit " + line) + " here.");
                    r = 1;
                }
            }
            if (!r)
                .tell(("I don't understand " + (line.chop((.linelen()) - 22))) + ".");
        case 'ok:
            // do nothing, probably a null command
        default:
            ._tell("Unusual response from the parser: " + more);
    }
};

public method .directed_tell() {
    arg what, type;
    
    ._tell(what);
    .send_event('social, sender(), type, what);
};

public method .tell_traceback() {
    arg traceback, @parse;
    var tb;
    
    if (parse && (| ((parse[2]).find_method(parse[3])).has_flag('core) |))
        $sys.log_traceback(traceback, last_command);
    
    // who do we show tracebacks to...
    if (.has_ancestor($sys.get_setting("traceback-for", $sys))) {
        .tell(traceback.fmt_tb());
        .tell(["!", "! You may want to use @report to report this problem."]);
    } else {
        .tell("OOPS! An error has occurred: " + ((traceback[1])[2]));
        .tell("You can view the full error with @traceback");
        .tell("You may want to use @report to report this problem.");
    }
};

public method ._tell() {
    arg @args;
    var m;
    
    m = .manager();
    if ((m != this()) && ((m.location()) != (.location())))
        (| m.tell(@args.prefix(("<" + (.name())) + "> ")) |);
};

public method .tell_realm_announce() {
    arg last_realm, message;
    var loc, realm, propagator, prop_list, len, i;
    
    pause();
    loc = .location();
    if (!(propagator = loc.will_propagate()))
        return;
    prop_list = [propagator];
    realm = (.location()).realm();
    if (type(message) == 'symbol)
        message = realm.eval_message(tostr(message), $realm, realm.ctext_variables());
    while (realm != $realm) {
        if (realm == last_realm) {
            len = prop_list.length();
            for i in [1 .. len] {
                message = message.propagate(prop_list[(len - i) + 1]);
                if (!message)
                    return;
            }
            .tell(message);
            return;
        }
        if (!(propagator = realm.will_propagate()))
            return;
        prop_list += [propagator];
        realm = (realm.parents())[1];
    }
};

public method .event_notify() {
    arg event, origin, @args;
    
    if (caller() != $event_handler)
        throw(~perm, caller() + " is not $event_handler.");
    if (event == 'realm_announce)
        .tell_realm_announce(origin, args[1]);
};

public method .linelen() {
    return 79;
};

public method .get_cols() {
    arg @args;
    
    return 80;
};

public method .get_rows() {
    arg @args;
    
    return 79;
};

public method .tell_error() {
    arg syntax, @problem;
    var problem, line, sprefix, prefix, length;
    
    // arg 1 == syntax
    // arg 2 == problem lines
    length = .linelen();
    if (syntax)
        .tell(("=> Syntax: `" + syntax) + "`");
    if (problem) {
        for line in (problem) {
            if (type(line) == 'string)
                line = line.wrap_lines(length, "!  ", 1);
            .tell(line);
        }
    }
    throw(~stop, "");
};

public method .match_env_nice() {
    arg name, @syntax;
    var obj, args, line;
    
    catch any {
        return (> .match_environment(name) <);
    } with {
        if (syntax)
            (> .tell_error(syntax[1], (traceback()[1])[2]) <);
        else
            throw(~stop, (traceback()[1])[2]);
    }
};

public method .last_traceback() {
    return last_traceback;
};

public method .set_last_traceback() {
    arg tb;
    
    if (caller() != $parse_lib)
        throw(~sorry, "nope.");
    last_traceback = tb;
};

protected method .clear_last_traceback() {
    (| clear_var('last_traceback) |);
};

protected method .get_cmd() {
    arg cmdstr, cmd, what;
    var ol, l, isuser;
    
    (> .perms(caller(), 'command) <);
    ol = what.location();
    if (ol == this()) {
        throw(~stop, ("You already have " + (what.name())) + ".");
    } else if (what == this()) {
        throw(~stop, "Ewww, its all twisty.");
    } else {
        l = .location();
        if (l != ol) {
            isuser = ol.is($user);
            if ((| ol.location() |) != l)
                throw(~stop, ("You are not in " + (what.location())) + ".");
        }
        catch any {
            (> what.move_to(this()) <);
        } with {
            if (error() == ~locked) {
                if (isuser)
                    ol.tell((((.name()) + " tried to take ") + (what.name())) + " from you.");
                rethrow(~stop);
            } else {
                rethrow(~stop);
            }
        }
        if (isuser)
            ol.tell((((.name()) + " takes ") + (what.name())) + " from you.");
        l.announce((((.name()) + " takes ") + (what.name())) + ".", this(), ol);
        if (l != ol) {
            if (!isuser)
                l.announce((((.name()) + " takes ") + (what.name())) + ".");
            return ((("You take " + (what.name())) + " from ") + (ol.name())) + ".";
        }
        return ("You take " + (what.name())) + ".";
    }
};

protected method .get_from_cmd() {
    arg cmdstr, cmd, what, p, loc;
    var c, obj, l, wl, str;
    
    (> .perms(caller(), 'command) <);
    if (loc == this())
        return "Huh?  Get what?";
    for c in (loc.contents()) {
        if (c.match_name(what))
            obj = c;
    }
    if (!obj) {
        if (loc.is($place))
            return ("No \"" + what) + "\" in your environment.";
        else
            return ((loc.name()) + " does not have ") + what;
    }
    if ((obj == this()) || (obj == loc))
        return "Ewww, its all twisty.";
    if (loc.is($place))
        return .get_cmd(cmdstr, cmd, obj);
    catch any {
        l = .location();
        (> obj.move_to(this()) <);
        str = (((" " + (obj.name())) + " ") + p) + " ";
        wl = loc.location();
        .tell(((("You " + cmd) + str) + (loc.name())) + ".");
        (| loc.tell((((((.name()) + " ") + cmd) + "s") + str) + "you.") |);
        cmd += "s";
        str = (str + (loc.name())) + " ";
        if (l != wl)
            wl.announce((((.name()) + " ") + cmd) + str, this(), loc);
        l.announce((((.name()) + " ") + cmd) + str, this(), loc);
        return;
    } with {
        switch (error()) {
            case ~locked:
                if (loc.is($user))
                    loc.tell((((((.name()) + " tried to take ") + (obj.name())) + " ") + p) + " you.");
                return (((obj.name()) + " is locked to ") + ((obj.lock()).lock_name('thing))) + ".";
            default:
                return (traceback()[1])[2];
        }
    }
};

protected method .give_to_cmd() {
    arg cmdstr, cmd, what, p, loc;
    var c, obj, l, wl, str;
    
    (> .perms(caller(), 'command) <);
    if (!(what in (.contents())))
        return ("You don't have " + (what.name())) + ".";
    if (what == this())
        return "Give yourself away?  Interesting...";
    if (what == loc)
        return ((("Uhh, you cannot give " + ((what.gender()).pronoun('po))) + " to ") + ((what.gender()).pronoun('pr))) + ".";
    if (loc.is($place))
        return .drop_cmd(cmdstr, cmd, what);
    catch any {
        l = .location();
        wl = loc.location();
        (> what.move_to(loc) <);
        str = (((" " + (what.name())) + " ") + p) + " ";
        .tell(((("You " + cmd) + str) + (loc.name())) + ".");
        (| loc.tell((((((.name()) + " ") + cmd) + "s") + str) + "you.") |);
        cmd += "s";
        str = (str + (loc.name())) + " ";
        if (l != wl)
            wl.announce((((.name()) + " ") + cmd) + str, this(), loc);
        l.announce((((.name()) + " ") + cmd) + str, this(), loc);
    } with {
        .tell_traceback(traceback());
        return (traceback()[1])[2];
    }
};

protected method .drop_cmd() {
    arg cmdstr, cmd, what;
    
    (> .perms(caller(), 'command) <);
    if (!(what in (.contents()))) {
        return ("You don't have " + (what.name())) + ".";
    } else {
        catch any {
            (> what.move_to(.location()) <);
            .tell(("You drop " + (what.name())) + ".");
            (| (.location()).announce((((.name()) + " drops ") + (what.name())) + ".", this(), what) |);
        } with {
            return (traceback()[1])[2];
        }
    }
};

public method .set_last_command() {
    arg cmd;
    
    // HACKNOTE: Remove
    if (caller() != $user)
        return;
    last_command = cmd;
};


new object $has_reactions: $foundation;

var $root manager = $has_reactions;
var $root created_on = 809243338;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root managed = [$has_reactions];
var $has_reactions active = 0;
var $has_reactions reactions = 0;
var $has_reactions last_id = 0;

protected method .check_reactions() {
    arg type, str, sender;
    var rnum, t, id, chance, times, method, template, m;
    
    rnum = random(100);
    for t in ([type, 'any]) {
        if (!dict_contains(active, t))
            continue;
        for id in (dict_keys(active[t])) {
            [chance, times] = (active[t])[id];
            if (rnum > chance)
                break;
            [method, template] = reactions[id];
            if ((m = str.(method)(template))) {
                if (times == 1)
                    .remove_active(t, id);
                else if (times > 1)
                    .update_active(t, id, [chance, --times]);
                if ((.do_reaction(str, m, id, sender)) != 'continue)
                    return;
            }
        }
    }
};

public method .active() {
    return active;
};

protected method .update_active() {
    arg key, id, value;
    
    active = dict_add(active, key, dict_add(active[key], id, value));
};

protected method .remove_active() {
    arg key, id;
    
    active = dict_add(active, key, dict_del(active[key], id));
};

public method .set_active() {
    arg id;
    var ra, key, e, inserted, chance, times;
    
    if ((!reactions) || (!dict_contains(reactions, id)))
        throw(~noreaction, ("No reaction with id '" + id) + "'.");
    if (!active)
        active = #[];
    [key, chance, times] = sublist(reactions[id], 3, 3);
    if (dict_contains(active, key)) {
        ra = active[key];
        if (ra.contains(id))
            return .update_active(key, id, [chance, times]);
        active = dict_del(active, key);
        ra = map e in (ra) to (e);
    } else {
        ra = [];
    }
    for e in [1 .. listlen(ra)] {
        if ((((ra[e])[2])[1]) < chance) {
            ra = insert(ra, e, [id, [chance, times]]);
            inserted++;
        }
    }
    if (!inserted)
        ra += [[id, [chance, times]]];
    active = dict_add(active, key, hash e in (ra) to (e));
};

protected method .do_reaction(): forked {
    arg str, match, id, sender;
    var method, args, min, max, time;
    
    [[method, args], min, max] = sublist(reactions[id], 6);
    time = random(max - min) + min;
    $scheduler.sleep(time);
    catch any
        return (> .(method)(str, match, sender, @args) <);
    with
        .tell_traceback(traceback());
    return 'stop;
};

public method .tell_traceback() {
    arg @args;
    
};

public method .add_reaction() {
    arg @args;
    var r, id;
    
    // make sure it doesn't already exist..
    for r in (reactions || #[]) {
        if (((r[2])[2]) == (args[2])) {
            if ((r[2]) == args)
                return r[1];
        }
    }
    (> .check_reaction_args(@args) <);
    reactions = dict_add(reactions || #[], ++last_id, args);
};

private method .check_reaction_args() {
    arg method, template, type, chance, times, hook, min, max;
    
    if (type(method) != 'symbol)
        throw(~type, "Match type (arg 1) is not a symbol.");
    if (type(template) != 'string)
        throw(~type, "Match template (arg 2) is not a string.");
    if (type(type) != 'symbol)
        throw(~type, "Reaction type (arg 3) is not a symbol.");
    if (type(chance) != 'integer)
        throw(~type, "Reaction chance (arg 4) is not a integer.");
    if (type(times) != 'integer)
        throw(~type, "Reaction times (arg 5) is not a integer.");
    if (type(hook) != 'list)
        throw(~type, "Reaction hook (arg 6) is not a list.");
    if ((!hook) || (type(hook[1]) != 'symbol))
        throw(~type, "Reaction hook method (arg 6[1]) is not a symbol.");
    if ((listlen(hook) == 1) || (type(hook[2]) != 'list))
        throw(~type, "Reaction hook arguments (arg 6[2]) is not a list.");
    if (type(min) != 'integer)
        throw(~type, "Reaction minimum delay (arg 7) is not a integer.");
    if (type(max) != 'integer)
        throw(~type, "Reaction maximum delay (arg 8) is not a integer.");
};

public method .del_reaction() {
    arg id;
    
    // cruft up later
    reactions = reactions.del(id);
};


new object $robot: $body, $has_reactions;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core, 'fertile, 'general_cache];
var $has_name name = ['uniq, "Robot", "the Robot"];
var $described prose = <$ctext_frob, [["A generic automated robot object."], #[['this, $robot]]]>;
var $located location = $nowhere;
var $located obvious = 1;
var $body body_parts = #[];
var $location contents = [];
var $command_cache modules = [];
var $root manager = $robot;
var $root managed = [$robot];
var $robot last_id = 1;
var $robot reactions = #[];
var $robot active = 0;
var $robot match_types = #[["regexp", ['regexp, "rex"]], ["pattern", ['match_pattern, "pat"]], ["template", ['match_template, "tmp"]]];
var $has_commands remote = #[["@reactions", [["@reactions", "*", "@reactions <this>", 'reactions_cmd, #[[1, ['this, []]]]]]], ["@del-r?eaction", [["@del-r?eaction", "* from|on *", "@del-r?eaction <number> from|on <this>", 'del_reaction_cmd, #[[1, ['number, []]], [3, ['this, []]]]]]], ["@add-r?eaction", [["@add-r?eaction", "* to * on *", "@add-r?eaction <any> to <any> on <this>", 'add_reaction_cmd, #[[1, ['any, []]], [3, ['any, []]], [5, ['this, []]]]]]], ["@deactivate-r?eaction|@dr", [["@deactivate-r?eaction|@dr", "* on *", "@deactivate-r?eaction|@dr <number> on <this>", 'deactivate_reaction_cmd, #[[1, ['number, []]], [3, ['this, []]]]]]], ["@activate-r?eaction|@ar", [["@activate-r?eaction|@ar", "* on *", "@activate-r?eaction|@ar <number> on <this>", 'activate_reaction_cmd, #[[1, ['number, []]], [3, ['this, []]]]]]]];
var $robot active_ids = 0;
var $thing gender = $gender_neuter;
var $root help_node = $help_obj_robot;
var $command_cache commands = 0;
var $command_cache shortcuts = 0;

public method .parse_line() {
    arg line;
    var parse;
    
    (> .perms(sender()) <);
    catch any {
        parse = $command_parser.parse(this(), line, $null_parser);
        (> .handle_parser_result(line, @parse) <);
    } with {
        if (error() == ~stop) {
            if ((traceback()[1])[2])
                .tell((traceback()[1])[2]);
        } else if ((.manager()) != this()) {
            (.manager()).tell(traceback().fmt_tb());
        } else {
            .tell_traceback(traceback());
        }
    }
};

protected method .react_command() {
    arg str, match, sender, cmd;
    
    .parse_line(cmd);
};

protected method .react_subcmd() {
    arg str, match, sender, cmd;
    var m;
    
    cmd = strsub(cmd, "%P", sender.name());
    for m in [1 .. listlen(match)]
        cmd = strsub(cmd, "%" + m, match[m]);
    .parse_line(cmd);
};

public method .tell() {
    arg what, @who;
    var line;
    
    if (!(.active()))
        return;
    switch (type(what)) {
        case 'list:
            for line in (what)
                .tell(line, @who);
        case 'string:
            // drop through, this is what we want
        default:
            return;
    }
    if (who && (sender().is($place)))
        who = who[1];
    else
        who = sender();
    if (who == this())
        return;
    .check_reactions('tell, what, who);
};

public method .event_notify() {
    arg event, origin, @args;
    
    if (caller() != $event_handler)
        throw(~perm, caller() + " is not $event_handler.");
    if (!(.active()))
        return;
    if (event == 'social)
        .check_reactions(args[2], args[3], args[1]);
};

public method .startup() {
    (> .perms(sender(), 'trusts) <);
    .hook_events('startup);
};

protected method .check_reactions() {
    arg type, str, sender;
    var rnum, t, id, chance, times, method, template, m, types;
    
    rnum = random(100);
    if (type == 'tell)
        types = ['tell, 'any];
    else
        types = [type, 'notell, 'any];
    for t in (types) {
        if (!dict_contains(active, t))
            continue;
        for id in (dict_keys(active[t])) {
            [chance, times] = (active[t])[id];
            if (rnum > chance)
                break;
            [method, template] = reactions[id];
            if ((!template) || (m = str.(method)(template))) {
                if (times == 1)
                    .remove_active(t, id);
                else if (times > 1)
                    .update_active(t, id, [chance, --times]);
                if ((.do_reaction(str, m, id, sender)) != 'continue)
                    return;
            }
        }
    }
};

public method .active() {
    return active;
};

protected method .update_active() {
    arg key, id, value;
    
    active = dict_add(active, key, dict_add(active[key], id, value));
};

protected method .remove_active() {
    arg key, id;
    
    active = dict_add(active, key, dict_del(active[key], id));
    if (!(active[key]))
        active = dict_del(active, key);
    if (!active)
        clear_var('active);
};

public method .activate_reaction() {
    arg id;
    var ra, key, e, inserted, chance, times;
    
    // Make sure the sender is a writer, added by Sean 20 Feb 1998
    (> .perms(sender()) <);
    if ((!reactions) || (!dict_contains(reactions, id)))
        throw(~noreaction, ("No reaction with id '" + id) + "'.");
    if (!active)
        active = #[];
    [key, chance, times] = sublist(reactions[id], 3, 3);
    if (dict_contains(active, key)) {
        ra = active[key];
        if (ra.contains(id))
            return .update_active(key, id, [chance, times]);
        active = dict_del(active, key);
        ra = map e in (ra) to (e);
    } else {
        ra = [];
    }
    for e in [1 .. listlen(ra)] {
        if ((((ra[e])[2])[1]) < chance) {
            ra = insert(ra, e, [id, [chance, times]]);
            inserted++;
        }
    }
    if (!inserted)
        ra += [[id, [chance, times]]];
    active = dict_add(active, key, hash e in (ra) to (e));
    active_ids = dict_add(active_ids || #[], id, key);
    
    // Hook into 'social; .hook_into_events() will not add twice, so we're safe
    // Added by Sean 20 Feb 1998
    // Only hook if the type is not 'tell
    if (key != 'tell)
        .hook_into_event('social);
};

protected method .do_reaction(): forked {
    arg str, match, id, sender;
    var method, args, min, max, time, range;
    
    [[method, args], min, max] = sublist(reactions[id], 6);
    range = max - min;
    if (range < 2)
        time = 1;
    else
        time = random(range) + min;
    $scheduler.sleep(time);
    catch any
        return (> .(method)(str, match, sender, @args) <);
    with
        .tell_traceback(traceback());
    return 'stop;
};

public method .tell_traceback() {
    arg @args;
    
};

public method .add_reaction() {
    arg @args;
    var r, id;
    
    // Make sure the sender is a writer, added by Sean
    (> .perms(sender()) <);
    
    // make sure it doesn't already exist..
    for r in (reactions || #[]) {
        if (((r[2])[2]) == (args[2])) {
            if ((r[2]) == args)
                return r[1];
        }
    }
    (> .check_reaction_args(@args) <);
    reactions = dict_add(reactions || #[], ++last_id, args);
};

private method .check_reaction_args() {
    arg method, template, type, chance, times, hook, min, max;
    
    (> .check_reaction_matchwith(method) <);
    (> .check_reaction_template(template) <);
    (> .check_reaction_type(type) <);
    (> .check_reaction_chance(chance) <);
    (> .check_reaction_times(times) <);
    (> .check_reaction_hook(hook) <);
    (> .check_reaction_hook_method(hook[1]) <);
    (> .check_reaction_hook_args(hook[2]) <);
    (> .check_reaction_min(min) <);
    (> .check_reaction_max(max) <);
};

public method .del_reaction() {
    arg id;
    var key;
    
    (> .perms(sender()) <);
    if (!dict_contains(reactions, id))
        return;
    (| .deactivate_reaction(id) |);
    reactions = reactions.del(id);
};

public method .reactions() {
    return reactions;
};

public method .match_type() {
    arg type;
    
    type = strsed(tostr(type), "match_", "");
    if (!dict_contains(match_types, type))
        throw(~type, "Invalid type matcher: " + type);
    return (| match_types[type] |);
};

public method .reactions_cmd() {
    arg cmdstr, cmd, this;
    var id, m, tmpl, type, chance, times, method, args, max, min, out, t, a;
    
    // [id, [match, template, type, chance, times, [method, args], max, min]]
    out = [];
    for id in (dict_keys(reactions || #[])) {
        [m, tmpl, type, chance, times, [method, args], min, max] = reactions[id];
        t = $robot.match_type(m);
        a = dict_contains(active_ids || #[], id);
        out += [strfmt("%l%3r %3r %4r %6l %8c %22l %l %l", a ? "*" : " ", id, chance, (times == (-1)) ? "inf" : times, type, (min == max) ? min : ((min + "~") + max), method, t[2], tmpl ? (("\"" + tmpl) + "\"") : "anything")];
    }
    if (out)
        return (["-- Defined Reactions:", "  ID %CH    # TYPE    DELAY   HOOK                   MT  TEMPLATE"] + out) + ["--"];
    return "-- No Reactions Defined --";
};

private method .check_reaction_hook() {
    arg hook;
    
    if (type(hook) != 'list)
        throw(~type, "Reaction hook is not a list.");
    if (listlen(hook) != 2)
        throw(~type, "Reaction hook is not a two element list.");
};

private method .check_reaction_hook_method() {
    arg method;
    
    if (type(method) != 'symbol)
        throw(~type, "Reaction hook method is not a symbol.");
};

private method .check_reaction_hook_args() {
    arg args;
    
    if (type(args) != 'list)
        throw(~type, "Reaction hook arguments is not a list.");
};

private method .check_reaction_min() {
    arg min;
    
    if (type(min) != 'integer)
        throw(~type, "Reaction minimum delay is not a integer.");
};

private method .check_reaction_max() {
    arg max;
    
    if (type(max) != 'integer)
        throw(~type, "Reaction maximum delay is not a integer.");
};

private method .check_reaction_matchwith() {
    arg method;
    
    if (type(method) != 'symbol)
        throw(~type, "Match type is not a symbol.");
};

private method .check_reaction_template() {
    arg template;
    
    if (type(template) != 'string)
        throw(~type, "Match template is not a string.");
};

private method .check_reaction_type() {
    arg type;
    
    if (type(type) != 'symbol)
        throw(~type, "Reaction type is not a symbol.");
};

private method .check_reaction_chance() {
    arg chance;
    
    if (type(chance) != 'integer)
        throw(~type, "Reaction chance is not a integer.");
};

private method .check_reaction_times() {
    arg times;
    
    if (type(times) != 'integer)
        throw(~type, "Reaction times is not a integer.");
};

public method .update_reaction() {
    arg id, part, value;
    var r, chance, times, active;
    
    (> .perms(sender()) <);
    if (!(reactions.contains(id)))
        throw(~noreaction, ("No reaction with id \"" + id) + "\".");
    r = reactions[id];
    if ((active = dict_contains(active_ids, id)))
        .deactivate_reaction(id);
    switch (part) {
        case 'matchwith:
            (> .check_reaction_matchwith(value) <);
            r = replace(r, 1, value);
        case 'template:
            (> .check_reaction_template(value) <);
            r = replace(r, 2, value);
        case 'type:
            (> .check_reaction_type(value) <);
            r = replace(r, 3, value);
        case 'chance:
            (> .check_reaction_chance(value) <);
            r = replace(r, 4, value);
        case 'times:
            (> .check_reaction_times(value) <);
            r = replace(r, 5, value);
        case 'method, 'hook_method:
            (> .check_reaction_hook_method(value) <);
            r = replace(r, 6, replace(r[6], 1, value));
        case 'args, 'hook_args:
            (> .check_reaction_hook_args(value) <);
            r = replace(r, 6, replace(r[6], 2, value));
        case 'min, 'min_delay:
            (> .check_reaction_min(value) <);
            r = replace(r, 7, value);
        case 'max, 'max_delay:
            (> .check_reaction_max(value) <);
            r = replace(r, 8, value);
        default:
            throw(~invpart, ("Invalid part '" + part) + ".");
    }
    reactions = reactions.add(id, r);
    if (active)
        .activate_reaction(id);
};

public method .deactivate_reaction() {
    arg id;
    
    // sender should be a writer.  added by Sean 20 Feb 1998
    (> .perms(sender()) <);
    if (active_ids && dict_contains(active_ids, id)) {
        .remove_active(active_ids[id], id);
        active_ids = dict_del(active_ids, id);
        if (!active_ids) {
            clear_var('active_ids);
            .unhook_from_event('social);
        }
    }
};

public method .connected() {
    // to simulate a user
    return .active();
};

public method .connected_time() {
    arg @args;
    
    [(args ?= 'dhms)] = args;
    if (!(.active()))
        return "Inactive";
    switch (args) {
        case 'seconds:
            return 0;
        default:
            return "";
    }
};

public method .idle_time() {
    arg @args;
    
    return "";
};

public method .activate_reaction_cmd() {
    arg cmdstr, cmd, int, prep, this;
    
    (> .perms(sender()) <);
    catch ~noreaction
        .activate_reaction(int);
    with
        return (traceback()[1])[2];
    sender().tell(((("Reaction " + int) + " activated on ") + (.name())) + ".");
};

public method .deactivate_reaction_cmd() {
    arg cmdstr, cmd, int, prep, this;
    
    (> .perms(sender()) <);
    .deactivate_reaction(int);
    sender().tell(((("Reaction " + int) + " deactivated on ") + (.name())) + ".");
};

public method .add_reaction_cmd() {
    arg cmdstr, cmd, args, prep1, hook, prep2, me;
    var t, type, method, times, chance, min, max, hook_args, i, opts, o, def_opts;
    
    (> .perms(caller(), 'command) <);
    hook = (| hook.to_symbol() |);
    if (!hook)
        throw(~args, "Invalid hook");
    def_opts = [["t?ype", 1], ["m?ethod", 1], ["ti?mes", 1], ["c?hance", 1], ["min", 1], ["max", 1], ["a?rgs", 1]];
    [t, opts] = $parse_lib.getopt(args, def_opts);
    t = t.join();
    
    // Set the defaults
    method = 'regexp;
    type = 'tosay;
    chance = 100;
    times = -1;
    hook_args = [];
    min = 0;
    max = 0;
    catch any {
        // check the options!
        o = opts.slice(1);
        if ((i = "m?ethod" in o)) {
            method = (| ((opts[i])[4]).to_symbol() |);
            if (!method)
                throw(~args, "Invalid method specified with +m?ethod=??");
        }
        if ((i = "t?ype" in o)) {
            type = (| ((opts[i])[4]).to_symbol() |);
            if (!type)
                throw(~args, "No type specified with +t?ype=??");
        }
        if ((i = "c?hance" in o)) {
            chance = (| ((opts[i])[4]).to_number() |);
            if ((chance < 1) || (chance > 100))
                throw(~args, "+c?hance=?? requires an integer between 1 and 100");
        }
        if ((i = "ti?mes" in o)) {
            times = (| ((opts[i])[4]).to_number() |);
            if ((!times) || (times < (-1)))
                throw(~args, "+ti?mes=?? requires an integer >= -1");
        }
        if ((i = "min" in o)) {
            min = (| ((opts[i])[4]).to_number() |);
            if ((!min) || (min < 0))
                throw(~args, "+min=?? requires an integer >= 0");
        }
        if ((i = "max" in o)) {
            max = (| ((opts[i])[4]).to_number() |);
            if ((!max) || (max < 0))
                throw(~args, "+max=?? requires an integer >= 0");
        }
        if ((i = "a?rgs" in o)) {
            hook_args = (> fromliteral((opt[i])[4]) <);
            if (type(hook_args) != 'list)
                hook_args = [hook_args];
        }
        if (max < min)
            max = min;
        (> .add_reaction(method, t, type, chance, times, [hook, hook_args], min, max) <);
    } with {
        return (traceback()[1])[2];
    }
    return strfmt("Reaction %d added to %s.%s() with match method %s, type %s, chance %d, times %d, args %s, min_delay %s, and max_delay %s.", t, toliteral(this()), hook, toliteral(method), toliteral(type), chance, times, toliteral(hook_args), min, max);
};

public method .del_reaction_cmd() {
    arg cmdstr, cmd, id, @args;
    
    (> .perms(caller(), 'command) <);
    .del_reaction(id);
    return ((("Removed reaction " + id) + " from ") + (.name())) + ".";
};

public method .idle_seconds() {
    return 0;
};


new object $command_aliases: $user_interfaces;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $command_aliases command_aliases = [];
var $root manager = $command_aliases;
var $root managed = [$command_aliases];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;

root method .init_command_aliases() {
    command_aliases = [];
};

root method .uninit_command_aliases() {
    command_aliases = [];
};

public method .command_aliases() {
    return command_aliases;
};

public method .all_command_aliases() {
    var user, aliases, userc;
    
    // Collect complete command alias list from ancestors.
    aliases = [];
    for user in (.ancestors()) {
        userc = (| user.command_aliases() |);
        if (userc)
            aliases += userc;
        if (user == definer())
            break;
    }
    return aliases;
};

public method .match_command_aliases() {
    arg str;
    var alias, argf, match, newstr;
    
    // attempts to rebuild the string for an alias.
    if (sender() != this())
        throw(~perm, "Sender is not this.");
    for alias in (.all_command_aliases()) {
        match = str.match_pattern(alias[1]);
        if (match != 0) {
            newstr = alias[2];
            for argf in [1 .. match.length()]
                newstr = newstr.replace("%" + tostr(argf), match[argf]);
            return newstr;
        }
    }
    return str;
};

public method .add_command_alias() {
    arg alias, actual;
    var relation, a;
    
    (> .perms(sender()) <);
    if ((type(alias) != 'string) || (type(actual) != 'string))
        throw(~type, "alias and actual are not strings.");
    relation = (> $command_lib.parse_relation(alias, actual) <);
    
    // have it 'replace' the old alias (if one exists) by first removing
    // the old one, and adding the new one later.
    for a in (command_aliases) {
        if ((a[1]) == alias)
            command_aliases = command_aliases.setremove(a);
    }
    command_aliases += [[(relation[1])[1], (relation[2])[2]]];
};

public method .del_command_alias() {
    arg alias;
    var ca, rel;
    
    (> .perms(sender()) <);
    if (type(alias) != 'string)
        throw(~type, "alias is not a string.");
    rel = (> $command_lib.parse_relation(alias, alias) <);
    rel = rel[1];
    for ca in (command_aliases) {
        if ((ca[1]) == (rel[1])) {
            command_aliases = command_aliases.setremove(ca);
            return;
        }
    }
    throw(~aliasnf, ("alias `" + alias) + "' is not found");
};


new object $bad_commands: $user_interfaces;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $bad_commands non_supported_cmds = #[["quit", "@quit"], ["WHO", "@who"], ["@create", "@new"], ["help", "@help"], ["news", "@news"], ["page", "@page"], ["@gender", "@set gender"], ["uptime", "@status"], ["@alias", "@add-command-alias` or `@add-name-alias"], ["@check", "@monitor"], ["@paranoid", "@monitor"], ["@version", "@status"], ["@lock", "@set lock"], ["@unlock", "@set lock"], ["+com", ["See: `@help Channels`"]], ["tell", "@page"]];
var $has_commands local = #[["@create", [["@create", "*", "@create <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["page", [["page", "*", "page <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["who", [["who", "*", "who <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["quit", [["quit", "*", "quit <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["news", [["news", "*", "news <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@gender", [["@gender", "*", "@gender <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["uptime", [["uptime", "*", "uptime <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@alias", [["@alias", "*", "@alias <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@check|@paranoid", [["@check|@paranoid", "*", "@check|@paranoid <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@version", [["@version", "*", "@version <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["+com", [["+com", "*", "+com <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["tell", [["tell", "*", "tell <any>", 'old_command_cmd, #[[1, ['any, []]]]]]]];
var $root manager = $bad_commands;
var $root managed = [$bad_commands];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;

public method .add_old_cmd_reference() {
    arg oldcmd, @newcmd;
    
    (> .perms(caller()) <);
    if (this() != $bad_commands)
        throw(~perm, "Only define bad commands on $bad_commands");
    if ((" " in oldcmd) || (("<" in oldcmd) || ("*" in oldcmd)))
        throw(~perm, "Just the first word of the old command.");
    if (newcmd)
        non_supported_cmds = non_supported_cmds.add(oldcmd, newcmd[1]);
    .add_command(oldcmd + " <any>", 'old_command_cmd);
};

protected method .old_command_cmd() {
    arg cmdstr, com, @args;
    var line, equiv, pref;
    
    (> .perms(caller(), 'command) <);
    equiv = (| ($bad_commands.non_supported_cmds())[com] |);
    line = ("Oops, `" + com) + "` is not supported here.";
    if (equiv) {
        if (type(equiv) == 'list)
            line = (line + "  ") + (equiv[1]);
        else
            line = ((line + "  Try `") + equiv) + "`";
    }
    .tell(line);
    .tell("Use `@help commands` for an explanation on the differences in commands.");
};

public method .non_supported_cmds() {
    return non_supported_cmds;
};


new object $help_ui: $user_interfaces;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $has_commands local = #[["@help", [["@help", "*", "@help <any>", 'help_cmd, #[[1, ['any, []]]]]]], ["help", [["help", "*", "help <any>", 'help_cmd, #[[1, ['any, []]]]]]]];
var $has_commands shortcuts = #[["?*", ['help_cmd, ["?", 1]]]];
var $help_ui current = 1;
var $help_ui history = [$help_coldcore];
var $root manager = $help_ui;
var $help_ui index = 0;
var $command_cache modules = [];
var $root managed = [$help_ui];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;

root method .init_help_ui() {
    history = [$help_lib.default_node()];
    current = 1;
};

public method .current_node() {
    return history[current];
};

protected method .help_cmd() {
    arg cmdstr, cmd, args;
    var o, opt, optval, way, node, links, i;
    
    (> .perms(caller(), 'command) <);
    o = #[["?", "h?istory"], ["<", "b?ack"], [">", "f?orward"], ["!", "fix"], ["#", "l?inks"], ["^", "u?p"]];
    args = (> $parse_lib.opt(args, @o.values()) <);
    opt = args[2];
    args = args[1];
    if (!opt) {
        if (!args) {
            if (cmd == "?")
                node = .current_node();
            else
                node = $help_lib.default_node();
        } else {
            args = args.join();
            if ((args[1]) in (o.keys())) {
                opt = o[args[1]];
                if ((args.length()) > 1)
                    optval = args.subrange(2);
            } else if ((o = match_template(args, "* in *"))) {
                if (!(i = $help_index.match_children(o[3])))
                    return ("\"" + (o[3])) + "\" is not a help index.";
                if ((!(o[1])) || ((o[1]) == "#"))
                    node = i;
                else if (!(node = (| i.match_begin(o[1]) |)))
                    return ((("Unable to find help on \"" + (o[1])) + "\" in the ") + (i.name())) + " index.";
            } else {
                catch ~nonode, ~ambig {
                    node = (> .parse_help_reference(args) <);
                } with {
                    if (error() == ~ambig) {
                        o = (traceback()[1])[3];
                        i = (.get_rows()) - 3;
                        .tell(((("Topic '" + args) + "' has ") + (o.length())) + " possibilities:");
                        if ((o.length()) > i) {
                            i--;
                            .tell((sublist(o, 1, i).mmap('namef, 'ref)).prefix("    "));
                            .tell(("[truncated, " + ((o.length()) - i)) + " more matches]");
                        } else {
                            .tell((o.mmap('namef, 'ref)).prefix("    "));
                        }
                        return "---";
                    }
                    return (traceback()[1])[2];
                }
            }
        }
    } else {
        // since all options override each other, just use the last one.
        optval = (opt[listlen(opt)])[4];
        opt = ((opt[listlen(opt)])[1]) || ((opt[listlen(opt)])[2]);
        if (dict_contains(o, opt[1]))
            opt = o[opt[1]];
    }
    if (!node) {
        catch ~nonode {
            switch (opt) {
                case "u?p":
                    o = ((.current_node()).parents())[1];
                    while ((o.is($help_node)) && (o.holder()))
                        o = (o.parents())[1];
                    if ((!(o.is($help_node))) || (o.top_of_help_heirarchy()))
                        return "You are at the top of this help node heirarchy.";
                    node = o;
                case "h?istory":
                    return ._help_node_history();
                case "b?ack":
                    if (!optval)
                        optval = "";
                    node = (> ._navigate_node_history("<" + optval) <);
                case "f?orward":
                    if (!optval)
                        optval = "";
                    node = (> ._navigate_node_history(">" + optval) <);
                case "fix":
                    .tell("Fixing your help history.");
                    for node in (history) {
                        if ((!valid(node)) || (!(node.has_ancestor($help_node))))
                            history = setremove(history, node);
                    }
                    current = listlen(history);
                    return;
                case "l?inks":
                    node = .current_node();
                    links = node.links();
                    if (!links) {
                        .tell(("No links from " + (node.name())) + ".");
                    } else {
                        .tell(("Links from " + (node.name())) + ":");
                        .tell(map i in (links) to (strfmt("%30l %s", @i)).prefix("    "));
                    }
                    if (node.group()) {
                        links = ((node.parents())[1]).children();
                        links = filter o in (links) where ((!(o.nolist())) && (o != node));
                        if (!links)
                            return ("No group nodes with " + (node.name())) + ".";
                        .tell(("Group nodes with " + (node.name())) + ":");
                        .tell(map i in (links) to (strfmt("%30e %s", i.name(), i)).prefix("    "));
                        .tell("---");
                    }
                    return;
                default:
                    throw(~stop, ("Unknown option '-" + opt) + "'");
            }
        } with {
            return (traceback()[1])[2];
        }
    }
    .set_help_node(node);
    .tell_help_node(node);
};

protected method .last_visited() {
    (> .perms(sender()) <);
    return last_visited;
};

public method .help_index() {
    return index;
};

protected method ._back_help_node() {
    var pos;
    
    pos = current - 1;
    if (pos >= 1) {
        current = pos;
        return history[current];
    }
    throw(~nonode, "You are at the start of your help node history, use \"??\" to list the history.");
};

protected method ._forward_help_node() {
    var pos;
    
    pos = current + 1;
    if ((pos <= ($help_lib.history_cap())) && (pos <= (history.length()))) {
        current = pos;
        return history[current];
    }
    throw(~nonode, "You are at the end of your help node history, use \"??\" to list the history.");
};

protected method .set_help_node() {
    arg node, @navhist;
    var cur;
    
    if (node.index())
        index = node.index();
    cur = history[current];
    if (node in history) {
        if ((history[current]) == node)
            return;
        if (navhist)
            return (current = node in history);
        else
            history = setremove(history, node);
    } else if (listlen(history) >= ($help_lib.history_cap())) {
        history = sublist(history, 1, $help_lib.history_cap());
    }
    current = cur in history;
    if (navhist) {
        if (current)
            history = insert(history, current + 1, node);
    } else {
        history = (history ? sublist(history, 1, current) : []) + [node];
    }
    current = node in history;
};

protected method ._navigate_node_history() {
    arg str;
    var node, r, hist, match;
    
    while ((r = regexp(str, "^ *([<>]) *([^<>]*) *"))) {
        if (r[2]) {
            if ((r[1]) == "<")
                hist = (sublist(history, 1, current - 1).reverse()) + (sublist(history, current).reverse());
            else
                hist = sublist(history, current + 1) + sublist(history, 1, current);
            r = r[2];
            for node in (hist) {
                if (node.match_name(r)) {
                    .set_help_node(node);
                    match++;
                    break;
                }
            }
            if (!match)
                throw(~nonode, ("There is no node \"" + r) + "\" in your history.");
        } else if ((r[1]) == "<") {
            (| .set_help_node(._back_help_node()) |);
        } else {
            (| .set_help_node(._forward_help_node()) |);
        }
        str = strsed(str, "^ *([<>]) *([^<>]*) *", "");
    }
    return history[current];
};

protected method ._help_node_history() {
    var node, line;
    
    .tell("Help node history:");
    for node in [1 .. history.length()] {
        line = "   ";
        if (node == current)
            line = "=> ";
        catch any {
            .tell(line + ((history[node]).name()));
        } with {
            history = history.delete(node);
            .set_help_node(history[1]);
            .tell(line + ">> ERROR: INVALID NODE IN HISTORY <<");
        }
    }
    .tell("---");
};

protected method .tell_help_node() {
    arg node;
    var out, len, clen, line, n, name, changed, sibs, end, start, flen;
    
    // len = .linelen() % 2 ? .linelen() - 1 : .linelen();
    len = .linelen();
    name = node.node_name();
    while (strlen(name) >= (len - 10)) {
        name = substr(name, (":" in name) + 1);
        changed++;
    }
    if (changed)
        name = ".." + name;
    line = strfmt("%*{-}c", len, (" " + name) + " ");
    .tell(line);
    .ptell(node.body(), #[['type, 'help], ['ctype, 'ctext]]);
    if (node.group()) {
        line = (start = (end = ""));
        sibs = filter n in (((node.parents())[1]).children()) where (!(| n.nolist() |));
        flen = (((strlen((sibs.mmap('small_name)).join()) + (listlen(sibs) * 3)) + 3) + strlen(end)) + strlen(start);
        while (flen > len) {
            if ((listlen(sibs) / 2) >= (node in sibs)) {
                sibs = sublist(sibs, 1, listlen(sibs) - 1);
                if (!end)
                    end = ".. ";
            } else {
                sibs = sublist(sibs, 2);
                if (!start)
                    start = ".. ";
            }
            flen = (((strlen((sibs.mmap('small_name)).join()) + (listlen(sibs) * 3)) + 3) + strlen(end)) + strlen(start);
        }
        if (sibs) {
            for n in (sibs) {
                if (n == node)
                    line += ". ";
                else if (n.holder())
                    line += (((n.name()).word(1, "|")).word(1)) + " ";
                else
                    line += ("[" + (((n.name()).word(1, "|")).word(1))) + "] ";
            }
            line = (((" " + start) + line) + end).center(len, "-", 'both);
        } else {
            line = "-" * len;
        }
    } else {
        line = "-" * len;
    }
    .tell(["", line]);
};

root method .uninit_help_ui() {
    (| clear_var('history) |);
    (| clear_var('current) |);
    (| clear_var('index) |);
};

protected method .help_node_history() {
    return history;
};

protected method .parse_help_reference() {
    arg str;
    var node, cnode, current, indices, len, links, i, matches, m;
    
    if ((str[1]) == "$") {
        node = (| $object_lib.to_dbref(str) |);
        if (node && (node.help_node()))
            node = node.help_node();
        else if ((!node) || (!(node.has_ancestor($help_node))))
            throw(~nonode, ("\"" + str) + "\" is not a help node, and does not have a help node assigned to it.");
        return node;
    }
    if ((m = match_template(str, "*=*"))) {
        if (!(m[2]))
            throw(~nonode, ("Search in " + (m[1])) + " for nothing?");
        else if (match_template(m[1], "g?roup"))
            return (> .find_help_in_group(m[2]) <);
        else if (match_template(m[1], "l?inks"))
            return (> .find_help_in_links(m[2]) <);
        else if (match_template(m[1], "i?ndex"))
            return (> .find_help_in_index(m[2]) <);
        if (!(i = $help_index.match_children(m[1])))
            throw(~nonode, ("\"" + (m[1])) + "\" is not a help index.");
        if ((m[2]) == "#")
            return i;
        if (!(node = (| i.match_begin(m[2]) |)))
            throw(~nonode, ((("Unable to find help on \"" + (m[2])) + "\" in the ") + (i.name())) + " index.");
        return node;
    }
    if (">" in str)
        return (> .step_help_nodes(split(str, " *> *")) <);
    if ((m = regexp(str, "(\.[a-z][0-9a-z_]+)\( *\)"))) {
        str = m[1];
    } else if ((m = regexp(str, " *([a-z][0-9a-z_]+)\( *\)"))) {
        i = "help_func_" + (m[1]);
        if ((node = (| lookup(tosym(i)) |)))
            return node;
        else
            throw(~nonode, ("Unable to find help on function " + (m[1])) + "()");
    }
    return (| .find_help_in_links(str) |) || ((| .find_help_in_group(str) |) || (> .find_help_in_index(str) <));
};

public method .find_help_in_links() {
    arg str;
    var links, node, index;
    
    links = ((| .current_node() |) || ($help_lib.default_node())).links();
    for node in (links.keys()) {
        if (match_begin(node, str)) {
            node = links[node];
            return node;
        }
    }
    throw(~nonode, ("Unable to find link \"" + str) + "\".");
};

public method .find_help_in_group() {
    arg str;
    var sibling, node;
    
    node = (.current_node()) || ($help_lib.default_node());
    if (node.group()) {
        for sibling in (((node.parents())[1]).children()) {
            if ((sibling == node) || ((sibling.nolist()) || (sibling.holder())))
                continue;
            if (sibling.match_name(str))
                return sibling;
        }
    }
    throw(~nonode, ("Unable to find group node \"" + str) + "\".");
};

public method .find_help_in_index() {
    arg str;
    var indices, i, node, index, matches, len;
    
    // get from $help_lib to keep in a consistent prioritized order
    indices = $help_lib.indices();
    
    // put the 'current' node at the end, and use it first
    if ((i = sender().help_index())) {
        indices = setremove(indices, i);
        indices = setadd(indices, i);
    }
    
    // loop through the indices backwards
    len = listlen(indices);
    matches = [];
    for i in [1 .. len] {
        i = (len - i) + 1;
        catch any {
            if ((node = (| (indices[i]).exact_match(str) |))) {
                // return the first perfect match
                return node;
            } else if ((node = (> (indices[i]).match_begin(str) <))) {
                matches = setadd(matches, node);
            }
        } with {
            if (error() == ~ambig)
                matches += ((traceback()[1])[3]) || [];
        }
    }
    if (listlen(matches) == 1)
        return matches[1];
    else if (matches)
        throw(~ambig, "More than one match.", matches);
    throw(~nonode, ("Unable to find help on \"" + str) + "\".");
};

protected method .reset_help_history() {
    history = [$help_coldcore];
    current = 1;
};

protected method .clear_help_history() {
    (| clear_var('history) |);
    (| clear_var('current) |);
};

public method .fmt_help_from() {
    arg from;
    var node, c, name;
    
    c = .task_connection();
    for node in (from.traverse()) {
        name = (node.name()).word(1, "|");
        c.write(["", name, "=" * strlen(name)]);
        if (!(node.holder()))
            c.write($parse_lib.filter_ctext(node.body(), #[['formatter, $flat_format]]));
    }
};

protected method .step_help_nodes() {
    arg hist;
    var sn, node;
    
    // start from the same base
    .set_help_node($help_lib.default_node());
    for sn in (hist) {
        if ((node = (| .find_help_in_links(sn) |))) {
            .set_help_node(node);
            .tell(("Following link for '" + sn) + "'");
        } else if ((node = (| .find_help_in_group(sn) |))) {
            .set_help_node(node);
            .tell(("Following group for '" + sn) + "'");
        } else {
            catch any {
                node = (> .find_help_in_index(sn) <);
                .set_help_node(node);
                .tell(("Found '" + sn) + "' in index");
            } with {
                throw(~stop, (traceback()[1])[2]);
            }
        }
    }
    return node;
};


new object $editor_reference: $has_commands;

var $root manager = $editor_reference;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root created_on = 820684615;
var $root inited = 1;
var $editor_reference active_editor = 0;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[["@mcp-upload-session", [["@mcp-upload-session", "*", "@mcp-upload-session <descendant of $editor_session>", 'mcp_upload_cmd, #[[1, ['descendant, [$editor_session]]]]]]], ["@edit", [["@edit", "*", "@edit <any>", 'edit_cmd, #[[1, ['any, []]]]]]]];
var $editor_reference bg_sessions = 0;
var $root managed = [$editor_reference];
var $root defined_settings = #[["local-editor", #[['parse, ['parse_local_editor]]]]];
var $root settings = #[["local-editor", 'none]];

protected method .reinvoke_editor() {
    arg @session;
    var i, t, name;
    
    t = "";
    [(session ?= active_editor), (name ?= "")] = session;
    if (session == 0)
        return "No session to resume.";
    bg_sessions ?= [];
    if (active_editor && ((active_editor != session) || (!(| session.is_resumable() |))))
        t = (.store_editor()) + " ";
    if ((!valid(session)) || (!(session in (bg_sessions + [active_editor])))) {
        active_editor = 0;
        return "Invalid session - editor cleared.";
    }
    if (!(| session.is_resumable() |))
        return "The session is not resumable, you can use '@edit +clean' to remove it";
    active_editor = session;
    bg_sessions = bg_sessions.setremove(active_editor);
    bg_sessions = filter i in (bg_sessions) where (valid(i));
    .add_parser($editor_parser);
    return [t, ("Resumed editing " + ((.active_editor()).session_name())) + ".", "Type 'help' to list available commands."];
};

public method .invoke_editor() {
    arg object, method, initial_text, cdata;
    
    // finishing object, finishing method, initial text, client data;
    if (active_editor != 0)
        throw(~misc, "Editor already active");
    (> object.perms(sender()) <);
    active_editor = $editor_session.spawn();
    if (active_editor.startup(object, method, initial_text, cdata))
        .add_parser($editor_parser);
};

public method .quit_editor() {
    if (active_editor == 0)
        throw(~misc, "No active editor.");
    .perms(sender(), active_editor);
    .del_parser($editor_parser);
    active_editor.destroy();
    clear_var('active_editor);
};

public method .store_editor() {
    var t;
    
    if (active_editor) {
        (sender() == this()) || (> .perms(sender(), active_editor) <);
        .del_parser($editor_parser);
        bg_sessions = (bg_sessions ? bg_sessions : []).setadd(active_editor);
        t = active_editor;
        active_editor = 0;
        return "Editor session %s saved.".format(t);
    }
    return "No active editor.";
};

public method .active_editor() {
    return active_editor;
};

public method .cleanup_sessions() {
    arg @disregard;
    var out, s;
    
    (sender() == $housekeeper) || (> .perms(sender(), this()) <);
    out = [];
    for s in (bg_sessions || []) {
        if (valid(s)) {
            if (s.cleanup_session())
                s.destroy();
            else
                out = setadd(out, s);
        }
    }
    bg_sessions = out;
    if (valid(active_editor) && (active_editor.cleanup_session())) {
        active_editor.destroy();
        clear_var('active_editor);
    }
    return "Clean and invalid sessions cleared.";
};

public method .edit_cmd() {
    arg cmdstr, com, args;
    var syn, num, sess, out, type, i, e, bg;
    
    (> .perms(caller(), 'command) <);
    syn = "@edit <object reference> [+type=...]";
    args = args.trim();
    if (!args) {
        // list sessions
        out = [];
        e = .active_editor();
        if (e) {
            if ($editor_parser in (.parsers()))
                out += ["** %0 " + (e.session_name())];
            else
                out += ["   %0 " + (e.session_name())];
        }
        bg = .background_editor_sessions();
        for sess in [1 .. listlen(bg)]
            out += [(("   %" + sess) + " ") + ((bg[sess]).session_name())];
        if (out)
            return ["Editor Sessions:"] + out;
        return "No editor sessions.";
    } else if ((args[1]) == "%") {
        // resume session
        args = substr(args, 2);
        if ((!args) || ((args[1]) == " ")) {
            num = 0;
        } else {
            catch ~nonum
                num = (> args.to_number() <);
            with
                return (traceback()[1])[2];
        }
        if (!num) {
            if (.active_editor())
                return .reinvoke_editor(.active_editor(), "%0");
            else if (.background_editor_sessions())
                sess = (.background_editor_sessions())[1];
            else
                return "No sessions to resume.";
        } else {
            if ((listlen((.background_editor_sessions()) || []) < num) || (num < 0))
                return ("There is not an editor session %" + num) + ".";
            sess = (.background_editor_sessions())[num];
        }
        return .reinvoke_editor(sess, "%" + num);
    } else {
        args = (> $parse_lib.opt(args, "t?ype", "c?lean") <);
        if ((i = "c?lean" in ((args[2]).slice(1))))
            return .cleanup_sessions();
        if ((i = "t?ype" in ((args[2]).slice(1))))
            type = ((args[2])[i])[4];
        type ?= "any";
        catch ~objnf, ~namenf, ~ambig, ~symbol
            args = replace(args, 1, (> $parse_lib.ref((args[1]).join()) <));
        with
            return (traceback()[1])[2];
        return .edit(@args, type);
    }
};

public method .local_editor() {
    return .get_setting("local-editor", $editor_reference);
};

protected method .mcp_upload_cmd() {
    arg cmdstr, cmd, session;
    var text, status, tmp;
    
    (> .perms(caller(), 'command) <);
    text = (| .read("Reading the editor session text...") |);
    if (type(text) != 'list)
        return "Upload failed.";
    if (!(session in bg_sessions))
        return "Illegal session - upload failed.";
    tmp = active_editor;
    active_editor = session;
    catch any {
        status = session.mcp_upload(text);
    } with {
        .tell_traceback(traceback());
        status = "Compilation failed.";
    }
    active_editor = tmp;
    return status[2];
};

public method .edit_sessions_notify() {
    var e, s, bg;
    
    if (bg_sessions) {
        .tell("<editor> Use @edit to resume the following editor sessions:");
        e = .active_editor();
        if (e) {
            if ($editor_parser in (.parsers()))
                .tell("<editor> ** %0 " + (e.session_name()));
            else
                .tell("<editor>    %0 " + (e.session_name()));
        }
        bg = .background_editor_sessions();
        for s in [1 .. listlen(bg)]
            .tell((("<editor>    %" + s) + " ") + ((bg[s]).session_name()));
    } else if (.active_editor()) {
        .tell("<editor> Disconnected from an active session. Use @edit %0 to resume.");
    }
};

public method .do_save() {
    arg @info;
    
    // The purpose of this method is to ensure that save is ran with
    // this user's perms
    if ((!(sender().has_ancestor($editor_session))) || (!((sender().startup_sender()) == this())))
        throw(~perm, "Permission denied");
    return (> (info[1]).(info[2])(info[3], info[4]) <);
};

public method .background_editor_sessions() {
    return bg_sessions || [];
};

public method .parse_local_editor() {
    arg value, @args;
    var styles;
    
    value = (| (styles = #[["None", 'none], ["MCP", 'mcp]])[value] |);
    if (!value)
        throw(~wrong, "Local editor must be one of: " + ((styles.keys()).to_english("", " or ")));
    return value;
};

protected method .edit() {
    arg ref, opts, type;
    
    if (.active_editor()) {
        .tell("Storing active editor..");
        .store_editor();
    }
    catch ~quota
        return .new_editor_session(ref, opts, type);
    with
        return ["You do not have enough quota remaining."];
};


new object $channel_ui: $user_interfaces;

var $root manager = $channel_ui;
var $channel_ui active_channels = #[];
var $root flags = ['variables, 'methods, 'code, 'fertile, 'core, 'general_cache];
var $root created_on = 838251646;
var $channel_ui channel_dict = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[["@desc-c?hannel", [["@desc-c?hannel", "* as *", "@desc-c?hannel <any> as <any>", 'describe_channel_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["@join-lock-channel|@jlc", [["@join-lock-channel|@jlc", "* with|to *", "@join-lock-channel|@jlc <any> with|to <any>", 'channel_add_lock_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["@leave-lock-channel|@llc", [["@leave-lock-channel|@llc", "* with|to *", "@leave-lock-channel|@llc <any> with|to <any>", 'channel_add_lock_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["@use-lock-channel|@ulc", [["@use-lock-channel|@ulc", "* with|to *", "@use-lock-channel|@ulc <any> with|to <any>", 'channel_add_lock_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["@add-channel-manager|@acm", [["@add-channel-manager|@acm", "* to *", "@add-channel-manager|@acm <user> to <any>", 'channel_add_manager, #[[1, ['user, []]], [3, ['any, []]]]]]], ["@del-channel-manager|@dcm", [["@del-channel-manager|@dcm", "* from *", "@del-channel-manager|@dcm <user> from <any>", 'channel_del_manager, #[[1, ['user, []]], [3, ['any, []]]]]]], ["@add-ch?annel|@addcom", [["@add-ch?annel|@addcom", "*", "@add-ch?annel|@addcom <any>", 'addcom_cmd, #[[1, ['any, []]]]]]], ["@del-ch?annel|@delcom", [["@del-ch?annel|@delcom", "*", "@del-ch?annel|@delcom <any>", 'delcom_cmd, #[[1, ['any, []]]]]]], ["@purge-channel", [["@purge-channel", "*", "@purge-channel <any>", 'channel_purge_cmd, #[[1, ['any, []]]]]]], ["@ch?annels", [["@ch?annels", "*", "@ch?annels <any:+f?ull +d?etailed>", 'channels_cmd, #[[1, ['any_opt, ["f?ull", "d?etailed"]]]]]]], ["@channel-paste", [["@channel-paste", "* to", "@channel-paste <any> to", 'channel_page_cmd, #[[1, ['any, []]]]]]]];
var $root inited = 1;
var $root managed = [$channel_ui];
var $channel_ui channel_creation = 1;
var $root trusted_by = [$channel_db];
var $channel_ui credits = ["Chuck and Brad"];
var $command_cache modules = [];
var $command_cache commands = 0;
var $command_cache shortcuts = 0;

public method .broadcast() {
    arg channel, msg;
    var q, spammer_name, message, target, user;
    
    (> .perms(sender()) <);
    
    // is this really a command?. If so, do the command.
    catch any {
        switch (msg) {
            case "who":
                if ((channel in ($channel_db.system_channels())) && (!($sys.is_system(sender()))))
                    return "Sorry, that's a listen only channel.";
                return .channel_members(channel);
            case "off":
                .channel_off(channel);
                return;
            case "on":
                .channel_on(channel);
                return;
        }
    } with {
        return (traceback()[1])[2];
    }
    if ((channel in ($channel_db.system_channels())) && (channel != 'All))
        return "Sorry, that's a listen only channel.";
    if (!(active_channels.contains(channel)))
        return "You must be on a channel to send a message to it.";
    spammer_name = .name();
    if (((msg[1]) == "'") || ((msg[1]) == "-")) {
        target = ((msg.explode())[1]).subrange(2);
        msg = msg.subrange((target.length()) + 3);
        catch ~namenf
            user = $user_db.match(target);
        with
            return target + " is not a valid user.";
        if (!(user.connected()))
            return (user.name()) + " is not connected.";
        if (!(user.channel_member(channel)))
            return (user.name()) + " is not a member of that channel.";
        spammer_name += (" (to " + (user.name())) + ")";
    }
    
    // check for poses, thinking, etc.
    switch (msg[1]) {
        case ":":
            message = (spammer_name + " ") + (msg.subrange(2));
        case "%":
            message = ((spammer_name + " . o O ( ") + (msg.subrange(2))) + " )";
        case "!":
            (> .channel_moderator_ok() <);
            message = msg.subrange(2);
        default:
            message = msg ? ($code_lib.punctuation_type(msg)) : "say";
            message = ((((spammer_name + " ") + message) + "s, \"") + msg) + "\"";
    
            // message = spammer_name + ": " + msg;
    }
    ._broadcast(channel, message);
};

protected method .channel_on() {
    arg channel;
    
    if (!(active_channels.contains(channel))) {
        active_channels = active_channels.add(channel, 1);
        if (channel in ($channel_db.system_channels()))
            .tell(("<" + channel) + "> You have joined this channel");
        else
            .broadcast(channel, ":has joined this channel.");
    } else {
        .tell("You are already on this channel.");
    }
};

public method .channel_moderator_ok() {
    (> .check_mojo() <);
    return 1;
};

protected method .channel_off() {
    arg channel;
    
    if (active_channels.contains(channel)) {
        if (channel in ($channel_db.system_channels()))
            .tell(("<" + channel) + "> You have left this channel.");
        else
            .broadcast(channel, ":has left this channel.");
        active_channels = active_channels.del(channel);
    } else {
        .tell("You are not on this channel.");
    }
};

public method .listen_channel() {
    arg channel;
    
    if (active_channels.contains(channel))
        return 1;
    return 0;
};

public method .channel_members() {
    arg channel, @full;
    var q, members, name, who, line;
    
    members = [];
    [(full ?= 0)] = full;
    if (full) {
        line = ("All members of channel " + channel) + " ('*'=listening, '!'=not connected):";
        who = $user_db.user_dbrefs();
    } else {
        line = ("Connected members of channel " + channel) + " ('*'=listening):";
        who = $user_db.connected();
    }
    for q in (who) {
        if (!valid(q))
            continue;
        if (q.channel_member(channel)) {
            if (q.connected())
                name = " " + (q.name());
            else
                name = "!" + (q.name());
            if (q.listen_channel(channel))
                members += ["*" + name];
            else
                members += [" " + name];
        }
    }
    return ([line] + ((members.vcolumnize(4, (.linelen()) - 4)).prefix("    "))) + ["---"];
};

public method .channel_alias() {
    arg ch_alias;
    
    return (| channel_dict[ch_alias] |) || "";
};

public method .channel_msg() {
    arg channel, msg;
    
    (caller() == definer()) || (> .perms(sender(), 'system) <);
    if ((channel == 'All) || (active_channels.contains(channel)))
        .tell((("<" + channel) + "> ") + msg);
};

protected method .init_channel_ui() {
    channel_dict = #[];
    active_channels = #[];
};

protected method .addcom_cmd() {
    arg cmdstr, cmd, args;
    var elements, db, channel, lowerchannel, msg;
    
    (> .perms(caller(), 'command) <);
    elements = args.explode("=");
    if ((elements.length()) != 2) {
        return "Syntax: @addcom <alias>=<channel_name>";
    } else if (channel_dict.contains(elements[1])) {
        return "You are already using that alias for a channel.";
    } else {
        catch any
            channel = tosym(elements[2]);
        with
            throw(~stop, ("Channel '" + (elements[2])) + "' contains invalid characters.");
        lowerchannel = tosym((elements[2]).lowercase());
        db = (| $channel_db.search(lowerchannel) |) || 0;
        if (type(db) == 'list) {
            if ((type(db[3]) == 'frob) && ((!((db[3]).try(sender()))) && (!($sys.is_system(sender())))))
                return ("Sorry, channel " + (db[1])) + " is join-locked.";
            msg = (("Channel " + (elements[2])) + " added with alias ") + (elements[1]);
        } else if (.can_create_channel()) {
            db = [channel, 0, 0, 0, sender(), [sender()], 0, 0];
            $channel_db.insert(lowerchannel, db);
            msg = (("Channel " + (elements[2])) + " created with alias ") + (elements[1]);
        } else {
            return "Sorry, that channel doesn't exist, and you are not authorized to create new channels.";
        }
    }
    $channel_db.value_changed(lowerchannel, db.replace(2, (db[2]) + 1));
    channel_dict = channel_dict.add(elements[1], db[1]);
    .channel_on(db[1]);
    return msg;
};

protected method .delcom_cmd() {
    arg cmdstr, cmd, args;
    var db, channel, del_from_db, msg, dict_var;
    
    (> .perms(caller(), 'command) <);
    del_from_db = 1;
    msg = ("Channel alias " + args) + " deleted.";
    if (!args)
        return ("Syntax: " + cmd) + " <channel>";
    dict_var = (| channel_dict[args] |);
    channel = (| (((channel_dict[args]).to_string()).lowercase()).to_symbol() |) || 0;
    if (type(channel) == 'symbol) {
        db = (| $channel_db.search(channel) |) || 0;
        if (type(db) == 'list) {
            if ((type(db[4]) == 'frob) && ((!((db[4]).try(sender()))) && (!($sys.is_system(sender())))))
                return "Channel leave locked, you can't leave it!";
        } else {
            del_from_db = 0;
            msg = ("That channel does not seem to be in the channel database.  Channel alias " + args) + " deleted.";
        }
    } else {
        return "You do not have that channel alias defined.";
    }
    if (del_from_db)
        $channel_db.value_changed(channel, db.replace(2, (db[2]) - 1));
    if (active_channels.contains(dict_var))
        .channel_off(dict_var);
    channel_dict = channel_dict.del(args);
    return msg;
};

public method .channel_dict() {
    return channel_dict;
};

public method .active_channels() {
    return active_channels;
};

public method .can_create_channel() {
    if ((sender().has_ancestor($user)) && (($channel_ui.channel_creation()) || ($sys.is_system(sender()))))
        return 1;
    else
        return 0;
};

protected method .channel_add_lock_cmd() {
    arg cmdstr, cmd, this, prep, str;
    var channel, db, lock, mode, modestr;
    
    (> .perms(caller(), 'command) <);
    if ((cmd[2]) == "j") {
        mode = 3;
        modestr = "join";
    } else if ((cmd[2]) == "l") {
        mode = 4;
        modestr = "leave";
    } else {
        mode = 8;
        modestr = "use";
    }
    channel = tosym(this.lowercase());
    db = (| $channel_db.search(channel) |) || 0;
    if (type(db) == 'list) {
        if ((!(sender() in (db[6]))) && (!($sys.is_system(sender())))) {
            return "Sorry, you're not on the manager list for that channel.";
        } else if ((str.length()) == 0) {
            $channel_db.value_changed(channel, db.replace(mode, 0));
            return ((("You un-" + modestr) + "lock channel ") + (db[1])) + ".";
        } else {
            catch ~objnf, ~parse {
                lock = $lock_frob.parse(str, sender());
                $channel_db.value_changed(channel, db.replace(mode, lock));
                return ((((("You " + modestr) + "lock channel ") + (db[1])) + " with ") + (lock.lock_name('thing))) + ".";
            } with {
                switch (error()) {
                    case ~objnf:
                        return "Object not found in lock string.";
                    case ~parse:
                        return "Invalid lock string.";
                }
            }
        }
    } else {
        return "Channel not found, nothing locked.";
    }
};

protected method .describe_channel_cmd() {
    arg cmdstr, cmd, channel, prep, desc;
    var db, channel;
    
    (> .perms(caller(), 'command) <);
    channel = (| tosym(channel.lowercase()) |) || 0;
    if (channel == 0)
        return "@desc-ch?annel <channel> as <description>";
    db = (| $channel_db.search(channel) |) || 0;
    if (db == 0)
        return "That channel does not exist.";
    if ((!(sender() in (db[6]))) && (!($sys.is_system(sender()))))
        return "You are not a manager for channel " + (db[1]);
    $channel_db.value_changed(channel, db.replace(7, desc));
    return "Description updated.";
};

public method ._broadcast() {
    arg channel, message;
    var q;
    
    if (!(caller() in [$channel_ui, $user, $sys, $guest]))
        throw(~perm, "You are not allowed to call $channel_ui._broadcast() directly");
    for q in ($user_db.connected())
        q.channel_msg(channel, message);
};

public method .channel_add_manager() {
    arg cmdstr, cmd, user, prep, channel;
    var db, channel;
    
    channel = (| tosym(channel.lowercase()) |) || 0;
    if (channel == 0)
        return "@add-channel-manager|@acm <user> to <channel>";
    db = (| $channel_db.search(channel) |) || 0;
    if (db == 0)
        return "That channel does not exist.";
    if ((sender() != (db[5])) && (!($sys.is_system(sender()))))
        return "You are not the channel owner.";
    if (user in (db[6]))
        return ((user.name()) + " is already a manager of channel ") + (db[1]);
    $channel_db.value_changed(channel, db.replace(6, [@db[6], user]));
    return "Manager added.";
};

public method .channel_del_manager() {
    arg cmdstr, cmd, user, prep, channel;
    var db, channel;
    
    channel = (| tosym(channel.lowercase()) |) || 0;
    if (channel == 0)
        return "@add-channel-manager|@acm <user> from <channel>";
    db = (| $channel_db.search(channel) |) || 0;
    if (db == 0)
        return "That channel does not exist.";
    if ((sender() != (db[5])) && (!($sys.is_system(sender()))))
        return "You are not the channel owner.";
    if (!(user in (db[6])))
        return ((user.name()) + " is not a manager of channel ") + (db[1]);
    $channel_db.value_changed(channel, db.replace(6, (db[6]).del(user)));
    return "Manager deleted.";
};

public method .channel_creation() {
    return channel_creation;
};

public method .uninit_channel_ui() {
    var c, channel, db;
    
    for c in (.channel_dict()) {
        if ((| active_channels[c[2]] |) || 0)
            .channel_off(c[2]);
        channel = (| tosym(((c[2]).to_string()).lowercase()) |) || 0;
        if (type(channel) == 'symbol) {
            db = (| $channel_db.search(channel) |) || 0;
            if (type(db) == 'list)
                $channel_db.value_changed(channel, db.replace(2, (db[2]) - 1));
        }
    }
    active_channels = #[];
    channel_dict = #[];
};

public method .channel_purge_cmd() {
    arg cmdstr, cmd, channel;
    var db, channel, connected, u;
    
    channel = (| tosym(channel.lowercase()) |) || 0;
    if (channel == 0)
        return "@purge-channel <channel>";
    db = (| $channel_db.search(channel) |) || 0;
    if (db == 0)
        return "That channel does not exist.";
    if ((sender() != (db[5])) && (!($sys.is_system(sender()))))
        return "You are not the channel owner.";
    $channel_db.remove(channel);
    connected = $user_db.connected();
    for u in ((((($user_db.database()).to_dict()).to_list()).slice(2)).compress()) {
        if ((u in connected) && (((u.channel_dict()).invert()).contains(db[1])))
            u.tell((("<" + (db[1])) + "> Channel deleted by ") + (sender().name()));
        (| u._del_active_channel(db[1]) |);
        (| u._del_channel_dict(((u.channel_dict()).invert())[db[1]]) |);
        pause();
    }
    return "Channel deleted.";
};

private method ._del_active_channel() {
    arg key;
    
    active_channels = active_channels.del(key);
};

public method ._del_channel_dict() {
    arg key;
    
    channel_dict = channel_dict.del(key);
};

public method .channel_member() {
    arg channel;
    
    return channel in dict_values(channel_dict || #[]);
};

public method .channel_command() {
    arg cmd, args, opts, detailed, full;
    var ch, syn, cmd;
    
    syn = ("Syntax: " + cmd) + " <channel> <command>";
    if (listlen(args) < 2)
        return [syn, "Where <command> is one of: WHO, OFF, ON, or INFO"];
    [ch, cmd, @args] = args;
    switch (cmd) {
        case "who":
            if ((ch in ($channel_db.system_channels())) && (!($sys.is_system(this()))))
                return "Sorry, that's a listen only channel.";
            return .channel_members(ch, full);
        case "off":
            .channel_off(ch);
            return;
        case "on":
            .channel_on(ch);
            return;
        case "info":
            return;
        default:
            return ("Unknown @channel command: " + cmd) + ", should be: WHO, OFF, ON or INFO";
    }
};

protected method .channels_cmd() {
    arg cmdstr, cmd, args;
    var opts, f, d, cur_channels, cd_keys, cd_values, i, alias, db, active, msg, match_with, match_pattern, tmp, form, add, o;
    
    (> .perms(caller(), 'command) <);
    [args, opts] = args;
    o = opts.slice(1);
    if ((f = (| "f?ull" in o |)))
        f = (opts[f])[3];
    if ((d = (| "d?etailed" in o |)))
        d = (opts[d])[3];
    if (listlen(args) > 1) {
        catch any {
            cmd = (| ($channel_db.search(args[1]))[1] |);
            return .channel_members(cmd, f);
        } with {
            return (traceback()[1])[2];
        }
    }
    cd_keys = channel_dict.keys();
    cd_values = channel_dict.values();
    cur_channels = f ? ((($channel_db.database()).values()).slice(1)) : cd_values;
    if (args) {
        match_with = (| .get_setting("match-with", $programmer) |) || 'match_pattern;
        match_pattern = (| (args[1])[1] |) || ((| .get_setting("match-default", $programmer) |) || "*");
        cur_channels = filter f in (cur_channels) where ((f.to_string()).(match_with)(match_pattern) != 0);
    }
    if (!cur_channels)
        return "No channels found.";
    msg = [];
    add = [];
    for i in (cur_channels) {
        alias = (| cd_keys[i in cd_values] |) || "";
        db = (| $channel_db.search(tostr(i)) |);
        if (type(db) == 'list) {
            msg += [[(active_channels.contains(i)) ? "*" : " ", alias, tostr(db[1]), (db[7]) || "<no description>"]];
            form = "%26r: %50l";
            if (d) {
                tmp = [form.format("Number of users", tostr(db[2])), form.format("Owner", (db[5]).name()), form.format("Managers", ((db[6]).mmap('namef, 'name)).to_english())];
                if (db[3])
                    tmp += [form.format("Join Lock", (db[3]).lock_name())];
                if (db[4])
                    tmp += [form.format("Leave Lock", (db[4]).lock_name())];
                if (db[8])
                    tmp += [form.format("Use Lock", (db[8]).lock_name())];
                add += [tmp];
            }
        } else {
            msg += [[(active_channels.contains(i)) ? "*" : " ", alias, "", "Channel not in database!"]];
        }
        refresh();
    }
    msg = (msg.transpose()).tabulate([["", ""], ["Alias", "-----"], ["Channel", "-------"], ["Description", "-----------"]]);
    if (d)
        msg = [msg[1], msg[2], @map i in [3 .. msg.length()] to ([msg[i]] + (add[i - 2])).sum()];
    return [@msg, "   -----"];
};

public method .channel_page_cmd() {
    arg cmd, cmstr, channel;
    var text, line;
    
    if ((.channel_alias(channel)) == "")
        return .tell(("Channel alias " + channel) + " does not exist.");
    text = .read();
    if (text == 'aborted)
        return .tell("@paste aborted.");
    else if (!text)
        return .tell("@paste nothing?");
    for line in (text)
        .broadcast(.channel_alias(channel), ":paste: " + line);
};


new object $user_info: $user_interfaces;

var $root manager = $user_info;
var $has_commands remote = #[];
var $root flags = ['variables, 'methods, 'code, 'fertile, 'core];
var $root created_on = 843753238;
var $has_commands shortcuts = #[];
var $root inited = 1;
var $has_commands local = #[];
var $user_info info = 0;
var $user_info info_defaults = #[["rl-name", 1], ["rl-email", 0], ["rl-address", 0], ["rl-affiliation", 0], ["rl-position", 0], ["rl-location", 0], ["rl-interests", 0], ["rl-plan", 0], ["rl-projects", 0], ["rl-home-page", 1]];
var $root managed = [$user_info];
var $root defined_settings = #[["rl-name", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-email", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-address", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-affiliation", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-position", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-location", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-interests", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-plan", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-projects", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-home-page", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]]];
var $root trusted_by = [$smtp];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;

public method .info_defaults() {
    arg @name;
    
    if (name)
        return (> info_defaults[name[1]] <);
    return info_defaults;
};

protected method .get_user_info() {
    arg name, @args;
    
    if ((| $user_info.info_defaults(name) |) == ~keynf)
        throw(~setting, ("Invalid user info setting '" + name) + "'");
    return (| info[name] |) || [0, ""];
};

public method .set_info_default() {
    arg name, def;
    
    def = def ? 1 : 0;
    info_defaults = dict_add(info_defaults, name, def);
};

public method .set_user_info() {
    arg name, definer, value, @args;
    var tmp, bool, public, def, valid;
    
    def = $user_info.info_defaults();
    if (!(def.contains(name)))
        throw(~setting, ("Invalid user info setting '" + name) + "'");
    value = (value.explode_quoted()).join(" ");
    if (value && ((value[1]) in ["+", "-"])) {
        bool = (value[1]) == "+";
        tmp = substr(value, 2);
        if ((tmp = match_template(tmp, "p?ublic *"))) {
            value = tmp[2];
            public = bool;
        } else {
            public = def[name];
        }
    } else {
        public = def[name];
    }
    
    // restrictions
    if ((!value) && (name == "rl-email"))
        throw(~setting, "You must specify an email address");
    if (name == "rl-email") {
        if ($sys.validate_email_addresses()) {
            .tell("Verifying Email Address..");
            tmp = (> $smtp.verify_email_address(value) <);
            .tell("SMTP Response: " + (tmp.join(" ")));
        } else {
            (> $smtp.parse_email_address(value) <);
        }
    }
    
    // set it 
    if (!info)
        info = #[];
    info = info.add(name, [public, value]);
};

public method .display_info() {
    arg @no_blanks;
    var out, i, v, sys;
    
    out = [];
    sys = .is_writable_by(sender());
    for i in (($user_info.info_defaults()).keys()) {
        v = (| info[i] |) || [0, ""];
        if ((!(v[2])) && no_blanks)
            continue;
        i = substr(i, 4);
        if ((v[1]) || sys)
            out += [(((i.capitalize()) + ":").pad(13)) + (v[2])];
        else
            out += [(((i.capitalize()) + ":").pad(13)) + "** PRIVATE **"];
    }
    return out;
};

public method .public_user_info() {
    arg name, sender, @caller;
    var i;
    
    i = (| info[name] |) || [0, ""];
    if ((!(i[1])) && (!(.is_writable_by(sender))))
        throw(~private, ("'" + name) + "' is private user information.");
};

public method .user_info() {
    arg name;
    var i;
    
    // call this method to bypass the settings system.
    i = (| info[name] |) || ((| info["rl-" + name] |) || [0, ""]);
    if ((!(i[1])) && ((!(.is_writable_by(sender()))) && ((caller() != $mail_list) && (caller() != $mail_message))))
        throw(~private, ("'" + name) + "' is private user information.");
    return i[2];
};

protected method .clear_user_info() {
    arg name;
    
    if (info.contains(name))
        info = info.del(name);
};

protected method .format_user_info() {
    arg value;
    
    return ((value[1]) ? "+public " : "") + toliteral(value[2]);
};


new object $menu: $user_interfaces;

var $root manager = $menu;
var $menu menu_choice = 0;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 866642150;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $menu menu = 0;
var $root managed = [$menu];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $command_cache modules = [];
var $command_cache commands = 0;
var $command_cache shortcuts = 0;

public method .bar() {
    arg @text;
    var l, str;
    
    if (!text) {
        return "==============================================================================";
    } else {
        str = ("=[" + (text[1])) + "]";
        for l in [1 .. 75 - ((text[1]).length())]
            str = str + "=";
        return str;
    }
};

public method .set_menu() {
    arg val;
    
    menu = val;
    
    // Set the current (sub)-menu
};

public method .menubar() {
    arg @text;
    var l, str;
    
    if (!text) {
        .tell("==============================================================================");
    } else {
        str = ("=[" + (text[1])) + "]";
        for l in [1 .. 75 - ((text[1]).length())]
            str = str + "=";
        .tell(str);
    }
};

public method .menuchoice() {
    arg choice, text;
    
    .tell(((" [" + choice) + "] ") + text);
};

public method .menutext() {
    arg text;
    
    if (!text)
        .tell("");
    else
        .tell(" " + text);
};

public method .menu_choice() {
    return menu_choice;
};

public method .do_menu() {
    arg @menu;
    var l, str, options, title, prompt, temp, instr, helptext, accept_any, accept_skip, accept_exit, accept_numeric, accept_return, myline, mylist, reloop;
    
    if ((menu.length()) < 3)
        throw(~menu, "Menu must consist of title, prompt text, and at least one option.");
    
    // Obtain the title and prompt text:
    title = menu[1];
    menu = menu.delete(1);
    prompt = menu[1];
    menu = menu.delete(1);
    options = [];
    .tell("");
    pause();
    .menubar(title);
    for l in [1 .. menu.length()] {
        switch (type((menu[l]) || 'blank)) {
            case 'symbol:
                switch ((menu[l]) || 'blank) {
                    case 'accept_any:
                        // Accept any input
                        accept_any = 1;
                    case 'accept_numeric:
                        // Accept numeric input
                        accept_numeric = 1;
                    case 'back:
                        // .tell(" [-] Back Up");
                        options = [@options, "-"];
                    case 'blank:
                        // Probably not needed.
                        .tell("");
                    case 'exit:
                        // .tell(" [X] Exit");
                        options = [@options, "X"];
                        accept_exit = 1;
                    case 'help:
                        // .tell(" [?] Help");
                        options = [@options, "?"];
                    case 'nothing:
                        // Nothing; not even a blank line.
                    case 'return:
                        accept_return = 1;
                    case 'skip:
                        // .tell(" [+] Skip Set");
                        options = [@options, "+"];
                        accept_skip = 1;
                }
            case 'list:
                // One of the elements is a list. Split this
                // up as we do with normal strings, columnize
                // it, store the options, then columnize it.
                mylist = [];
                for myline in (menu[l]) {
                    myline.replace("=> ", "=>");
                    temp = myline.explode("=>");
                    if ((temp.length()) == 1) {
                        // It's just a string. Print it.
                        // .tell(" "+temp[1]);
                        mylist = mylist.add((temp[1]) + " ");
                    } else {
                        // It's a menu choice and txt.
                        mylist = mylist.add(((("[" + ((temp[1]).uppercase())) + "] ") + (temp[2])) + " ");
    
                        // .tell(" ["+temp[1].uppercase()+"] "+temp[2]);
                        options = [@options, ((temp[1])[1]).uppercase()];
                    }
                }
                mylist = mylist.lcolumnize();
                for myline in (mylist)
                    .tell(" " + myline);
            case 'string:
                // Break things up into choice, text:
                (menu[l]).replace("=> ", "=>");
                temp = (menu[l]).explode("=>");
                if ((temp.length()) == 1) {
                    // It's just a string. Print it.
                    .tell(" " + (temp[1]));
                } else {
                    // It's a menu choice and txt.
                    switch (temp[1]) {
                        case "?":
                            // .tell(" ["+temp[1].uppercase()+"] Help");
                            // helptext=temp[2];
                            // options=[@options,temp[1][1].uppercase()];
                        default:
                            // Print the choice and text:
                            .tell(((" [" + ((temp[1]).uppercase())) + "] ") + (temp[2]));
                            options = [@options, ((temp[1])[1]).uppercase()];
                    }
                }
        }
    }
    .menubar();
    pause();
    reloop = 1;
    while (reloop == 1) {
        reloop = 0;
        .tell("");
        .non_terminated_tell(prompt);
        instr = tostr((> .prompt(" ") <));
        if (((instr.length()) > 1) && ((instr[1]) == "~")) {
            .tell("");
            .menuline("Command Line: " + ((instr.subrange(2)).chop(40)));
            reloop = 1;
            ((.connections())[1]).parse_line(instr.subrange(2));
            .tell("");
            .menuline();
        }
        if (instr == "abort") {
            .tell("Aborted! Exiting menu.");
            throw(~abort, "Aborted! Exiting menu.", 'notraceback);
        }
    }
    if (helptext && (instr == "?")) {
        .atell("[help!]");
        .atell(helptext);
        (> .prompt("Press Return> ") <);
    }
    
    // Yell at the user if a valid option is not selected:
    if ((!(accept_return && (instr == ""))) && ((!(accept_numeric && (instr.is_numeric()))) && ((!accept_any) && ((instr in options) == 0)))) {
        .tell("");
        .tell(("Valid options are " + ([@options, "Abort"].to_english())) + ".");
        menu_choice = 'invalid;
    }
    
    // 'skip, 'exit and such can be specified in the menu call. If these
    // are included, accept_skip, accept_exit, etc. will be set to 1. If
    // the user then selects the approprate character, 'skip, 'exit, etc.
    // will be returned instead of the character. Why? I don't know.
    if (accept_skip && (instr == "+"))
        instr = 'skip;
    if (accept_exit && (instr == "X"))
        instr = 'exit;
    if (accept_return && (instr == ""))
        instr = 'return;
    menu_choice = instr;
    return instr;
};

public method .menu() {
    return menu;
    
    // Returns the current (sub)-menu.
};

public method .menuline() {
    arg @text;
    var l, str;
    
    if (!text) {
        .tell("------------------------------------------------------------------------------");
    } else {
        str = ("=[`[34m" + (text[1])) + "`[37m]";
        for l in [1 .. 75 - ((text[1]).length())]
            str = str + "-";
        .tell(str);
    }
};

public method .do_menu_split() {
    arg @args;
    var x, choicelist, numgroups, pergroup, extra, title, prompt, len, arglen, menu, groups, choice;
    
    choicelist = "abcdefghijklmnopqrstuvwyz0123456789";
    title = args[1];
    prompt = args[2];
    menu = [];
    groups = [];
    args = args.subrange(3);
    len = choicelist.length();
    arglen = args.length();
    numgroups = arglen / len;
    if ((arglen % len) != 0)
        numgroups++;
    pergroup = arglen / numgroups;
    extra = arglen % numgroups;
    for x in [1 .. numgroups] {
        menu = menu + [((tostr(x) + "=>") + (x.n_to_nth())) + " list of choices"];
        if (extra) {
            groups = groups + [args.subrange(1, pergroup + 1)];
            args = args.subrange(pergroup + 2);
            extra--;
        } else {
            groups = groups + [args.subrange(1, pergroup)];
            args = args.subrange(pergroup + 1);
        }
    }
    while (choice != 'exit) {
        choice = .do_menu(title, prompt, @menu, 'exit);
        if (choice != 'exit)
            .do_menu_nice(title, prompt, @groups[toint(choice)]);
    }
};

public method .do_menu_nice() {
    arg @args;
    var choicelist, menu, selections, title, prompt, x, choice, obj, meth, arguments, unassigned, letter;
    
    // Generate a nice menu from a list of choices; run the menu
    //  and call all appropriate methods
    // Initialize lots of things
    choicelist = "abcdefghijklmnopqrstuvwyz0123456789";
    menu = [];
    selections = #[];
    unassigned = [];
    if ((filter x in (args) where (type(x) == 'list).length()) > (choicelist.length()))
        return .do_menu_split(@args);
    
    // Get the menu's title and prompt
    title = args[1];
    prompt = args[2];
    args = args.subrange(3);
    
    // Now parse the menu choices
    for x in (args) {
        switch (type(x)) {
            case 'string:
                // If it's a string, just copy it to the menu
                menu = menu + [x];
            case 'list:
                // If it's not a string, we need to parse it
                // First, we get the choice
                choice = x[1];
    
                // Now we get the method to be called if this
                //  option is selected
                if (type(x[2]) == 'objnum) {
                    obj = x[2];
                    x = x.subrange(3);
                } else {
                    obj = sender();
                    x = x.subrange(2);
                }
                meth = x[1];
                arguments = x.subrange(2);
                choice = ((choice.replace("$", "")).replace("'", "")).replace("_", " ");
                letter = (choice.replace(" ", ""))[1];
    
                // Find the first letter of the choice. If it's already
                //  in use, add this choice to an 'unassigned' list.
                //  Otherwise, use that letter for this choice
                if (letter in choicelist) {
                    choice = (letter + "=>") + choice;
                    menu = menu + [choice];
                    choicelist = choicelist.replace(letter, "");
                    selections = selections.add(letter, [obj, meth, arguments]);
                } else {
                    unassigned = unassigned + [[choice, obj, meth, arguments]];
                }
            default:
                throw(~menu, "Bad menu parameter.");
        }
    }
    
    // Now go through the unassigned list and assign letters to all
    //  remaining choices if possible
    for choice in (unassigned) {
        letter = choicelist[1];
        menu = menu + [(letter + "=>") + (choice[1])];
        selections = selections.add(letter, [choice[2], choice[3], choice[4]]);
        choicelist = choicelist.subrange(2);
    }
    
    // Ok, do the menu
    while (choice != 'exit) {
        choice = .do_menu(title, prompt, @menu, 'exit);
        if (choice && (choice != 'exit)) {
            meth = selections[choice];
            (meth[1]).(meth[2])(@meth[3]);
        }
    }
};


new object $www_preferences: $user_interfaces;

var $root manager = $www_preferences;
var $root defined_settings = #[["www-show-line-num", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["www-show-descriptions", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["www-show-methods", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["www-show-variables", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $root flags = ['variables, 'methods, 'code, 'fertile, 'core];
var $root created_on = 867669920;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $root inited = 1;
var $root settings = #[["www-show-line-num", 0], ["www-show-descriptions", 0], ["www-show-methods", 0], ["www-show-variables", 0]];
var $root managed = [$www_preferences];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;

public method .set_www_preferences() {
    arg name, value;
    
    (> .perms(caller(), this()) <);
    .set_setting(name, $www_preferences, value);
};


new object $user: $body, $mail_ui, $command_aliases, $bad_commands, $help_ui, $editor_reference, $channel_ui, $user_info, $menu, $www_preferences;

var $root inited = 1;
var $root created_on = 796268969;
var $root manager = $user;
var $root flags = ['methods, 'core, 'code, 'variables, 'general_cache];
var $root managed = [$user];
var $location contents = [];
var $located location = $body_cave;
var $located obvious = 1;
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user ext_parsers = 0;
var $user title = 0;
var $user action = "";
var $user activity = 0;
var $user parsers = [$command_parser, $channel_parser];
var $user context = 0;
var $user remembered = 0;
var $user evaluator = 0;
var $user connected_seconds = 0;
var $user task_connections = #[];
var $user global_tell = 0;
var $user formatter = $plain_format;
var $user content_type = 'plain;
var $command_aliases command_aliases = [];
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list senders = 1;
var $mail_list readers = [];
var $mail_list notify = [$user];
var $mail_list last_letter = 0;
var $mail_list mail = [];
var $mail_ui subscribed = #[[$user, [791485891, 0]]];
var $mail_ui current = #[['location, 0], ['list, $user]];
var $described prose = [];
var $has_name name = ['prop, "Generic User Object", "Generic User Object"];
var $user registered = 0;
var $has_commands local = #[["@quit", [["@quit", "", "@quit", 'quit_cmd, #[]]]], ["i?nventory", [["i?nventory", "", "i?nventory", 'inventory_cmd, #[]]]], ["@audit", [["@audit", "*", "@audit <any>", 'audit_cmd, #[[1, ['any, []]]]]]], ["@who", [["@who", "*", "@who <any>", 'who_cmd, #[[1, ['any, []]]]]]], ["@del-command-a?lias|@dca?lias", [["@del-command-a?lias|@dca?lias", "*", "@del-command-a?lias|@dca?lias <any>", 'del_command_alias_cmd, #[[1, ['any, []]]]]]], ["@command-a?liases|@ca?liases", [["@command-a?liases|@ca?liases", "*", "@command-a?liases|@ca?liases <any>", 'command_aliases_cmd, #[[1, ['any, []]]]]]], ["@add-command-a?lias|@aca?lias", [["@add-command-a?lias|@aca?lias", "*", "@add-command-a?lias|@aca?lias <any>", 'add_command_alias_cmd, #[[1, ['any, []]]]]]], ["@com?mands", [["@com?mands", "*", "@com?mands <any>", 'commands_cmd, #[[1, ['any, []]]]]]], ["@news", [["@news", "", "@news", 'news_cmd, #[]]]], ["@forget", [["@forget", "*", "@forget <any>", 'forget_cmd, #[[1, ['any, []]]]]]], ["@whereis|@where-is", [["@whereis|@where-is", "*", "@whereis|@where-is <any>", 'whereis_cmd, #[[1, ['any, []]]]]]], ["@password|@passwd", [["@password|@passwd", "*", "@password|@passwd <any>", 'password_cmd, #[[1, ['any, []]]]]]], ["@age", [["@age", "*", "@age <object>", 'age_cmd, #[[1, ['object, []]]]]]], ["@context", [["@context", "", "@context", 'context_cmd, #[]]]], ["@rename", [["@rename", "*", "@rename <any>", 'rename_cmd, #[[1, ['any, []]]]]]], ["@remember", [["@remember", "* as *", "@remember <object> as <any>", 'remember_cmd, #[[1, ['object, []]], [3, ['any, []]]]]]], ["@remembered", [["@remembered", "*", "@remembered <any>", 'remembered_cmd, #[[1, ['any, []]]]]]], ["discard", [["discard", "*", "discard <object>", 'discard_cmd, #[[1, ['object, []]]]]]], ["@monitor", [["@monitor", "*", "@monitor <any>", 'monitor_cmd, #[[1, ['any, []]]]]]], ["@ex?amine", [["@ex?amine", "*", "@ex?amine <object:+c?hop>", 'examine_cmd, #[[1, ['object_opt, ["c?hop"]]]]]]], ["@map", [["@map", "", "@map", 'map_cmd, #[]]]], ["@desc?ribe|@prose", [["@desc?ribe|@prose", "*", "@desc?ribe|@prose <any>", 'description_cmd, #[[1, ['any, []]]]]]], ["l?ook|exam?ine", [["l?ook|exam?ine", "*", "l?ook|exam?ine <any>", 'look_cmd, #[[1, ['any, []]]]]]], ["walk|go", [["walk|go", "*", "walk|go <any>", 'go_cmd, #[[1, ['any, []]]]]]], ["@ant|@add-name-template", [["@ant|@add-name-template", "*", "@ant|@add-name-template <any>", 'add_name_template_cmd, #[[1, ['any, []]]]]]], ["@dnt|@del-name-template", [["@dnt|@del-name-template", "*", "@dnt|@del-name-template <any>", 'del_name_template_cmd, #[[1, ['any, []]]]]]], ["@name-template?s|@template?s", [["@name-template?s|@template?s", "*", "@name-template?s|@template?s <object>", 'name_templates_cmd, #[[1, ['object, []]]]]]], ["@register|@register-name", [["@register|@register-name", "*", "@register|@register-name <any>", 'register_name_cmd, #[[1, ['any, []]]]]]], ["@unregister|@unregister-name", [["@unregister|@unregister-name", "*", "@unregister|@unregister-name <any>", 'unregister_name_cmd, #[[1, ['any, []]]]]]], ["@registered", [["@registered", "", "@registered", 'registered_cmd, #[]]]], ["@page", [["@page", "* with *", "@page <any> with <any>", 'remote_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["@paste?-to", [["@paste?-to", "*", "@paste?-to <any>", 'paste_cmd, #[[1, ['any, []]]]]]], ["@new", [["@new", "*", "@new <any>", 'new_cmd, #[[1, ['any, []]]]]]], ["@status|@uptime", [["@status|@uptime", "*", "@status|@uptime <any>", 'status_cmd, #[[1, ['any, []]]]]]], ["@msg?s|@message?s", [["@msg?s|@message?s", "*", "@msg?s|@message?s <any>", 'msg_cmd, #[[1, ['any, []]]]]]], ["@date|@time", [["@date|@time", "*", "@date|@time <any>", 'date_cmd, #[[1, ['any, []]]]]]], ["@set", [["@set", "*", "@set <any>", 'set_cmd, #[[1, ['any, []]]]]]], ["PUEBLOCLIENT", [["PUEBLOCLIENT", "*", "PUEBLOCLIENT <any>", 'pueblo_cmd, #[[1, ['any, []]]]]]], ["@ways|@exits", [["@ways|@exits", "*", "@ways|@exits <any>", 'ways_cmd, #[[1, ['any, []]]]]]], ["@tut?orial", [["@tut?orial", "*", "@tut?orial <any>", 'tutorial_cmd, #[[1, ['any, []]]]]]], ["null", [["null", "*", "null <any>", 'null_cmd, #[[1, ['any, []]]]]]], ["@away", [["@away", "*", "@away <any>", 'away_cmd, #[[1, ['any, []]]]]]], ["@back", [["@back", "", "@back", 'back_cmd, #[]]]], ["@finger", [["@finger", "*", "@finger <user>", 'finger_cmd, #[[1, ['user, []]]]]]], ["@rep?ort|@bug", [["@rep?ort|@bug", "", "@rep?ort|@bug", 'report_cmd, #[]]]], ["@traceback|@tb", [["@traceback|@tb", "*", "@traceback|@tb <any>", 'traceback_cmd, #[[1, ['any, []]]]]]]];
var $has_commands shortcuts = #[["--*", ['remote_cmd, ["@page ", "", " with ", 1]]], ["-* *", ['remote_cmd, ["@page ", 1, " with ", 2]]], ["/*", ['null_cmd, ["null ", 1]]]];
var $user monitor = 0;
var $root trusted_by = [$user_db];
var $user failed = 0;
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $user rows = 0;
var $user cols = 0;
var $command_cache modules = [];
var $user auto_look = 0;
var $root defined_settings = #[["experienced", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["global-tell", #[['get, ['get_global_tell]], ['set, ['set_global_tell]], ['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["cols", #[['get, ['get_cols]], ['set, ['set_cols]], ['parse, ['is_type, 'integer]]]], ["rows", #[['get, ['get_rows]], ['set, ['set_rows]], ['parse, ['is_type, 'integer]]]], ["prompt", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["auto-look", #[['get, ['get_auto_look]], ['set, ['set_auto_look]], ['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["content-type", #[['set, ['set_content_type]], ['parse, ['parse_content_type]], ['format, ['format_content_type]], ['clear, ['clear_content_type]], ['get, ['get_content_type]]]], ["extended-parsers", #[['parse, ['parse_ext_parsers]], ['format, ['format_ext_parsers]]]], ["exit-style", #[['parse, ['parse_exit_style]]]], ["title", #[['get, ['title]], ['set, ['set_title]]]], ["@who-options", #[]], ["away", #[['get, ['get_away]], ['set, ['set_away]], ['clear, ['clear_away]]]]];
var $root settings = #[["experienced", 0], ["exit-style", 'brief], ["home", $body_cave], ["prompt", 0], ["extended-parsers", []], ["@who-options", ""]];
var $thing gender = $gender_neuter;
var $user reap_notified = 0;
var $root quota = 76800;
var $user away = 0;
var $user away_time = 0;
var $user connection_options = 0;
var $command_cache shortcuts = 0;
var $command_cache commands = 0;

root method .init_user() {
    var n;
    
    password = "*";
    connected_at = 0;
    last_command_at = 0;
    connections = [];
    parsers = [$command_parser, $channel_parser];
    action = "";
    context = #[];
    .set_quota($sys.get_starting('quota));
    $user_db.insert(.name(), this());
    .set_flags([]);
    .move_to($body_cave);
    task_connections = #[];
    formatter = $plain_format;
};

root method .uninit_user() {
    var conn, name;
    
    if (.connected())
        (| (.location()).did_disconnect() |);
    
    // and incase any are lying about
    for conn in (connections)
        (| conn.interface_going_away() |);
    password = 0;
    connections = 0;
    (| $user_db.remove(.name()) |);
    for name in (registered || [])
        (| $user_db.remove(name) |);
};

public method .will_move() {
    arg mover, place;
    
    (> pass(mover, place) <);
    if (place.is($user))
        throw(~user, "Users cannot move into other users!");
    if ((mover.is($user)) && ((mover != this()) && (!($sys.is_system(mover)))))
        throw(~user, "Only system priviledged objects can freely move users around.");
};

public method .connected_at() {
    return connected_at;
};

public method .last_command_at() {
    return last_command_at;
};

public method .tell() {
    arg what, @who;
    
    if (!(.connected()))
        return;
    if (monitor != 0) {
        if (listlen(monitor) > 19)
            monitor = [[user(), @stack()[2], what], @delete(monitor, 10)];
        else
            monitor = [[user(), @stack()[2], what], @monitor];
    }
    ._tell(what);
};

public method .set_password() {
    arg str;
    
    (> .perms(sender(), 'manager) <);
    if ((str.length()) < 5)
        throw(~badpasswd, "Passwords must be at least 5 characters long.");
    password = crypt(str);
};

public method .check_password() {
    arg str, @cinfo;
    var match, warn, ts1, ts2;
    
    (> .perms(caller(), definer(), $security_lib) <);
    
    // no password means always match
    if (!password)
        return 1;
    
    // "*" means never match
    if (password == "*")
        return 0;
    match = match_crypted(password, str);
    
    // keep track of failed attempts, if its from a connection
    if ((!match) && cinfo) {
        if (.connected())
            .tell("<Login> Failed Login Attempt from " + (cinfo[1]));
        else
            failed++;
    }
    
    // done
    return match;
};

public method .did_move() {
    arg @args;
    
    (> pass(@args) <);
    if (auto_look != 'no)
        .tell((.location()).get_description(#[['actor, this()], ['exclude, [this()]]]));
};

public method .parsers() {
    .perms(sender(), 'trusts);
    return parsers;
};

protected method .add_parser() {
    arg parser, @over_pr;
    var x, pr;
    
    [(pr ?= parser.priority())] = over_pr;
    
    // does it exist?  If so remove it.
    while (parser in parsers)
        parsers = setremove(parsers, parser);
    for x in [1 .. listlen(parsers)] {
        if (((parsers[x]).priority()) > pr) {
            parsers = insert(parsers, x, parser);
            return;
        }
    }
    parsers += [parser];
};

public method .del_parser() {
    arg parser;
    var keepers;
    
    // removes a parser.  Cannot remove $command_parser (put things in
    // front of it instead).
    if (parser == $command_parser)
        throw(~no, "You must always have the $command_parser.");
    parsers = parsers.setremove(parser);
};

public method .parse_line() {
    arg line;
    var parse, c, r, rval;
    
    (> .perms(caller(), $connection) <);
    set_user();
    if (away)
        .tell("You are still marked as being away.");
    
    // if we dont set it, it'll act like normal
    rval = this();
    last_command_at = time();
    .set_last_command(line.trim());
    catch any {
        task_connections = task_connections.add(task_id(), sender());
        parse = parsers ? ((parsers[1]).parse(this(), line, @parsers.subrange(2), $null_parser)) : ['failed];
        switch (parse[1]) {
            case 'action:
                r = (| (parse[2]).action(@parse[3]) |);
                if (type(r) in ['list, 'frob, 'string])
                    .ptell(r, #[['type, 'parser], ['action, parse[3]]]);
                else
                    .tell(("Invalid registered action '" + (parse[3])) + "'");
            case 'error:
                .tell(parse[2]);
            case 'match, 'command:
                r = (> (parse[2]).(parse[3])(@parse.subrange(4)) <);
                if (type(r) in ['list, 'frob, 'string])
                    .ptell(r, #[['type, 'parser], ['command, parse[3]]]);
                else
                    rval = r;
            case 'failed:
                for c in (($place_lib.coordinate_shortcuts()).keys()) {
                    if (line.match_template(c)) {
                        .tell(("There is no exit " + line) + " here.");
                        r = 1;
                    }
                }
                if (!r)
                    .tell(("I don't understand " + (line.chop((.linelen()) - 22))) + ".");
            case 'ok:
                // do nothing, probably a null command
            default:
                .tell("Unusual response from the parser: " + toliteral(parse));
        }
    } with {
        if (error() == ~stop) {
            if ((traceback()[1])[2])
                .tell((traceback()[1])[2]);
        } else {
            .tell_traceback(traceback(), @parse);
        }
    }
    catch any
        task_connections = task_connections.del(task_id());
    return rval;
};

public method .login() {
    arg connection;
    var loc, cmd, p, c, last, tmp;
    
    set_user();
    .poll_semaphore('cleanup);
    if ((sender() != this()) || (definer() != caller()))
        throw(~perm, "Invalid access to private method.");
    task_connections = #[];
    (| .reset_parsers() |);
    .cache_client_init();
    (| .reset_help_history() |);
    $user_db.did_connect();
    if (reap_notified)
        clear_var('reap_notified);
    last = connected_at;
    connected_at = time();
    last_command_at = time();
    loc = .location();
    if (loc == $body_cave) {
        if ((.home()) != $body_cave)
            (| .move_to(.home()) |);
        else
            (| .move_to($world.starting_place()) |);
    } else {
        .tell(.look_cmd("", "", ""));
    }
    $channel_ui._broadcast('Login, (((.namef('titled)) + " has connected (total: ") + ($user_db.total_connected())) + ")");
    (| (.location()).did_connect() |);
    (| .login_notify(connection, last) |);
    (| .edit_sessions_notify() |);
    .hook_events('startup);
    $world.hook_into_event('realm_announce);
    context = #[];
    if (formatter == $pueblo_format)
        .set_content_type_pueblo();
    .release_semaphore('cleanup);
};

public method .login_again() {
    arg connection;
    
    if ((sender() != this()) || (definer() != caller()))
        throw(~perm, "Invalid access to private method.");
    last_command_at = time();
    (| .tell(("<Login> " + (((.connections()).length()).n_to_nth())) + " login.") |);
    if (failed) {
        (> .tell(("<Login> ** " + failed) + " failed login attempts **") <);
        (| clear_var('failed) |);
    }
};

public method .logout() {
    arg connection;
    var p;
    
    (| (.location()).did_disconnect() |);
    (| .reset_parsers() |);
    (| .clear_help_history() |);
    (| $user_db.did_disconnect() |);
    
    // Track how long they are online (random info) -Lynx
    connected_seconds += time() - connected_at;
    
    // set this to -last_command so we know they aren't connected
    // (and using last command will be last_login)
    connected_at = -last_command_at;
    
    // user specific things
    if (!($guest in (.parents()))) {
        (| $housekeeper.did_disconnect() |);
        (| $user_db.last_log_disconnect(this()) |);
    } else {
        (| $user_db.last_log_disconnect($guest) |);
    }
    .cache_client_uninit();
    $channel_ui._broadcast('Login, (((.namef('titled)) + " has disconnected (total: ") + ($user_db.total_connected())) + ")");
    task_connections = #[];
    .set_activity("");
    (| clear_var('monitor) |);
    (| .new_list(this()) |);
    .unhook_events('startup);
    $world.unhook_from_event('realm_announce);
    (| clear_var('context) |);
};

public method .connections() {
    return connections;
};

public method .connected() {
    return connections ? 1 : 0;
};

public method .who_cmd() {
    arg cmdstr, com, args;
    var who, title, rest, opts, opt, a, all, prog, admin, short, sort, sortorder, s, x, place, results, sortopts, sortmeths;
    
    (> .perms(caller(), 'command) <);
    
    // just the basic who listing
    args = ((.get_setting("@who-options", $user)) + " ") + args;
    [args, opts] = (> $parse_lib.opt(args, "a?ll", "p?rogrammers", "a?dmins", "s?hort", "so?rt") <);
    for opt in (opts) {
        switch (opt[1]) {
            case "a?ll":
                all = opt[3];
            case "p?rogrammers":
                prog = opt[3];
            case "a?dmins":
                admin = opt[3];
            case "s?hort":
                short = opt[3];
            case "so?rt":
                sort = opt[4];
                sortorder = opt[3];
        }
    }
    args = (args.join()).explode_english_list();
    results = [];
    if (admin && (admin = ._who__admins([], all)))
        results += [admin];
    if (prog && (prog = ._who__programmers([], all)))
        results += [prog];
    if ((!prog) && ((!admin) && (!args))) {
        results += [[$user_db.connected(), "Connected Users"]];
    } else {
        for a in (args) {
            if ((a[1]) == "@") {
                if ((place = ._who__at_place(a.subrange(2))))
                    results += [place];
                args = args.setremove(a);
            }
        }
        if (args && (args = ._who__is(args)))
            results += [args];
    }
    who = [];
    for x in (results)
        who = union(who, x[1]);
    title = (results.slice(2)).to_english();
    rest = ((results.length()) == 1) ? ((results[1]).subrange(3)) : [];
    if (!who)
        return "Ack, nobody to list?";
    if (sort) {
        sortopts = ["idle", "connected", "name", "location", "place"];
        sortmeths = ['idle_seconds, 'connected_at, 'name, 'location, 'location];
        s = filter x in (sortopts) where (match_begin(x, sort));
        if ((s.length()) != 1) {
            .ptell("Unrecognized sort option: " + sort, #[['type, 'command]]);
            sort = 0;
        } else {
            sort = sortmeths[(s[1]) in sortopts];
        }
    }
    if (sort) {
        sort = who.mmap(sort);
        if (type(sort[1]) == 'objnum)
            sort = sort.mmap('name);
        who = who.sort(sort);
        if (!sortorder)
            who = who.reverse();
    }
    if (short)
        return ._who__short(who, title, @rest);
    else
        .ptell($code_lib.generate_listing(who, title, @rest), #[['type, 'command]]);
};

protected method .quit_cmd() {
    arg @args;
    
    (> .perms(caller(), 'command) <);
    return 'disconnect;
};

protected method .inventory_cmd() {
    arg @args;
    var i;
    
    (> .perms(caller(), 'command) <);
    if (.contents()) {
        .tell("Carrying:");
        for i in (.contents())
            .tell(" " + (i.name()));
    } else {
        .tell("You are empty-handed.");
    }
};

public method .linelen() {
    if (cols)
        return cols - 1;
    return 79;
    
    // backwards compatability, older tiny style systems
    // want linelen to actually be cols - 1
};

public method .idle_seconds() {
    return time() - last_command_at;
};

public method .title() {
    arg @args;
    
    return title || "";
};

public method .action() {
    // different from activity, returns a more accurate second to second action
    if (.connected())
        return action || "";
    else
        return "(asleep)";
};

protected method .commands_cmd() {
    arg cmdstr, cmd, args;
    var s, full, o, opt, lcmds, rcmds, len, obj, shorts, m, c, local, remote, short, all;
    
    (> .perms(caller(), 'command) <);
    s = cmd + " [options] <object>";
    args = (> $parse_lib.opt(args, "f?ull", "a?ll", "l?ocal", "r?emote", "s?hortcuts") <);
    o = args[2];
    local = (remote = (short = 1));
    if ((opt = "f?ull" in (o.slice(1))))
        full = (o[opt])[3];
    if ((opt = "a?ll" in (o.slice(1))))
        all = (o[opt])[3];
    if ((opt = "r?emote" in (o.slice(1))))
        remote = (o[opt])[3];
    if ((opt = "s?hortcuts" in (o.slice(1))))
        short = (o[opt])[3];
    if ((opt = "l?ocal" in (o.slice(1))))
        local = (o[opt])[3];
    args = (args[1]).join();
    if ((!args) && (!all)) {
        (| .tell_error(cmd + " <object> [options]") |);
        return "!  Defaults: -f?ull -a?ll +l?ocal +r?emote +s?hortcuts";
    } else {
        args = args || "me";
        obj = (> .match_env_nice(args) <);
    }
    if (!(obj.has_ancestor($has_commands)))
        return "Sorry, that object has no commands.";
    lcmds = (rcmds = #[]);
    shorts = [];
    if (all) {
        if (local)
            lcmds = obj.all_local_commands();
        if (remote)
            rcmds = obj.all_remote_commands();
        if (short)
            shorts = obj.all_shortcuts();
    } else {
        if (local) {
            c = obj.local_commands();
            if (c)
                lcmds = #[[obj, c]];
        }
        if (remote) {
            c = obj.remote_commands();
            if (c)
                rcmds = #[[obj, c]];
        }
        if (short)
            shorts = (obj.shortcuts()).to_list();
    }
    if (full) {
        m = 'format_commands_long;
        len = ((.linelen()) / 3) * 2;
    } else {
        m = 'format_commands_short;
        len = .linelen();
    }
    o = [];
    if (lcmds)
        o += $command_lib.(m)(lcmds, "Local", len);
    if (rcmds)
        o += $command_lib.(m)(rcmds, "Remote", len);
    if (shorts) {
        o += ["Shortcuts:"];
        if (full)
            m = 'unparse_shortcut_full;
        else
            m = 'unparse_shortcut;
        for c in (shorts)
            o += ["  " + $command_lib.(m)(c)];
    }
    return o || ("No commands defined on " + (obj.namef('ref)));
};

public method .activity() {
    arg @noidle;
    var idle, r;
    
    // different from action, returns a broader version of your doings
    if (!(.connected()))
        return "asleep";
    if (activity)
        return activity;
    if (!noidle) {
        idle = .idle_seconds();
        if (idle >= 180) {
            if (idle < 300)
                r = "daydreaming";
            if (idle < 900)
                r = "zoned";
            else
                r = "long gone";
        }
        if (away)
            return ((((r ? (r + ", ") : "") + "away for ") + ($time.dhms(time() - away_time, 1))) + ": ") + away;
    }
    return r;
};

public method .home() {
    arg @args;
    var home;
    
    if ((home = pass(@args)) == $lost_and_found)
        return $body_cave;
    return home;
};

protected method .rename_cmd() {
    arg cmdstr, cmd, args;
    var obj, name, templates, article, old, oldart, oldts, new, t;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    if ((listlen(args) > 2) && ((args[2]) == "to"))
        args = delete(args, 2);
    if (listlen(args) > 2)
        args = [args[1], sublist(args, 2).join()];
    if ((!args) || (listlen(args) != 2))
        return ("Syntax: `" + cmd) + " \"<object>\" [to] \"<newname>\" [+(proper|unique|normal)]`";
    obj = (> .match_env_nice(args[1]) <);
    catch any {
        name = (> $code_lib.parse_name(sublist(args, 2).join()) <);
        templates = name[2];
        article = (name[1])[2];
        name = (name[1])[1];
        if ((name[1]) == "$") {
            if ((obj.is($user)) || (obj.is($place))) {
                if (!(.is($admin)))
                    return "User and Place objnames can only be changed by administrators.";
                else
                    (> .check_mojo() <);
            }
            name = substr(name, 2);
            if (!(name.valid_ident()))
                return "Object names can only contain a-z, 0-9 and the underscore.";
            name = tosym(name);
            old = obj.namef('xref);
            (> obj.set_objname(name) <);
            return ((("Renamed " + old) + " to ") + obj) + ".";
        } else {
            if (!(obj.has_ancestor($has_name)))
                return ("Object \"" + obj) + "\" cannot have a regular name.";
            oldart = (obj.name('literal))[1];
            oldts = obj.name_templates();
            old = ((((" [" + article) + "] \"") + (obj.name())) + "\"") + (templates ? ((" (" + (oldts.to_english())) + ")") : "");
            old = ("\"" + (obj.name())) + "\"";
            obj = (> obj.set_name(name, article) <);
            new = ("\"" + (obj.name())) + "\"";
            if (templates) {
                for t in (templates)
                    obj = (> obj.add_name_template(t) <);
                new += (" (" + ((obj.name_templates()).to_english())) + ")";
                old += (" (" + (oldts.to_english())) + ")";
            }
            if (oldart != ((obj.name('literal))[1])) {
                old = (("[" + oldart) + "] ") + old;
                new = (("[" + ((obj.name('literal))[1])) + "] ") + new;
            }
            return ((("Renamed " + old) + " to ") + new) + ".";
        }
    } with {
        return (traceback()[1])[2];
    }
};

protected method .audit_cmd() {
    arg cmdstr, cmd, args;
    var opts, o, summary, obj, syntax, t;
    
    (> .perms(caller(), 'command) <);
    [args, opts] = (> $parse_lib.opt(args, "q?uota", "m?anages", "w?rites", "t?rusted-by", "s?ummary") <);
    if ((o = "s?ummary" in (opts.slice(1))))
        summary = (opts[o])[2];
    syntax = cmd + " <object> +m?anages|+w?rites|+t?rusted|+q?uota";
    if (!args) {
        obj = this();
    } else {
        args = args.join();
        obj = (| .match_environment(args) |);
        if (!obj) {
            obj = (| $user_db.search(args) |);
            if (!obj)
                return ("Unable to find \"" + args) + "\".";
        }
    }
    if (!opts)
        opts = [["noopt", "", 1, ""]];
    
    // not pretty, but why not loop it
    for o in (opts) {
        if ((o[1]) == "s?ummary")
            continue;
        switch (o[1]) {
            case "s?ummary":
            case "q?uota":
                .tell(.audit_cmd__quota(obj, summary));
            case "m?anages":
                t = .audit_cmd__manages(obj);
                t = $ctext_frob.new_with([$cml_lib.fmt_table("60%,13%,27%", t)]);
                .tell(t);
            case "w?rites":
                t = .audit_cmd__writes(obj);
                t = $ctext_frob.new_with([$cml_lib.fmt_table("60%,13%,27%", t)]);
                .tell(t);
            case "t?rusted-by":
                t = .audit_cmd__trusted(obj);
                t = $ctext_frob.new_with([$cml_lib.fmt_table("60%,13%,27%", t)]);
                .tell(t);
            case "noopt":
                .tell($object_lib.format_object(obj, 0));
            default:
                (> .tell_error(syntax, "Invalid Argument " + ((o[1]) || (((o[3]) ? "+" : "-") + (o[2])))) <);
        }
    }
};

protected method .login_notify(): forked {
    arg connection, last;
    var l, sub, out, ans, rtime;
    
    sub = .subscribed();
    out = [];
    for l in ((sub.keys()).setremove(this())) {
        if (valid(l) && ((l.last_received_on()) > ((sub[l])[1])))
            out += [l.mail_name()];
    }
    if (out)
        .tell("<Mail> New mail on lists: " + (out.to_english()));
    if ((| (.last_received_on()) > (((.subscribed())[this()])[1]) |))
        .tell("<Mail> You have new mail (use `@help mail` to learn about mail)");
    if (last)
        .tell("<Login> Last connected at " + ($time.format("%A %B %d %I:%M %p %Y", abs(last))));
    rtime = $time.realm_time((.location()).realm(), 'with_season);
    .tell((("<Login> It is currently " + (rtime[1])) + " in ") + ((rtime[2]).name()));
    if (failed) {
        (| .tell(("<Login> ** " + failed) + " failed login attempts **") |);
        (| clear_var('failed) |);
    }
    if (!(.prose('literal)))
        .tell(["You have not yet set a description for yourself.", "Perhaps you'd like to take a look at the tutorial.", "Type @tutorial to read about how to set a description and more."]);
};

protected method .news_cmd() {
    arg @args;
    var line, x, mail, m, base, length, out;
    
    (> .perms(caller(), 'command) <);
    mail = $mail_list_news.recent_mail();
    base = mail[1];
    mail = mail[2];
    length = mail.length();
    .new_list($mail_list_news);
    out = [($motd.server_name()) + " news:", ""];
    for x in [1 .. length] {
        m = mail[x];
        out += [((((m.has_read(this())) ? "       " : "NEW => ") + (tostr(x + base).pad(-3))) + ") ") + (m.subject())];
    }
    return out + ["", "Use \"@read #\", where # is the news item number, such as \"@read 1\".  All news items can be found on mail list *news.", "---"];
};

protected method .add_command_alias_cmd() {
    arg cmdstr, cmd, input;
    
    (> .perms(caller(), 'command) <);
    input = input.explode_quoted();
    if (listlen(input) == 3)
        input = input.delete(2);
    if (listlen(input) != 2)
        return ("Syntax: `" + cmd) + " \"<alias>\" [to] \"<actual command>\"`";
    catch any
        (> .add_command_alias(@input) <);
    with
        return (traceback()[1])[2];
    return strfmt("New command alias %d => %d added.", @input);
};

protected method .del_command_alias_cmd() {
    arg cmdstr, com, template;
    
    (> .perms(caller(), 'command) <);
    template = template.explode_quoted();
    if (listlen(template) == 0)
        return ("Syntax: " + com) + " <template>";
    template = template[1];
    catch ~aliasnf
        (> .del_command_alias(template) <);
    with
        return ("No command alias found matching \"" + template) + "\".";
    return ("Deleted command alias \"" + template) + "\".";
};

protected method .command_aliases_cmd() {
    arg cmdstr, com, what;
    var aliases, a, line, str, num, out, left, right;
    
    (> .perms(caller(), 'command) <);
    if (!what)
        what = this();
    else
        what = (> .match_env_nice(what) <);
    if ((what != this()) && (!(what.is_writable_by(this()))))
        return ("You are not allowed to read the command aliases on " + (what.namef('ref))) + ".";
    if (!(what.has_ancestor($command_aliases)))
        return "Command aliases are not applicable to " + (what.namef('ref));
    out = [("--- Command aliases on " + (what.namef('ref))) + ":"];
    aliases = what.command_aliases();
    if (aliases) {
        for a in (aliases) {
            str = a[1];
            num = 0;
            while ("*" in str) {
                num++;
                left = str.subrange(1, ("*" in str) - 1);
                right = str.subrange(("*" in str) + 1);
                str = ((left + "%") + tostr(num)) + right;
            }
            out += [strfmt("  %30d => %d", str, $command_lib.format_relation(a[2]))];
        }
    } else {
        out += ["  <none>"];
    }
    return out + ["---"];
};

protected method ._tell() {
    arg what, @args;
    var line, conn, type, f;
    
    switch (type(what)) {
        case 'frob:
            what = $parse_lib.filter_ctext(what, #[['formatter, formatter], ["viewer", this()]]);
        case 'string:
            if (!(args && ((args[1]).contains('nomod)))) {
                if (content_type == 'html)
                    what = (((what.replace("&", "&amp;")).replace("<", "&lt;")).replace(">", "&gt;")) + "<br>";
                else if (content_type == 'tkmoo)
                    what = (what.replace("}", "\}")).replace("{", "\{");
            }
        case 'list:
            // a refresh here could allow text output to be corrupted,
            // ohwell, its needed for HUGE lists of input
            for line in (what) {
                ._tell(line, @args);
                refresh();
            }
            return;
        case 'buffer:
            throw(~nobuf, "You are not allowed to send buffers.");
    }
    conn = (| .task_connection() |);
    if (conn && (!global_tell)) {
        conn.write(what);
    } else {
        for conn in (connections)
            (| conn.write(what) |);
    }
};

private method .registered_cmd() {
    arg @args;
    
    return ("Registered names: " + ((registered || []).to_english("none"))) + ".";
};

private method .unregister_name_cmd() {
    arg cmd, cmdstr, name;
    
    catch any
        (> .unregister_name(name) <);
    with
        return (traceback()[1])[2];
    return [("Unregistered alternate name \"" + name) + "\".", ("Registered names: " + ((registered || []).to_english("none"))) + "."];
};

public method .set_tell_traceback() {
    arg which, @lines;
    
    .perms(sender(), 'manager);
    if (!(which in ['verbose, 'brief, 'none]))
        throw(~type, "Which style must either be 'verbose, 'brief, or 'none.");
    if (lines && (type(lines[1]) != 'integer))
        throw(~type, "You must specify the max lines as an integer.");
    if (!lines)
        lines = 0;
    else
        lines = lines[1];
    tell_traceback = [which, lines];
};

public method .namef() {
    arg type;
    var str;
    
    switch (type) {
        case 'doing:
            str = .activity('noidle);
            if (str)
                return (((.name()) + " (") + str) + ")";
            return .name();
        case 'nactivity, 'activity:
            str = .activity();
            if (str)
                return (((.name()) + " (") + str) + ")";
            return .name();
        case 'titled:
            str = .title();
            if (str)
                return (((.name()) + " (") + str) + ")";
            return .name();
        default:
            return (> pass(type) <);
    }
};

protected method .password_cmd(): nooverride {
    arg cmdstr, com, args;
    var syn, c, curr, new, verify;
    
    (> .perms(caller(), 'command) <);
    syn = com + " [<old password> [<new password>]]";
    args = explode(args);
    c = .task_connection();
    if (!args) {
        while (!curr)
            curr = (> (.prompt("Current Password (@abort to abort): ")).trim() <);
    } else {
        curr = args[1];
    }
    if (!(.check_password(curr)))
        return "Invalid Password";
    if (listlen(args) < 2) {
        while (1) {
            while (!new)
                new = (> (.prompt("New Password (@abort to abort): ")).trim() <);
            while (!verify)
                verify = (> (.prompt("Retype New Password (@abort to abort): ")).trim() <);
            if (new == verify)
                break;
            .tell("Passwords do not match!");
            new = (verify = 0);
        }
    } else if (listlen(args) == 2) {
        new = args[2];
    } else {
        (> .tell_error(syn) <);
    }
    catch any
        .set_password(new);
    with
        (> .tell_error(syn, (traceback()[1])[2]) <);
    .tell("Password changed.");
};

protected method .set_title() {
    arg name, definer, value;
    
    .perms(sender());
    if (strlen(value) > 30)
        throw(~type, "Titles must be under 30 characters.");
    title = value;
};

public method .match_context() {
    arg str;
    
    return context[str];
};

public method .context() {
    return context;
};

public method .match_environment() {
    arg str;
    var match, gend;
    
    if ((str == ".") && (match = (| context['last] |))) {
        if (valid(match))
            return match;
    }
    if ((match = (| (.remembered())[str] |))) {
        if (!valid(match))
            .del_remembered(str);
        else
            return match;
    }
    match = (> pass(str) <);
    if (match.has_ancestor($thing)) {
        gend = (| match.gender() |);
        if (gend)
            context = context.add(gend.pronoun('po), match);
    }
    if (type(context) == 'dictionary)
        context = context.add('last, match);
    return match;
};

public method .non_terminated_tell() {
    arg text;
    var conn;
    
    if (.get_setting("prompt", $user)) {
        conn = (| .task_connection() |);
        if (conn && (!global_tell)) {
            conn.write(text, 'non_terminated);
        } else {
            for conn in (connections)
                (| conn.write(text, 'non_terminated) |);
        }
    } else {
        .tell(text);
    }
};

public method .set_name() {
    arg new_name, @ignore;
    var old_name, part, sname;
    
    (> .perms(sender(), 'manager) <);
    
    // if $sys is calling this, we probably want to strip off
    // the user_ prefix...
    if (sender() == $sys)
        new_name = strsed(new_name, ("^" + ((parents()[1]).objname())) + "_", "");
    
    // so it doesnt bomb on .set_objname
    if ((> $user_db.valid_name(new_name) <))
        old_name = .name();
    catch any {
        (> pass(new_name, 'prop) <);
        if (new_name in (registered || []))
            .unregister_name(new_name);
        if (!(| $user_db.key_changed(old_name, new_name) |))
            $user_db.insert(new_name, this());
        if (old_name != new_name) {
            sname = new_name.strip();
            (> .set_objname(tosym("user_" + sname)) <);
        }
    } with {
        (| pass(old_name, 'prop) |);
        rethrow(error());
    }
};

public method .find_object_nice() {
    arg str, @args;
    var match;
    
    catch any {
        match = .find_object(str, @args);
    } with {
        .tell("!  " + ((traceback()[1])[2]));
        throw(~stop, "");
    }
    return match;
};

public method .find_object() {
    arg str, @args;
    var trace, match;
    
    // comprehensive matching method.
    // args define what to match.
    if (!args)
        args = ['environment];
    while (args) {
        switch (args[1]) {
            case 'environment:
                match = (| .match_environment(str) |);
            case 'user:
                match = (| $user_db.search(str) |);
            case 'grasp:
                match = (| $object_lib.to_dbref(str) |);
        }
        if (match)
            return match;
        args = args.delete(1);
    }
    throw(~objnf, ("No object found by the reference \"" + str) + "\".");
};

protected method .age_cmd() {
    arg cmdstr, com, obj;
    var time, gender, out;
    
    (> .perms(caller(), 'command) <);
    time = obj.created_on();
    if (obj.is($thing))
        gender = (obj.gender()).pronoun('psc);
    else
        gender = "It";
    out = [((obj.name()) + " was created on ") + ($time.format("%A %B %d %Y", time)), ((gender + " is ") + ($time.to_english(time() - time))) + " old."];
    if (obj.is($user))
        out += [((gender + " has logged ") + ($time.to_english(obj.connected_seconds()))) + " online."];
    return out;
};

protected method .new_cmd() {
    arg cmdstr, cmd, args;
    var match, name, parent, line, set, nprog, new, t;
    
    (> .perms(caller(), 'command) <);
    if ((match = match_template(args, "* named *"))) {
        name = match[3];
        args = match[1];
    } else {
        name = "";
    }
    catch any
        parent = (> .match_env_nice(args) <);
    with
        return (traceback()[1])[2];
    if (!(parent.is($physical)))
        return ((parent.namef('ref)).capitalize()) + " is not a VR object, you can only create new objects from VR objects (try @spawn).";
    if (name) {
        catch any
            name = (> $code_lib.parse_name(name) <);
        with
            return (traceback()[1])[2];
    }
    
    // spawn from the first parent, add the others
    catch any {
        new = (> parent.new() <);
        if (new.is($located))
            new = (> new.move_to(this()) <);
        if (name) {
            new = (> new.set_name(@name[1]) <);
            for t in (name[2])
                new = (> new.add_name_template(t) <);
        }
        return (("You create \"" + (new.namef('ref))) + "\"") + ((new.name_templates()) ? ((" (" + ((new.name_templates()).to_english())) + ")") : "");
    } with {
        .tell((traceback()[1])[2]);
        if (valid(new)) {
            line = new.namef('xref);
            catch ~isfrob
                (> new.destroy() <);
            with
                (> new.discard() <);
            if (valid(new))
                return ("Unable to destroy new object " + line) + ".";
            else
                return ("Sucessfully destroyed new object " + line) + ".";
        }
    }
};

protected method .description_cmd() {
    arg cmdstr, cmd, str;
    var args, obj, desc, long;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "* as *"))) {
        obj = (> .match_env_nice(args[1]) <);
        desc = ((args[3]).trim()).unquote();
    } else {
        obj = (> .match_env_nice(str) <);
        if ((desc = .read()) == 'aborted)
            return;
        desc = join(desc.flatten()).trim();
    }
    if (!desc)
        desc = 0;
    catch any
        obj.set_prose(desc);
    with
        return (traceback()[1])[2];
    return ("Description for " + (obj.namef('ref))) + " set.";
};

protected method .status_cmd() {
    arg cmdstr, com, @args;
    var line, s, x, out, utime, stime, nosys;
    
    (> .perms(caller(), 'command) <);
    s = $sys.status();
    for x in [1 .. s.length()] {
        if ((s[x]) == (-1))
            nosys++;
    }
    out = [("--- " + ($motd.server_name())) + " status report ---"];
    if ($sys.dirty())
        out += ["System is:        dirty, will do normal backup."];
    else
        out += ["System is:        clean, will skip backup."];
    utime = ((strsub($time.to_english(s[1]), " and", ",") + " and ") + ((s[2]) / 1000)) + " milliseconds";
    stime = ((strsub($time.to_english(s[3]), " and", ",") + " and ") + ((s[4]) / 1000)) + " milliseconds";
    out += ["System lag:       " + ($lag_watcher.lag()), "Next dbref:       " + ($sys.next_objnum()), "Driver:           " + ($sys.server_info('driver_version, 'long)), "Core:             " + ($sys.server_info('core_version, 'long)), ("Started:          " + ($time.to_english(time() - ($sys.server_info('startup_time))))) + " ago", ("Backup:     last: " + ($time.to_english(time() - (s[21])))) + " ago", ("            next: " + ($time.to_english((s[22]) - time()))) + " from now", "        interval: " + ($time.to_english(s[20]))];
    if (!nosys)
        out += ["CPU time used:    user: " + utime, "                  system: " + stime, ((("Page:             " + (s[9])) + " reclaims ") + (s[10])) + " faults", ((("Context switches: " + (s[17])) + " voluntary ") + (s[18])) + " involuntary", "Signals:          " + (s[16]), "---"];
    return out;
};

public method .del_command_alias() {
    arg alias;
    
    (> .perms(sender()) <);
    (> pass(alias) <);
    if ((!(.command_aliases())) && ($command_aliases_parser in (.parsers()))) {
        .tell("Removing $command_aliases_parser from your list of parsers.");
        .del_parser($command_aliases_parser);
    }
};

public method .add_command_alias() {
    arg alias, actual;
    
    (> .perms(sender()) <);
    (> pass(alias, actual) <);
    if ((.command_aliases()) && (!($command_aliases_parser in (.parsers())))) {
        .tell("Adding $command_aliases_parser to your list of parsers..");
        .add_parser($command_aliases_parser);
    }
};

public method .logout_connection() {
    arg connection;
    
    if ((sender() != this()) || (definer() != caller()))
        throw(~perm, "Invalid access to private method.");
    .tell(("<Login> " + ((((.connections()).length()) + 1).n_to_nth())) + " logout.");
};

protected method .rehash_cmd() {
    arg cmdstr, cmd, args;
    var target, client, opts, client, o;
    
    (> .perms(caller(), 'command) <);
    [args, opts] = args;
    if ((o = (| "c?lient" in (opts.slice(1)) |)))
        client = (opts[o])[3];
    else if ((o = (| "r?aw" in (opts.slice(1)) |)))
        client = !((opts[o])[3]);
    if (args)
        target = (> .match_env_nice(join(args)) <);
    else
        target = this();
    catch ~perm {
        if (client) {
            .tell(("Rehashing commands on " + (target.namef('ref))) + "...");
            target.cache_client_uninit();
            target.cache_client_init();
            .tell("Done.");
        } else {
            .tell(("Rehashing (raw) commands on " + (target.namef('ref))) + "...");
            target.rehash_cache();
            .tell("Done.");
        }
    } with {
        return "You do not have permission to rehash " + (target.namef('ref));
    }
};

public method .description() {
    arg flags;
    var c, contents, ctext, pronoun, lines, p, br;
    
    br = $cml_lib.format_br_tag();
    pronoun = (.gender()).pronoun('psc);
    if (connections)
        lines = [((pronoun + " is ") + ((.activity()) || "awake")) + ".", br];
    else
        lines = [(pronoun + " is asleep, and was last connected ") + ($time.format("%d %B %y %H:%M", abs(connected_at))), br];
    if ((contents = .contents())) {
        lines += [pronoun + " is holding:"];
        lines += [(<$format, ["dfn", [["nobound", 1]], [(<$generator, ["join", [["separator", br]], map c in (contents) to ($cml_lib.format_obj_tag('look, c, c.name(), 'contained)), 'gen_join]>)], 'do_dfn]>)];
    }
    return (> pass(flags) <) + [$ctext_frob.new_with(lines)];
};

protected method ._who__at_place() {
    arg str;
    var place, thing, who, args;
    
    if (str == "home")
        place = .home();
    else
        place = (| .match_environment(str) |);
    
    // try the place db
    if (!place) {
        catch any {
            place = $place_db.search(str);
        } with {
            switch (error()) {
                case ~ambig:
                    .tell("Several places match that name: " + ((((traceback()[1])[3]).mmap('namef)).to_english()));
                case ~namenf:
                    .tell(("The place \"" + str) + "\" cannot be located.");
                    return 0;
                default:
                    .tell((traceback()[1])[2]);
                    return 0;
            }
        }
    }
    who = [];
    for thing in (place.contents()) {
        if (thing.has_ancestor($user))
            who += [thing];
    }
    if (!who) {
        .tell(("Nobody is in " + (place.name())) + ".");
        return 0;
    }
    args = [who, "Users in " + (place.name())];
    args = [@args, [['namef, 'titled], ['idle_time]]];
    args = [@args, ["Name", "Times (idle)"], [1, 1]];
    return args;
};

protected method ._who__is() {
    arg people, @args;
    var person, p, who, x;
    
    who = [];
    if (type(people) == 'string)
        people = ($string.explode_english_list(people, @args)) || [];
    for p in (people) {
        catch any {
            person = $user_db.search(p);
        } with {
            switch (error()) {
                case ~ambig:
                    .tell(((("The name \"" + p) + "\" can match any of: ") + ($list.to_english(filter x in ($user_db.users()) where (x.match_begin(p))))) + ".");
                    continue;
                default:
                    // hack, look for robots..
                    catch any {
                        person = ($robot.children()).match_object(p);
                    } with {
                        .tell(("I don't know who \"" + p) + "\" is.");
                        continue;
                    }
            }
        }
        who += [person];
    }
    if (!who)
        return 0;
    return [who, ((who.length()) == 1) ? "User" : "Users"];
};

protected method ._who__programmers() {
    arg args, all;
    var out, progs, p, x, t;
    
    progs = [];
    if (args && (!all)) {
        for p in (args) {
            x = $user_db.search(p);
            if (!x)
                .tell(("I don't know who \"" + p) + "\" is.");
            else
                progs += [x];
        }
        t = (("Programmer" + (progs.length())) == 1) ? "" : "s";
    } else if (all) {
        t = "All Programmers";
        progs = $programmer.descendants();
        progs = progs.setremove($admin);
    } else {
        t = "Connected Programmers";
        for p in ($user_db.connected()) {
            if (p.has_ancestor($programmer))
                progs += [p];
        }
    }
    if (!progs)
        return 0;
    return [progs, t];
};

protected method ._who__admins() {
    arg args, all;
    var out, admins, a, x, t;
    
    admins = [];
    if (args && (!all)) {
        for a in (args) {
            x = $user_db.search(a);
            if (!x)
                .tell(("I don't know who \"" + a) + "\" is.");
            else
                admins += [x];
        }
        t = (("Admin" + (admins.length())) == 1) ? "" : "s";
    } else if (all) {
        t = "All Admins";
        admins = $sys.admins();
    } else {
        t = "Connected Admins";
        for a in ($user_db.connected()) {
            if (a.has_ancestor($admin))
                admins += [a];
        }
    }
    if (!admins)
        return 0;
    return [admins, t];
};

protected method ._who__short() {
    arg people, title, @rest;
    var user, tmp, who, namestr, total;
    
    who = [];
    total = people.length();
    .tell((((title + " (total: ") + tostr(total)) + ((total == 1) ? " person" : " people")) + "):");
    for user in (people) {
        //     namestr = " " + user.name() + " (" + $time.elapsed(time()
        // - user.connected_at())
        //+ " " + $time.dhms(user.idle_seconds()) + ")";
        namestr = (((((" " + (user.name())) + " (") + ($time.dhms(time() - (user.connected_at())))) + "/") + ($time.dhms(user.idle_seconds()))) + ")";
        who += [namestr];
        if (tmp < ((namestr.length()) + 2))
            tmp = (namestr.length()) + 2;
    }
    .tell($list.vcolumnize(who, (.linelen()) / (tmp + 1), .linelen()));
};

protected method .remember_cmd() {
    arg cmdstr, cmd, what, as, str;
    
    (> .perms(caller(), 'command) <);
    .add_remembered(what, str);
    return ((("Remembering " + (what.namef('xref))) + " as \"") + str) + "\".";
};

protected method .forget_place() {
    arg place;
    
    if (type(place) != 'objnum)
        throw(~type, "Place must be submitted as an object.");
    remembered_places = remembered_places.setremove(place);
};

protected method .remembered_cmd() {
    arg cmdstr, cmd, args;
    var item, out;
    
    (> .perms(caller(), 'command) <);
    if (!(.remembered()))
        return .tell("You do not remember anything.");
    out = [];
    for item in (.remembered())
        out += [(("  " + (item[1])) + " is ") + ((item[2]).namef('xref))];
    return ["Remembered Items:"] + (out.lcolumnize());
};

protected method .forget_cmd() {
    arg cmdstr, cmd, str;
    var what;
    
    (> .perms(caller(), 'command) <);
    what = (| remembered[str] |);
    if (!what)
        return ("You don't remember what \"" + str) + "\" is...";
    .del_remembered(str);
    return ((("Forgetting " + (what.namef('xref))) + " as \"") + str) + "\".";
};

public method .idle_time() {
    arg @args;
    var idle;
    
    [(args ?= 'dhms)] = args;
    idle = .idle_seconds();
    if ((connected_at < 0) || (idle < 30))
        return "";
    switch (args) {
        case 'dhms:
            return $time.dhms(idle, 'long);
        case 'elapsed:
            return $time.elapsed(idle);
        case 'seconds:
            return idle;
    }
};

protected method .whereis_cmd() {
    arg cmdstr, cmd, who;
    var user, u;
    
    (> .perms(caller(), 'command) <);
    who = (who && (who.explode_english_list())) || [];
    if (who && ((who[1]) == "is"))
        who = who.delete(1);
    if (!who)
        return "You must specify somebody.";
    for user in [1 .. who.length()] {
        u = (| $user_db.search(who[user]) |);
        if (!u) {
            .tell(("I don't know who \"" + (who[user])) + "\" is.");
            who = who.replace(user, 0);
        } else {
            who = who.replace(user, u);
        }
    }
    for user in (who) {
        if (user)
            .tell(((user.namef('nactivity)) + " is in ") + ((user.location()).name()));
    }
};

public method .connected_time() {
    arg @args;
    
    [(args ?= 'dhms)] = args;
    if (connected_at < 0)
        return "Last on: " + ctime(abs(connected_at));
    switch (args) {
        case 'dhms:
            return $time.dhms(time() - connected_at, 'long);
        case 'elapsed:
            return $time.elapsed(time() - connected_at);
        case 'seconds:
            return time() - connected_at;
    }
};

protected method .name_templates_cmd() {
    arg cmdstr, com, obj;
    
    (> .perms(caller(), 'command) <);
    if (!(obj.has_ancestor($has_name)))
        return (obj.name()) + " is not descended from $has_name!";
    return (("Name templates for " + (obj.namef('ref))) + ": ") + ((obj.name_templates()).to_english("none"));
};

public method .connection_going_away() {
    arg addr, port;
    var con, line, opt;
    
    catch any {
        (> .perms(caller(), $connection) <);
        for con in (connections) {
            if (!valid(con))
                connections = connections.setremove(con);
        }
        con = sender() in connections;
        connections = connections.setremove(sender());
        catch any {
            for opt in (connection_options) {
                if (!((opt[1]) in connections))
                    connection_options = connection_options.del(opt[1]);
            }
        }
        if (!connections)
            .logout(sender());
        else
            .logout_connection(sender());
        line = ((((((("DISCONNECT " + tostr(con)) + " (") + ((.parents())[1])) + "): ") + this()) + " <") + addr) + ">";
        (| $sys.log(line) |);
    } with {
        $sys.log($parse_lib.traceback(traceback()));
    }
};

public method .read() {
    arg @args;
    var text, output, head, tail;
    
    if (!(.connections()))
        return 'not_connected;
    if ((.task_connection()).is_reading_block())
        return 'engaged;
    if (args.length())
        head = args[1];
    else
        head = "Receiving input.  Enter \".\" to finish or \"@abort\" to abort.";
    if ((args.length()) > 1)
        tail = args[2];
    else
        tail = "** Aborted **; Text thrown away.";
    if (head)
        .ptell(head, #[['type, 'read]]);
    output = (.task_connection()).start_reading_block('multiple);
    if ((output == 'aborted) && tail)
        .ptell(tail, #[['type, 'read]]);
    return output;
};

public method .read_line() {
    arg @args;
    var line, abort, head, con;
    
    if (!(.connections()))
        return 'not_connected;
    con = (| .task_connection() |) || ((.connections())[1]);
    if (con.is_reading_block())
        throw(~engaged, "This connection is already reading input.");
    [(head ?= ""), (abort ?= 'yes)] = args;
    if (head)
        .tell(head);
    line = con.start_reading_block('one);
    if ((line == 'aborted) || ((abort != 'no) && ((| (line[1]).trim() |) == "@abort"))) {
        if (type(abort) == 'string)
            throw(~stop, abort);
        else
            throw(~stop, "** Aborted **");
    }
    if ((| type(line[1]) |) != 'string)
        throw(~prompt, "Unexpected result from .prompt(): " + line);
    return line[1];
};

public method .prompt() {
    arg prompt, @abort;
    
    // second argument represents how to handle '@abort' as input,
    // if it is 'no, then '@abort' is treated as any other string.
    // If it is 'yes, then ~stop will be thrown if @abort is
    // encountered, with the message "** Aborted **".  If it is a
    // string, then the behaviour is the same as with 'yes, but
    // that string is used instead of the default message.
    .non_terminated_tell(prompt);
    [(abort ?= 'yes)] = abort;
    return (> .read_line(0, abort) <);
};

protected method .ways_cmd() {
    arg cmdstr, cmd, rest;
    var exits, e, line, out, loc;
    
    (> .perms(caller(), 'command) <);
    loc = .location();
    exits = loc.visible_exits();
    if (!exits)
        return "There are no visible exits from this room.";
    
    // come up with some settings to configure how to display exits
    // for now they can deal with the following
    out = [];
    if ((.get_setting("exit-style", $user)) == 'none) {
        out += ["Visible exits: "];
        for e in (exits)
            out += [((("  " + (e.name())) + ((e.name_templates()) ? ((" (" + ((e.name_templates()).to_english())) + ")") : "")) + " to ") + ((e.dest(loc)).name())];
    } else {
        out += loc.format_exits(exits, #[['actor, this()]]);
    }
    return out + ["---"];
};

public method .set_objname(): nooverride {
    arg new_objname;
    
    if ((caller() != $user) && (!(sender() in ($sys.system()))))
        throw(~perm, "User objnames can only be changed by $user.");
    (> pass(new_objname) <);
};

protected method .context_cmd() {
    arg @args;
    var out;
    
    (> .perms(caller(), 'command) <);
    out = ["Last thing: " + ((| (context['last]).name() |) || "(nothing)")];
    out += ["Last it:    " + ((| (context["it"]).name() |) || "(nothing)")];
    out += ["Last her:   " + ((| (context["her"]).name() |) || "(nothing)")];
    out += ["Last him:   " + ((| (context["him"]).name() |) || "(nothing)")];
    return out;
};

private method .register_name_cmd() {
    arg cmd, cmdstr, name;
    
    catch any
        (> .register_name(name) <);
    with
        return (traceback()[1])[2];
    return [("Registered alternate name \"" + name) + "\".", ("Registered names: " + (registered.to_english("none"))) + "."];
};

private method .unregister_name() {
    arg old;
    
    registered = setremove(registered || [], old);
    if (!registered)
        (| clear_var('registered) |);
    (| $user_db.remove(old) |);
};

private method .register_name() {
    arg new;
    
    if (!(new in (registered || []))) {
        (> $user_db.valid_name(new) <);
        (> $user_db.insert(new, this()) <);
        if (registered)
            registered += [new];
        else
            registered = [new];
    }
};

protected method .look_cmd() {
    arg cmdstr, cmd, args;
    var m, obj, desc, flags, loc, prep, line, exam;
    
    (> .perms(caller(), 'command) <);
    
    // flags that are always the same
    flags = #[['actor, this()], ['actor_location, .location()], ['examine, match_begin(cmd, "e")], ['exclude, [this()]]];
    
    // Because we do some non-environment things, we parse look ourselves.
    // some times I critically catch things and sometimes I let the catch
    // statement catch them, this is because of how I want the errors to look.
    catch any {
        if ((m = match_template(args, "in|on *"))) {
            obj = (> .match_environment(m[2]) <);
            flags = (flags.add('type, m[1])).add_elem('exclude, obj);
            return obj.get_description(flags);
        } else {
            if ((m = match_template(args, "at *")))
                args = m[2];
            if (!args) {
                obj = .location();
                return obj.get_description(flags.add_elem('exclude, obj));
            } else if ((m = match_template(args, "* in|on *"))) {
                prep = m[2];
                catch any
                    loc = (> .match_environment(m[3]) <);
                with
                    return (traceback()[1])[2];
                obj = (| loc.match_environment(m[1]) |);
                if (!obj) {
                    return (> loc.get_detail(m[1]) <);
                } else if ((m = match_template(args, "det?ail *"))) {
                    desc = (| loc.get_detail(m[2]) |);
                    if (!desc)
                        return strfmt("No detail %d %l %l.", m[2], prep, loc.name());
                    return desc;
                } else {
                    return obj.get_description(flags.add_elem('exclude, obj));
                }
            } else if ((m = match_template(args, "det?ail *"))) {
                return (> (.location()).get_detail(m[2]) <);
            } else {
                obj = (> .match_environment(args) <);
                return obj.get_description(flags.add_elem('exclude, obj));
            }
        }
    } with {
        line = (traceback()[1])[2];
        if (error() in [~ambig, ~nodetail])
            return line;
        desc = (| (.location()).get_detail(args) |);
        if (!desc)
            return line;
        return desc;
    }
};

protected method .walk_path() {
    arg @path;
    var p, exit, exits, e, l, oal;
    
    if (!path)
        throw(~badpath, "Walk nowhere?");
    oal = .get_auto_look();
    .set_auto_look($user, "", 0);
    catch any {
        for p in (path) {
            // did we actually move?
            l = .location();
            exits = l.exits();
            if (!(exit = find e in (exits) where (e.match_name(p))))
                .tell((("No exit \"" + p) + "\" from ") + (l.name()));
            else
                (exits[exit]).invoke();
            pause();
        }
        .set_auto_look(0, 0, oal);
    } with {
        .set_auto_look(0, 0, oal);
        rethrow(error());
    }
};

protected method .set_content_type() {
    arg name, definer, value;
    var sets, meth;
    
    // a touch of Pueblo cruft crap
    if ((formatter == $pueblo_format) && (value != 'pueblo))
        (.connections()).mmap('write, "<img xch_mode=text>Rich-HTML disabled");
    content_type = value;
    formatter = lookup(tosym(value + "_format"));
    meth = tosym("set_content_type_" + value);
    if ((| .find_method(meth) |))
        (> .(meth)() <);
};

public method .evaluator() {
    return evaluator;
};

protected method .set_cols() {
    arg name, definer, value, @args;
    
    if ((value == 80) || (!value))
        (| clear_var('cols) |);
    else
        cols = value;
};

protected method .take_from_cmd() {
    arg cmdstr, cmd, what, p, loc;
    var c, obj, l, wl;
    
    (> .perms(caller(), 'command) <);
    if (loc == this())
        return ("You already have " + (what.name())) + ".";
    for c in (loc.contents()) {
        if (c.match_name(what))
            obj = c;
    }
    if (!obj)
        return ((.name()) + " does not have ") + what;
    if ((obj == this()) || (obj == loc))
        return "Ewww, its all twisty.";
    catch any {
        l = .location();
        wl = loc.location();
        (> obj.move_to(this()) <);
        if (l != wl)
            wl.announce(((((((((.name()) + " ") + cmd) + "s ") + (obj.name())) + " ") + p) + " ") + (loc.name()), this());
        l.announce(((((((((.name()) + " ") + cmd) + "s ") + (obj.name())) + " ") + p) + " ") + (loc.name()), this());
        return ((((((("You " + cmd) + " ") + (obj.name())) + " ") + loc) + " ") + (loc.name())) + ".";
    } with {
        switch (error()) {
            case ~locked:
                if (loc.is($user))
                    loc.tell((((.name()) + " tried to take ") + (obj.name())) + " from you.");
                return (((obj.name()) + " is locked to ") + ((obj.lock()).lock_name('thing))) + ".";
            default:
                return (traceback()[1])[2];
        }
    }
};

public method .set_activity() {
    arg str;
    
    (> .perms(sender()) <);
    activity = str;
};

public method .is_tellable_by() {
    arg caller, sender;
    
    return (sender == this()) || (caller in [$place, $user, $programmer, $admin, $mail_ui, $help_ui, $editor_session]);
};

protected method .go_cmd() {
    arg cmdstr, cmd, path;
    var m, route, loc;
    
    (> .perms(caller(), 'command) <);
    if ((m = match_template(path, "to *"))) {
        path = m[2];
        if (!path) {
            .tell("Specify a destination.");
            return;
        }
        if (path == "home")
            loc = .home();
        else
            loc = (| .match_environment(path) |);
    
        // if we have still not found a location...
        if (!loc) {
            catch any {
                loc = $place_db.search(path);
            } with {
                switch (error()) {
                    case ~ambig:
                        .tell("Several rooms match that name: " + ((((traceback()[1])[3]).mmap('namef)).to_english()));
                    case ~namenf:
                        .tell(("Unable to find place \"" + path) + "\".");
                        return;
                    default:
                        return (traceback()[1])[2];
                }
            }
        }
        if (!loc) {
            .tell(("Unable to find place \"" + path) + "\".");
            return;
        }
        if (loc == (.location())) {
            .tell("You are already there!");
            return;
        }
        if (!(route = (| $place_lib.bfs(.location(), loc) |)))
            throw(~stop, ("I can't find a route to " + path) + ".");
        return .follow_path(@route);
    }
    path = path.explode_quoted();
    catch any
        .walk_path(@path);
    with
        .tell((traceback()[1])[2]);
    if (auto_look != 'no)
        .tell((.location()).get_description(#[['actor, this()], ['exclude, [this()]]]));
    return "You arrive";
};

public method .ptell() {
    arg what, flags;
    
    if (!(.is_tellable_by(caller(), sender())))
        throw(~perm, "Only allowed objects may call protected tell.");
    ._tell(what, flags);
};

public method .connection_starting() {
    arg addr, port;
    var line, c;
    
    (> .perms(caller(), $connection) <);
    
    // shutoff our connection's timeout
    sender().set_timeout(0);
    
    // cleanup our connections list
    for c in (connections) {
        if (!valid(c))
            connections = setremove(connections, c);
    }
    connections = setadd(connections, sender());
    if ((connections.length()) == 1)
        (| .login(sender()) |);
    else
        (| .login_again(sender()) |);
    line = ("CONNECT " + tostr(sender() in connections)) + " (";
    line = (line + ((.parents())[1])) + "): ";
    line = (((line + this()) + " <") + (sender().address())) + "> ";
    (| $sys.log(line) |);
};

protected method .reset_parsers() {
    var p, list;
    
    parsers = [];
    list = (.get_setting("extended-parsers", $user)) || [];
    for p in ((.get_base_parsers()) + list)
        .add_parser(p);
};

public method .connected_seconds() {
    return connected_seconds;
};

protected method .add_name_template_cmd() {
    arg cmdstr, cmd, args;
    var obj, template;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    if ((listlen(args) > 2) && ((args[2]) == "to"))
        args = delete(args, 2);
    if (listlen(args) > 2)
        args = [args[1], sublist(args, 2).join()];
    if ((!args) || (listlen(args) != 2))
        return ("Syntax: `" + cmd) + " \"<template>\" [to] \"<object>\"`";
    obj = (> .match_env_nice(args[2]) <);
    template = args[1];
    if (!(obj.has_ancestor($has_name)))
        return obj + " cannot have regular names.";
    catch any
        obj = (> obj.add_name_template(template) <);
    with
        return (traceback()[1])[2];
    return ((((("Added name template \"" + template) + "\" to ") + (obj.namef('ref))) + ", templates: ") + ((obj.name_templates()).to_english())) + ".";
};

protected method .add_remembered() {
    arg what, name;
    
    remembered = (remembered || #[]).add(name, what);
};

protected method .del_remembered() {
    arg name;
    
    remembered = (remembered || #[]).del(name);
    if (!remembered)
        clear_var('remembered);
};

public method .remembered() {
    return remembered || #[];
};

public method .task_connections() {
    return task_connections;
};

public method .task_connection() {
    return task_connections[task_id()];
};

protected method .set_global_tell() {
    arg @args;
    
    if ((args[3]) == 0)
        clear_var('global_tell);
    else
        global_tell = 1;
};

public method .get_global_tell() {
    arg @args;
    
    return global_tell;
};

public method .match_name() {
    arg str;
    var m, n;
    
    if (!str)
        return 0;
    if ((m = pass(str)))
        return m;
    for n in (registered || []) {
        if ((m = match_begin(n, str)))
            return m;
    }
    return 0;
};

protected method .discard_cmd() {
    arg cmdstr, cmd, target;
    var msg, s, name;
    
    (> .perms(caller(), 'command) <);
    if ((cmdstr.trim()) == "discard") {
        s = (> .prompt(("Are you sure you want to discard " + (target.name())) + "? ") <);
        if (!(s in ["yes", "y"]))
            return ("Ok, not discarding " + (target.name())) + ".";
    }
    if (((target.location()) != this()) && (!(target.is($path))))
        return ("You are not holding " + (target.name())) + ".";
    name = target.name();
    if (type(target) == 'frob) {
        catch ~perm
            target.discard();
        with
            return (traceback()[1])[2];
    } else if ((target.manager()) == this()) {
        target.destroy();
    } else {
        target.move_to($trash);
        msg = $mail_message.new_mail();
        msg.set_subject("Discarded Object");
        msg.set_text([(((((((target.name()) + " has been discarded by ") + (.name())) + ". It currently exists in ") + ($trash.namef('ref))) + ", and will be destroyed in 15 days.  You may retrieve it with the command `@move ") + target) + " to me`."]);
        (| msg.send(target.manager()) |);
    }
    return ("Discarding " + name) + ".";
};

public method ._list_objects() {
    arg objs, multi, @args;
    var line, obj, c2, name, fmt, out, c1;
    
    if (!objs) {
        out = ["** None **"];
    } else {
        c2 = ((| sender().linelen() |) || 79) / 10;
        c1 = c2 * 4;
        fmt = "%5L%*L %*L %*L";
        out = [strfmt(fmt, "#", c1, "Name", c2, "Flags", c2, "Size") + "Manager"];
        for obj in (objs) {
            line = strfmt(fmt, obj.(multi)(@args).length(), c1, obj.namef('xref), c2, $object_lib.see_perms(obj, ["", ""]), c2, obj.size());
            name = (obj.manager()).namef('xref);
            if ((name.length()) > c1)
                name = name.pad(c1);
            out += [line + name];
            refresh();
        }
    }
    return out;
};

protected method .personal_info() {
    return info || #[];
};

public method .personal_fields() {
    return #[["real-name", 1], ["email", 1], ["address", 1], ["affiliation", 1], ["position", 1], ["location", 1], ["interests", 1], ["plan", 1], ["projects", 1], ["home-page", 0]];
};

protected method .monitor_cmd() {
    arg cmdstr, cmd, @args;
    var e, out, line, len;
    
    (> .perms(caller(), 'command) <);
    if (!(args[1])) {
        if (monitor == 0)
            return "You are not monitoring what you hear.";
        out = [];
        len = .linelen();
        for e in ((monitor || []).reverse()) {
            line = strfmt("%20S %30S ", (| (e[1]).namef('xref) |) || toliteral(e[1]), ((((e[2]) + ".") + (e[4])) + "() line ") + (e[5])) + (e[6]);
            if (strlen(line) > len)
                line = line.chop(len);
            out += [line];
        }
        return out + ["---"];
    }
    if ("on" in args) {
        monitor = [];
        return "You are now monitoring what you hear.";
    } else {
        (| clear_var('monitor) |);
        return "You are no longer monitoring what you hear.";
    }
};

protected method .monitor() {
    return monitor;
};

protected method .examine_cmd() {
    arg cmdstr, cmd, args;
    var obj, opts, i, chop, out, m, cmds, c, desc, notfrobby, frobhandler;
    
    (> .perms(caller(), $user) <);
    obj = args[1];
    opts = args[3];
    chop = .linelen();
    if (type(obj) != 'frob)
        notfrobby = 1;
    if (notfrobby)
        c = obj.created_on();
    if ((i = "ch?op" in (opts.slice(1))) && (!((opts[i])[3])))
        chop = 0;
    out = ["Object (@rename):    " + (obj.namef('ref)), "Templates (@ant):    " + ((| (obj.name_templates()).to_english("none") |) || "none")];
    if (notfrobby)
        out += ["Created:             " + (c ? ctime(c) : "(Before Time)"), (("Quota:               " + ((obj.quota()).to_english())) + " bytes") + ((obj.quota_exempt()) ? " ** exempt **" : "")];
    out += [("Size:                " + ((notfrobby ? (obj.size()) : size(obj)).to_english())) + " bytes (on disk)"];
    if (notfrobby)
        out += ["Perms (@chmod):      " + (((obj.flags()).prefix("+")).join())];
    out += ["Manager (@chmanage): " + ($object_lib.get_name(obj.manager(), 'namef, ['ref])), ._exam_sub("Writer", 1, "@aw/@dw", chop, obj, 'writers, 'literal)];
    if (notfrobby)
        out += [._exam_sub("Trusted", 0, "@at/@dt", chop, obj, 'trusted, 'literal), ._exam_sub("Parent", 1, "@ap/@dp", chop, obj, 'parents)];
    if (!notfrobby) {
        out += ["Frob Class:          " + frob_class(obj)];
        if ((frobhandler = (| frob_handler(obj) |)))
            out += ["Frob Handler:        " + frobhandler];
    }
    if (obj.has_ancestor($located))
        out += ["Location (@move):    " + ($object_lib.get_name(obj.location(), 'namef, ['xref]))];
    if ((desc = (| obj.prose() |)))
        out += ["Description:", "@describe " + ((type(obj) == 'frob) ? (obj.name()) : obj), @(type(desc) == 'frob) ? (desc.uncompile()) : ((type(desc) == 'list) ? desc : [desc]), "."];
    if ((cmds = (| obj.remote_commands() |)))
        out += $command_lib.format_commands_short(#[[obj, cmds]], "Remote", .linelen());
    if ((cmds = (| obj.local_commands() |)))
        out += $command_lib.format_commands_short(#[[obj, cmds]], "Local", .linelen());
    return out + ((| obj.examine() |) || []);
};

protected method ._exam_sub() {
    arg name, plural, cmd, chop, obj, meth, @args;
    var list, line;
    
    list = (| obj.(meth)(@args) |) || [];
    if (!plural)
        line = pad(((name + " (") + cmd) + "):", 21) + (list.to_english("(none)"));
    else if (listlen(list) != 1)
        line = pad(((name + "s (") + cmd) + "):", 21) + (list.to_english("(none)"));
    else
        line = pad(((name + " (") + cmd) + "):", 21) + ((list[1]).namef('ref));
    if (chop)
        line = line.chop(chop);
    return line;
};

protected method .map_cmd() {
    arg cmdstr, cmd;
    var l, obj, pos;
    
    (> .perms(caller(), 'command) <);
    l = .location();
    pos = l.get_setting("map-position", $realm_settings);
    return (| (pos[4]).view(@pos.subrange(1, 3), 20, 79) |) || "This room doesn't have map defined for it.";
};

protected method .finger_cmd() {
    arg cmdstr, cmd, who;
    var out, awaymsg;
    
    (> .perms(caller(), 'command) <);
    out = ([("Information on " + (who.name())) + " (use @set to change):"] + ((who.display_info('no_blanks)).prefix("  "))) + ((.age_cmd("", "", who)).prefix("  "));
    if (who.connected()) {
        if ((| (awaymsg = who.away()) |))
            return out + [(((("  " + (who.name())) + " has been away for ") + ($time.dhms(time() - (who.away_time()), 1))) + ": ") + awaymsg];
        return out + [("  " + (who.name())) + " is currently connected."];
    } else {
        return out + [(((("  " + (who.name())) + " was last connected at ") + ($time.format("%I:%M:%S %p", abs(who.connected_at())))) + " ") + ($time.format("%A %B %d %Y", abs(who.connected_at())))];
    }
};

public method .prompt_yesno() {
    arg str, @def;
    var input, rx;
    
    // the second argument is an integer for the default value 
    [(def ?= 1)] = def;
    input = (> .prompt(str) <);
    if (match_regexp(input, "^(y|ye|yes)$"))
        return 1;
    if (match_regexp(input, "^(n|no)$"))
        return 0;
    return def;
};

protected method .del_name_template_cmd() {
    arg cmdstr, cmd, args;
    var syn, obj, template;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    if ((listlen(args) > 2) && ((args[2]) == "from"))
        args = delete(args, 2);
    if (listlen(args) > 2)
        args = [args[1], sublist(args, 2).join()];
    if ((!args) || (listlen(args) != 2))
        return ("Syntax: `" + cmd) + " \"<template>\" [from] \"<object>\"`";
    obj = (> .match_env_nice(args[2]) <);
    template = args[1];
    if (!(obj.has_ancestor($has_name)))
        return obj + " cannot have regular names.";
    if (!(template in (obj.name_templates())))
        return (((obj.name()) + " does not have the name template \"") + template) + "\"";
    catch any
        obj = (> obj.del_name_template(template) <);
    with
        return (traceback()[1])[2];
    return ((((("Deleted name template \"" + template) + "\" from ") + (obj.namef('ref))) + ", templates: ") + ((obj.name_templates()).to_english("none"))) + ".";
};

public method .get_cols() {
    arg @args;
    
    return cols || 80;
};

public method .get_rows() {
    arg @args;
    
    return rows || 19;
    
    // 19 is the number of display rows you have in tf, in
    // visual mode with a default display/terminal.
};

protected method .set_rows() {
    arg name, definer, value, @args;
    
    if ((value == 19) || (!value))
        (| clear_var('rows) |);
    else
        rows = value;
};

public method .get_base_parsers() {
    if (.command_aliases())
        return [$command_aliases_parser, $command_parser, $channel_parser];
    return [$command_parser, $channel_parser];
};

protected method .paste_cmd() {
    arg cmdstr, com, args;
    var obj, text, who, w, target;
    
    (> .perms(caller(), 'command) <);
    if (args) {
        args = args.sed("^to +", "");
        if ("," in args)
            args = args.explode_english_list();
        else
            args = args.explode();
        who = [];
        for w in (args) {
            catch ~ambig, ~namenf {
                target = (> $user_db.search(w) <);
            } with {
                catch any
                    target = (> .match_environment(w) <);
                with
                    .tell((traceback()[1])[2]);
            }
            if (target)
                who = setadd(who, target);
        }
        if (!who)
            return "No valid targets.";
    }
    text = .read();
    if (text == 'aborted)
        return .tell("@paste aborted.");
    else if (!text)
        return .tell("@paste nothing?");
    text = [((" " + (.name())) + " (@paste's) ").center(79, "-", 'both), @text, " + Finis + ".center(79, "-", 'both)];
    if (who) {
        for w in (who)
            (| w.tell(text) |);
        .tell(((((text.length()) - 2) + " lines of text pasted to ") + (who.map_to_english('name))) + ".");
    } else {
        (.location()).announce(text);
        .tell(((text.length()) - 2) + " lines of text pasted");
    }
};

public method .remote_cmd() {
    arg cmdstr, com, who, prep, str;
    var target, line, fstr, wstr, type, bad, awaymsg;
    
    (> .perms(caller(), $user, $robot) <);
    if (str && ((str[1]) == ":")) {
        type = 'emote;
        str = str.subrange(2);
    } else {
        type = 'say;
    }
    who = (> .parse_interaction_reference(who, tostr(type), 'userdb) <);
    if ((bad = filter target in (who) where (type(target) != 'objnum)))
        return ("Unable to find " + (bad.to_english())) + ".";
    .add_interaction('objs, who);
    line = .name();
    if (str && ((str[1]) == ":"))
        str = str.subrange(2);
    else
        line += " ";
    if (type == 'emote) {
        line += str;
    } else {
        if (str)
            line += $code_lib.punctuation_type(str);
        else
            line += "say";
        line = ((line + "s, \"") + str) + "\"";
    }
    wstr = (who.mmap('name)).to_english();
    fstr = "[from " + ((.location()).name());
    if ((who.length()) > 1)
        fstr = (fstr + ", to ") + wstr;
    fstr = (fstr + "] ") + line;
    for target in (who) {
        if (!(target.connected()))
            .tell((target.name()) + " is not connected.");
        (| target.directed_tell(fstr, 'remote) |);
    }
    .tell((("[to " + wstr) + "] ") + line);
    if ((| (awaymsg = target.away()) |))
        .tell((((target.name()).capitalize()) + " is away: ") + awaymsg);
};

protected method .new_editor_session() {
    arg ref, opts, type;
    var p;
    
    switch (ref[1]) {
        case 'object:
            if (!(| (p = (ref[2]).all_edit_types()) |))
                return "The object is not editable.";
            if (type == "any")
                type = p[1];
            if (!(| (ref[2]).(tosym("edit_" + type))() |))
                return ((("Could not edit " + (ref[2])) + "'s ") + type) + ".";
        default:
            return ("You cannot edit " + (ref[1])) + "s.";
    }
    if (.active_editor())
        return [("Editor invoked with " + ((.active_editor()).session_name())) + ".", "Type 'help' to list available commands."];
    else
        return ["Remote editing invoked."];
};

protected method .set_setting_title() {
    arg definer, name, value, @args;
    
    .set_title(value);
};

public method .get_auto_look() {
    arg @args;
    
    // invert the logic, most people want it on (less clutter this way)
    return !auto_look;
};

protected method .set_auto_look() {
    arg name, definer, value, @args;
    
    // invert the logic, most people want it on (less clutter this way)
    if (value) {
        if (auto_look)
            clear_var('auto_look);
    } else {
        auto_look = 'no;
    }
};

public method .msg_cmd() {
    arg cmdstr, cmd, args;
    var who, branch, name, msg, what, definer, opts, clear;
    
    (> .perms(caller(), 'command) <);
    
    // it niggles the string enough to 'clean' up little mistakes
    [args, opts] = (> $parse_lib.opt(args, "c?lear") <);
    args = join(args).trim();
    clear = "c?lear" in (opts.slice(1));
    if ((what = regexp(args, "^([^:=]+): *(.*)$"))) {
        who = (> .match_env_nice((what[1]).trim()) <);
        args = (what[2]).trim();
    } else {
        who = this();
    }
    if ((what = regexp(args, "^([^=]+)=(.*)$"))) {
        name = (what[1]).trim();
        args = (what[2]).trim();
    } else {
        name = args;
        args = "";
    }
    if (!name)
        return ([("-- Messages on " + (who.namef('ref))) + ":"] + (.format_messages(who))) + ["---"];
    [name, @branch] = split(name, " *\. *", "b");
    if (!($code_lib.valid_message_id(name)))
        return ("Invalid Message name \"" + name) + "\"";
    msg = args.unquote();
    catch any {
        [definer, name, branch] = who.parse_msg(name, branch);
        if (clear)
            who = who.clear_msg(name, branch);
        else
            who = who.set_msg(name, branch, definer, args);
        msg = (who.get_msg(name, definer))[branch];
        if (branch == "general")
            return ["-- Message changed to:", ("  " + name) + " = "].affix(msg.uncompile());
        else
            return ["-- Message changed to:", ((("  " + name) + ".") + branch) + " = "].affix(msg.uncompile());
    } with {
        return (traceback()[1])[2];
    }
};

public method .set_cmd() {
    arg cmdstr, cmd, args;
    var who, branch, name, setting, what, def, opts, clear, showdef, syn;
    
    (> .perms(caller(), 'command) <);
    syn = ["Syntax: @set [TARGET:]SETTING=VALUE", "TARGET defaults to yourself, if unspecified."];
    if ((what = regexp(args, "^ *\+(clear|c) +(.*)"))) {
        clear = 1;
        args = what[2];
    }
    if ((what = regexp(args, "^ *\+(definers|definer|def|d) *= *\$?([a-z0-9_]+) *(.*)"))) {
        if (!(showdef = (| lookup(tosym(what[2])) |)))
            return "Invalid definer $" + (what[2]);
        args = what[3];
    }
    if ((what = regexp(args, "^ *\+(def|definer|definers|d) *(.*)"))) {
        showdef = 1;
        args = what[2];
    }
    if ((what = regexp(args, "^([^:=]+): *(.*)$"))) {
        who = (> .match_env_nice((what[1]).trim()) <);
        args = (what[2]).trim();
    } else {
        who = this();
    }
    if ((what = regexp(args, "^([\@a-z0-9-]+) *= *(.*)$"))) {
        name = (what[1]).trim();
        args = (what[2]).trim();
    } else {
        name = args;
        args = "";
    }
    if (!name)
        return ([("-- Settings on " + (who.namef('ref))) + ":"] + (.format_settings(who, showdef))) + ["---"];
    if (!($code_lib.valid_setting_id(name)))
        return syn + [("** Invalid Setting name \"" + name) + "\""];
    setting = args.unquote();
    catch any {
        def = who.setting_definer(name);
        if (clear)
            who = who.clear_setting(name, def);
        else
            who = who.set_setting(name, def, setting);
        setting = who.format_setting(name, def, who.get_setting(name, def));
        return ["-- Setting changed to:", (("  " + name) + " = ") + setting, "--"];
    } with {
        if (error() == ~perm)
            return "You are not allowed to change settings on " + (who.namef('ref));
        return (traceback()[1])[2];
    }
};

public method .format_settings() {
    arg target, @showdef;
    var sets, out, m, s, value, defs;
    
    if (showdef)
        showdef = showdef[1];
    catch ~perm {
        if (type(showdef) == 'objnum)
            sets = hash s in (showdef.defined_settings()) to ([s[1], showdef]);
        else
            sets = target.all_defined_settings();
    } with {
        return ["** Permission Denied"];
    }
    out = sets;
    for s in (sets) {
        catch any
            value = target.format_setting(@s, target.get_setting(@s));
        with
            value = (((traceback()[1])[1]) + ": ") + ((traceback()[1])[2]);
        out = dict_add(out, s[1], value);
    }
    if ((type(showdef) != 'objnum) && showdef) {
        defs = #[];
        for s in (sets)
            defs = defs.setadd_elem(tostr(s[2]), s[1]);
        sets = out;
        out = [];
        for m in (defs) {
            out += [(m[1]) + ":"];
            out += map s in ((m[2]).sort()) to ([(("  " + s) + " = ") + (sets[s])]);
        }
        return out;
    } else if (type(showdef) == 'objnum) {
        return [showdef + ":"] + map s in ((out.keys()).sort()) to ([(("  " + s) + " = ") + (out[s])]);
    } else {
        return map s in ((out.keys()).sort()) to ([(("  " + s) + " = ") + (out[s])]);
    }
};

public method ._tmp_wwmmmww() {
    $world.hook_into_event('realm_announce);
};

protected method .date_cmd() {
    arg @args;
    var fmt, l, d, out, rtime;
    
    fmt = "%I:%M %p";
    l = "%25r ";
    rtime = $time.realm_time((.location()).realm(), 'with_season);
    out = [strfmt(l, "Server Time:") + ($time.format(fmt + " %A, %B %d %Y %Z"))];
    out += [strfmt(l, ((rtime[2]).name()) + " Time:") + (rtime[1])];
    return out;
};

public method .registered_names() {
    return registered || [];
};

public method .parse_content_type() {
    arg value, @args;
    var type, types, valid, f;
    
    value = strsed(value, "text/", "");
    if (!match_regexp(value, "[^a-z]")) {
        if ((| lookup(tosym(value + "_format")) |))
            return tosym(value);
    }
    valid = $formatter.descendants();
    valid = map f in (valid) to ("text/" + (substr(tostr(f), 2).sed("_format$", ""))).sort();
    throw(~check, "Content-type must be one of: " + (valid.to_english("", " or ")));
};

public method .parse_ext_parsers() {
    arg value, @args;
    var objs, o, r;
    
    objs = [];
    for o in (value.explode_english_list()) {
        o = o.trim();
        if (!(r = (| $object_lib.to_dbref(o) |))) {
            if (!(r = $user_parsers.match_children(o)))
                throw(~type, ("\"" + o) + "\" is not a child of $user_parsers.");
        }
        objs = setadd(objs, r);
    }
    
    // sorry buddy, no choice--these come from .get_base_parsers()
    for o in ((.get_base_parsers()) + [$command_aliases_parser])
        objs = setremove(objs, o);
    return objs;
};

public method .format_ext_parsers() {
    arg value;
    
    return value.to_english();
};

public method .parse_exit_style() {
    arg value, @args;
    var styles, s;
    
    // verify it is correct
    styles = ["none", "brief", "template?s", "long", "verbose"];
    for s in (styles) {
        if (match_template(value, s))
            return tosym(s.strip("?"));
    }
    throw(~wrong, "Style must be one of: " + (styles.to_english("", " or ")));
};

public method .clear_content_type() {
    arg name;
    
    content_type = 'plain;
};

public method .format_content_type() {
    arg value;
    
    return "text/" + value;
};

public method .get_content_type() {
    arg name, definer;
    
    return content_type || 'plain;
};

protected method .set_closable() {
    arg name, definer, value;
    
    closable = value;
};

public method .set_content_type_pueblo(): forked {
    .tell("This world is Pueblo 1.10 enhanced.");
    .tell("Pueblo is annoyingly proprietary in that it requires this message to be printed, the administration appologizes for the disgustingness of this behaviour.");
    content_type = 'html;
};

public method .pueblo_cmd() {
    arg cmstr, cmd, args;
    
    (.connections()).mmap('write, "</xch_mudtext><img xch_mode=purehtml>");
    (.connections()).mmap('write, "<h1>Rich-HTML text enabled</h1>");
};

public method ._edit_mail_callback() {
    arg text, cdata;
    var list, subj, err, mail, nosend, sent;
    
    // not necessarily safe perm checks
    (> .perms(caller(), $editor_session, $editor_reference) <);
    list = cdata[2];
    subj = cdata[3];
    if (!subj)
        subj = (> .prompt("Subject: ") <);
    mail = $mail_message.new_mail();
    mail.set_subject(subj);
    mail.set_text(text);
    catch any
        nosend = mail.send(@list);
    with
        return ['failed, [(traceback()[1])[2]]];
    if (nosend) {
        sent = list.set_difference(nosend);
        if (sent)
            err = ["Mail sent to " + (sent.map_to_english('mail_name))];
        else
            err = [];
        nosend = list.set_difference(sent);
        err += ["Mail NOT sent to " + (nosend.map_to_english('mail_name))];
        return ['failure, err];
    }
    return ['success, ["Mail sent to " + (list.map_to_english('mail_name))]];
};

protected method .report_cmd() {
    arg cmdstr, cmd, @args;
    var groups, group, id, s, lasttb, tb, text, request;
    
    .tell("");
    .tell(("** Entering the " + ($motd.server_name())) + " action request system **");
    .tell("** Use \"@abort\" at any time to abort this system **");
    groups = setremove($argroup.children(), $dismissed_problems);
    if (listlen(groups) > 1) {
        while (1) {
            .tell(["**", "** Available Problem Groups:"]);
            for group in [1 .. listlen(groups)]
                .tell(strfmt("**      %2r: ", group) + ((groups[group]).name()));
            s = (> .prompt("** Select most applicable Problem Group [1] ") <);
            if (!s)
                group = groups[1];
            else if (s.is_numeric())
                group = (| groups[toint(s)] |);
            else
                group = (| groups.match_name(s) |);
            if (!group)
                .tell(["**", ("** Sorry, '" + s) + "' is not a valid group."]);
            else
                break;
        }
    } else {
        group = groups[1];
    }
    .tell([("** " + (group.name())) + " Problem Report Group", ""]);
    if ((tb = .last_traceback()) && (((tb[1]) + 300) > time())) {
        .tell("** You received the following traceback in the last 5 minutes:");
        .tell("**");
        .tell((tb[3]).prefix("**   "));
        .tell("**");
        s = (> .prompt("** Is the issue you are reporting in regard to this traceback? [yes] ") <);
        if ((s.is_boolean()) != 0)
            tb = tb[3];
        else
            tb = [];
        .tell("**");
    } else {
        tb = [];
    }
    .tell("** Explain the problem as completely as possible **");
    text = .read("** Enter \".\" to finish or \"@abort\" to abort **");
    if (type(text) != 'list)
        return;
    s = (> .prompt(["**", "** Summarize the problem: "]) <);
    request = group.submit_request(s, text, tb);
    ._broadcast('Admin, ((((group.name()) + " Problem #") + (request.id())) + " submitted by ") + (.namef('ref)));
    return "** Problem Report Submitted, Thank you for your help";
};

root method .core_user() {
    if (this() == definer())
        context = 0;
    else
        (| clear_var('context) |);
};

public method .set_reap_status() {
    arg status;
    
    (> .perms(sender(), 'system) <);
    if (status)
        reap_status = status;
    else
        (| clear_var('reap_status) |);
};

public method .reap_status() {
    return reap_status;
};

public method .set_reap_notified() {
    arg date;
    
    (> .perms(sender(), 'system) <);
    if (date)
        reap_notified = date;
    else
        (| clear_var('reap_notified) |);
};

public method ._reap__notified() {
    return reap_notified;
};

public method .tutorial_cmd() {
    arg cmdstr, cmd, args;
    var tuts, t, start;
    
    args = args.trim();
    tuts = filter t in ($tutorial.children()) where ((t.minclass()) && (.is(t.minclass())));
    if (!args)
        t = $introductory_tutorial;
    else if (args == "?")
        return ["All tutorials available to your class:", "    " + (tuts.map_to_english('name)), ("Use '" + cmd) + " TUTORIAL' for the specific tutorial you wish to enter."];
    else if ((t = find t in (tuts) where ((t.name()) == args)))
        t = tuts[t];
    else
        return [("Unknown or unavailable tutorial '" + args) + "', try one of:", "    " + (tuts.map_to_english('name))];
    if ((.location()).is($tutorial))
        return "You are already in a tutorial, you must exit it before you can enter another one.";
    start = t.get_setting("start-topic", $tutorial);
    if (!start)
        return "Uhoh! There is no starting topic for that tutorial!";
    (.location()).announce((((.name()) + " enters the ") + ((t.name()).capitalize())) + " Tutorial.", this());
    .move_to(start);
    if (!(.get_setting("auto-look", $user)))
        return ["You enter the tutorial.", "", "The Tutorials use place descriptions to explain topics.  Your auto-look is turned off, you should turn it on in order to see each topic automatically."];
};

public method .null_cmd() {
    arg @args;
    
};

public method .last_matched_object() {
    var match;
    
    if ((match = (| context['last] |))) {
        if (valid(match))
            return match;
    }
    return 0;
};

public method .away_cmd() {
    arg cmdstr, cmd, msg;
    
    (> .perms('command, caller()) <);
    if (msg) {
        away = msg;
        away_time = time();
        return "You are now marked as being away.";
    } else if (away) {
        return "You are marked as being away.  Message: " + away;
    } else {
        return "You are not marked as being away.";
    }
};

public method .back_cmd() {
    arg cmdstr, cmd;
    
    (> .perms('command, caller()) <);
    if (away) {
        clear_var('away);
        return "You are no longer marked as being away.";
    } else {
        return "You are not marked as being away.";
    }
};

protected method .away() {
    return away;
};

public method .away_time() {
    return away_time;
};

protected method .conn_options() {
    arg conn;
    
    return (| connection_options[conn] |) || [];
};

protected method .set_conn_options() {
    arg conn, options;
    
    if (!(conn in connections))
        throw(~invarg, (conn + " is not a connection for ") + this);
    connection_options = (| connection_options.add(conn, options) |) || #[[conn, options]];
};

protected method .set_away() {
    arg name, definer, value, @args;
    
    if (value) {
        away = value;
        away_time = time();
    } else {
        clear_var('away);
    }
};

protected method .clear_away() {
    arg name;
    
    clear_var('away);
};

protected method .get_away() {
    arg name, def;
    
    return away;
};

public method .prompt2() {
    arg prompt, @abort;
    
    // second argument represents how to handle '@abort' as input,
    // if it is 'no, then '@abort' is treated as any other string.   
    // If it is 'yes, then ~stop will be thrown if @abort is 
    // encountered, with the message "** Aborted **".  If it is a
    // string, then the behaviour is the same as with 'yes, but 
    // that string is used instead of the default message.
    .non_terminated_tell(prompt);
    [(abort ?= 'yes)] = abort;
    return (> .read_line2(0, abort) <);
};

public method .read_line2() {
    arg @args;
    var line, abort, head, con;
    
    if (!(.connections()))
        return 'not_connected;
    con = (| .task_connection() |) || ((.connections())[1]);
    if (con.is_reading_block())
        throw(~engaged, "This connection is already reading input.");
    [(head ?= ""), (abort ?= 'yes)] = args;
    if (head)
        .tell(head);
    line = con.start_reading_block('one);
    if ((line == 'aborted) || ((abort != 'no) && ((| (line[1]).trim() |) == "@abort"))) {
        if (type(abort) == 'string)
            throw(~stop, abort);
        else
            throw(~stop, "** Aborted **");
    }
    if ((| type(line[1]) |) != 'string)
        throw(~prompt, "Unexpected result from .prompt(): " + line);
    return line[1];
};

protected method .follow_path() {
    arg @path;
    var e, oal;
    
    if (!path)
        throw(~badpath, "Walk nowhere?");
    oal = .get_auto_look();
    .set_auto_look($user, "", 0);
    catch any {
        for e in (path) {
            e.invoke();
            pause();
        }
        .set_auto_look(0, 0, oal);
    } with {
        .set_auto_look(0, 0, oal);
        rethrow(error());
    }
};

public method .format_messages() {
    arg target, @what;
    var messages, out, b, branches, m;
    
    catch ~methodnf
        messages = target.all_msgs();
    with
        return [("[" + (target.name())) + " does not have settable messages]"];
    out = [];
    for m in ((messages.keys()).sort()) {
        branches = messages[m];
        if (branches.contains("general")) {
            out += [("  " + m) + " = "].affix((branches["general"]).uncompile());
            branches = dict_del(branches, "general");
        }
        for b in ((branches.keys()).sort())
            out += [((("  " + m) + ".") + b) + " = "].affix((branches[b]).uncompile());
    }
    return out;
};

public method .player_breakdown_cmd() {
    arg cmdstr, cmd;
    var admins, programmers, builders, users, total, pstrip, bstrip, strip, names, players;
    
    // stuff to strip
    // users
    strip = [$guest, $user, $reaper, $no_one, $player, $builder, $storyteller, $programmer, $admin];
    
    // programmers
    pstrip = [$admin];
    
    // builders
    bstrip = [$programmer, $admin];
    
    // get number of admins
    admins = listlen($sys.admins());
    names = $sys.admins();
    
    // get number of programmers, minus those that are also admins
    programmers = $programmer.descendants();
    programmers = $list.setremove_all(programmers, pstrip);
    programmers = $list.setremove_all(programmers, $sys.admins());
    names += programmers;
    programmers = listlen(programmers);
    
    // get number of builders
    builders = $builder.descendants();
    builders = $list.setremove_all(builders, $sys.admins());
    builders = $list.setremove_all(builders, $programmer.descendants());
    builders = $list.setremove_all(builders, strip);
    names += builders;
    builders = listlen(builders);
    
    // get number of users
    users = $user.descendants();
    users = $list.setremove_all(users, strip);
    names += users;
    users = listlen(users);
    
    // get total number of players, users counts everybody, even admins
    total = users;
    
    // correct for backwards places like tCD where everybody is a programmer
    if ((users - ((admins + programmers) + builders)) < 0)
        users = 0;
    else
        users = users - ((admins + programmers) + builders);
    
    // break it down
    sender().tell("--- Player Breakdown ---");
    sender().tell(("There are currently " + total) + " total users.");
    sender().tell(("    " + admins) + " admin(s) *");
    sender().tell(("    " + programmers) + " programmer(s)");
    sender().tell(("    " + builders) + " builder(s)");
    sender().tell(("    " + users) + " user(s)");
    sender().tell("---");
    sender().tell("");
    players = (($sys.admins()).mmap('name)).prefix("*");
    players += ($list.setremove_all($list.setremove_all($user_db.user_dbrefs(), strip), $sys.admins())).mmap('name);
    sender().tell($list.columnize(players, 3));
};

public method .traceback_cmd() {
    arg @args;
    var tb, last;
    
    (> .perms(caller(), 'command) <);
    tb = .last_traceback();
    last = time() - (tb[1]);
    .tell(("=> Last traceback (recieved " + ($time.to_english(last))) + " ago):");
    .tell($parse_lib.traceback(tb[2], -1, ""));
};

protected method .audit_cmd__quota() {
    arg obj, summary;
    var title, list, out, sz, o, tot, t, tr, c, quota;
    
    if ((obj != this()) && (!(.is($admin))))
        (> .tell_error("Only administrators can list quota on others") <);
    list = obj.managed();
    title = ("Managed by " + (obj.namef('ref))) + ":";
    c = $cml_lib;
    t = (out = []);
    if (!summary) {
        [sz, out] = .audit_cmd__list(title, list, 0, 'display);
        out = [$ctext_frob.new_with([c.fmt_table("60%,13%,27%", out)])];
    } else {
        for o in (list) {
            if (valid(o)) {
                tot++;
                sz += o.size();
            }
        }
        tr = [c.fmt_td("Objects " + title), c.fmt_td(tot + " total.")];
        t += [c.fmt_tr(@tr)];
    }
    t += [c.fmt_tr(c.fmt_td("Total usage:"), c.fmt_td(sz.to_english()))];
    quota = obj.get_quota();
    t += [c.fmt_tr(c.fmt_td("Total quota:"), c.fmt_td((quota.to_english()) + " bytes"))];
    t += [c.fmt_tr(c.fmt_td("Remaining:"), c.fmt_td(((quota - sz).to_english()) + " bytes"))];
    out += [$ctext_frob.new_with([c.fmt_table("70%,30%", t)])];
    if ((obj.quota_valid()) < 0) {
        if (obj == this())
            out += ["*** You are over quota! ***"];
        else
            out += [("*** " + (obj.name())) + " is over quota! ***"];
    }
    if (obj.quota_exempt()) {
        if (obj == this())
            out += ["*** You are exempt from quota! ***"];
        else
            out += [("*** " + (obj.name())) + " is exempt from quota! ***"];
    }
    return out;
};

protected method .audit_cmd__manages() {
    arg obj, @opts;
    var list, title, out, tot, sz, expand, context;
    
    if ((obj != this()) && (!(.is($admin))))
        (> .tell_error("Only administrators can list other managers") <);
    list = obj.managed();
    title = ("Managed by " + (obj.namef('ref))) + ":";
    [expand, context] = [@opts, 0, 'display];
    return (.audit_cmd__list(title, list, expand, context))[2];
};

protected method .audit_cmd__writes() {
    arg obj, @opts;
    var list, title, out, tot, sz, expand, context;
    
    if ((obj != this()) && (!(.is($admin))))
        (> .tell_error("Only administrators can list other writers") <);
    list = obj.writes();
    title = ("Writable for " + (obj.namef('ref))) + ":";
    [expand, context] = [@opts, 0, 'display];
    return (.audit_cmd__list(title, list, expand, context))[2];
};

protected method .audit_cmd__trusted() {
    arg obj, @opts;
    var list, title, out, tot, sz, expand, context;
    
    if ((obj != this()) && (!(.is($admin))))
        (> .tell_error("Only administrators can list other trustees") <);
    list = obj.trusted_by();
    title = ("Objects which trust " + (obj.namef('ref))) + ":";
    [expand, context] = [@opts, 0, 'display];
    return (.audit_cmd__list(title, list, expand, context))[2];
};

private method .audit_cmd__list() {
    arg name, list, expand, context;
    var out, c, tr, t, td, o, tsz, s, tot, span, l;
    
    c = $cml_lib;
    
    // table header, expand used with $page_set
    if (expand) {
        name = "[-] " + name;
        tr = [c.fmt_td(c.fmt_href("set_objlist?e=" + expand, c.fmt_b(name)))];
    } else {
        tr = [c.fmt_td(c.fmt_b(name))];
    }
    tr += [c.fmt_td(strfmt("%10r", "Size"))];
    t = [c.fmt_tr(@(tr + [c.fmt_td(" Location")]))];
    
    // table rows
    span = ["colspan", "3"];
    for o in (list) {
        pause();
        if (!valid(o)) {
            tr = [c.fmt_td(("  ** invalid object (" + toliteral(o)) + " **", span)];
        } else {
            tot++;
            tr = [c.fmt_td(@[c.fmt_obj(context, o, "  " + (o.namef('xref)))])];
            s = o.size();
            tr += [c.fmt_td(strfmt("%10r", s.to_english()))];
            tsz += s;
            if (o.is($located)) {
                l = o.location();
                s = [" [", c.fmt_obj('look, l, l.name()), "]"];
            } else {
                s = "";
            }
            tr += [c.fmt_td(s)];
        }
        t += [c.fmt_tr(@tr)];
    }
    return [tsz, t + [c.fmt_tr(c.fmt_td(tot + " total.", ["colspan", "3"]))]];
};

protected method .chown_cmd() {
    arg cmdstr, cmd, args;
    var opts, obj, syn, o, t, list, s;
    
    (> .perms(caller(), 'command) <);
    [args, opts] = (> $parse_lib.opt(args, "m?anager", "w?riters", "t?rustees") <);
    syn = cmd + " <object> +-<m?anager|writers|trustees>=who,...";
    if (!opts) {
        if (listlen(args) > 1) {
            opts = [["m?anager", "m", 1, args.last()]];
            args = sublist(args, 1, listlen(args) - 1);
        } else {
            return [syn, "Nothing to do?"];
        }
    }
    
    // maybe someday make this handle a list of objs
    obj = (> .match_env_nice(args.join(), syn) <);
    for o in (opts) {
        switch (o[1]) {
            case "m?anager":
                t = (> .match_env_nice(o[4]) <);
                if ((!(t.is($user))) && (!(.is($admin))))
                    return "Sorry you can only set users as managers.";
                catch any
                    (> obj.change_manager(t) <);
                with
                    (> .tell_error((traceback()[1])[2]) <);
                return ((("Manager on " + (obj.namef('ref))) + " changed to ") + (t.namef('ref))) + ".";
            case "w?riters":
                if (!(o[4]))
                    (> .tell_error("No writers to change", syn) <);
                list = map t in ((o[4]).explode_english_list()) to ((> .match_env_nice(t) <));
                if (o[3])
                    s = "Added ";
                else
                    s = "Removed ";
                for t in (list) {
                    catch any {
                        if (o[3]) {
                            (> obj.add_writer(t) <);
                            .tell((s + (t.namef('ref))) + " from writers list...");
                        } else {
                            (> obj.del_writer(t) <);
                            .tell((s + (t.namef('ref))) + " from writers list...");
                        }
                    } with {
                        (> .tell_error((traceback()[1])[2]) <);
                    }
                }
                .tell(("New writers list for " + (obj.namef('ref))) + ":");
                .tell(((((obj.writers('literal)).compress()).mmap('namef, 'ref)).to_english("noone")) + ".");
            case "t?rustees":
                if (!(o[4]))
                    (> .tell_error("No trustees to change", syn) <);
                list = map t in ((o[4]).explode_english_list()) to ((> .match_env_nice(t) <));
                if (o[3])
                    s = "Added ";
                else
                    s = "Removed ";
                for t in (list) {
                    catch any {
                        if (o[3]) {
                            (> obj.add_trusted(t) <);
                            .tell((s + (t.namef('ref))) + " from trusted list...");
                        } else {
                            (> obj.del_trusted(t) <);
                            .tell((s + (t.namef('ref))) + " from trusted list...");
                        }
                    } with {
                        (> .tell_error((traceback()[1])[2]) <);
                    }
                }
                .tell(("New trustee list for " + (obj.namef('ref))) + ":");
                .tell(((((obj.trusted('literal)).compress()).mmap('namef, 'ref)).to_english("noone")) + ".");
            default:
                (> .tell_error(syntax, "Invalid Argument " + ((o[1]) || (((o[3]) ? "+" : "-") + (o[2])))) <);
        }
    }
};


new object $guest: $user;

var $root inited = 1;
var $root manager = $guest;
var $root quota = 75000;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core, 'general_cache];
var $root managed = [$guest];
var $location contents = [];
var $located location = $body_cave;
var $located obvious = 1;
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user modes = #[];
var $user formatter = $plain_format;
var $user parsers = [$command_parser];
var $user task_connections = #[];
var $command_aliases command_aliases = [];
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list senders = 1;
var $mail_list readers = 1;
var $mail_list notify = [$guest];
var $mail_list last_letter = 0;
var $mail_list mail = [];
var $mail_ui subscribed = #[[$guest, [791485891, 0]]];
var $mail_ui current = #[['location, 0], ['list, $guest]];
var $described prose = [];
var $has_name name = ['prop, "Generic Guest Object", "Generic Guest Object"];
var $has_commands local = #[["@request", [["@request", "*", "@request <any>", 'request_cmd, #[[1, ['any, []]]]]]]];
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $thing gender = $gender_neuter;
var $root settings = #[["home", $body_cave]];
var $command_cache modules = [];

root method .init_guest() {
    .set_title(0, 0, "a guest");
};

protected method .logout() {
    arg connection;
    
    (| pass(connection) |);
    (> .destroy() <);
};

protected method .title_cmd() {
    arg cmdstr, com, str;
    
    (> .perms(caller(), 'command) <);
    .tell("Guests are not allowed to change their titles.");
};

protected method .login_notify(): forked {
    arg connection, last;
    var msg;
    
    (| pass(connection, last) |);
    .tell(["**", "** Welcome to " + ($motd.server_name()), "**"]);
    .tell(["** If you are new to ColdCore, you may want to enter the Introductory", "** Tutorial by typing:", "**", "**     @tutorial", "**"]);
    msg = ((("GUEST: " + (.name())) + " [") + (connection.address())) + "] ";
    $channel_ui._broadcast('Admin, msg + (.user_info("email")));
};

public method .request_cmd() {
    arg @args;
    var msg, ans, utypes, line, mail;
    
    (> .perms(caller(), 'command) <);
    
    // hardcoded questions for now--should eventually drop this in a
    // configurable 'schema' dict somewhere --Brandon
    .tell(["", "*" * (.linelen())]);
    .tell([">> This is the new-user request system.  You will be asked a few questions", ">> at this time.  Please answer to the best of your ability."]);
    .tell(["*" * (.linelen()), ""]);
    msg = [("Email:".pad(22)) + (.user_info("email"))];
    line = "Read Tutorial:".pad(22);
    ans = (> .prompt(">> Have you read the Introductory Tutorial? [no] ") <);
    if ((!ans) || ((ans.is_boolean()) < 1)) {
        line += "no";
        .tell(["", ">> We suggest you take some time afterwards and enter the Introductory", ">> Tutorial.  To do so, just type: @tutorial", ""]);
    } else {
        .tell("");
        line += "yes";
    }
    msg += [line];
    line = "Heard about us from: ".pad(22);
    ans = "";
    while (ans == "") {
        ans = (> .prompt((">> Where did you hear about " + ($motd.server_name())) + "? ") <);
        ans = strsed(ans, "^ +", "");
    }
    msg += (line + ans).wrap_lines(.linelen(), " " * 22);
    .tell("");
    line = "Interest is with: ".pad(22);
    ans = "";
    while (ans == "") {
        ans = (> .prompt(">> What is your reason for requesting a user? ") <);
        ans = strsed(ans, "^ +", "");
    }
    msg += (line + ans).wrap_lines(.linelen(), " " * 22);
    line = "User type: ".pad(22);
    ans = "";
    .tell("");
    utypes = ["User", "Builder", "Programmer"];
    while (!(ans in utypes)) {
        ans = (> .prompt(([">> Available user types:"] + (utypes.prefix(">>    "))) + [">> Which of the above user types are you most interested in:"]) <);
        ans = ans.strip();
    }
    msg += [line + ans];
    .tell("");
    if (ans == "Programmer") {
        ans = (> .prompt([">> By asking for Programmer permissions, do you agree never to exploit", ">> any problem or security hole which may be found by yourself or others,", ">> and to reveal any problems to the appropriate administration as soon", ">> as possible? [yes] "]) <);
        line = "Will not exploit:".pad(22);
        ans = ans.is_boolean();
        if (ans == 1)
            msg += [line + "yes"];
        else if (ans == 0)
            msg += [line + "no"];
        else
            return "Invalid response.  Try the command again, and enter \"yes\" or \"no\" in response to the question.";
    }
    mail = $mail_message.new_mail();
    mail.set_subject("New User Request for: " + (.name()));
    mail.set_text(msg);
    catch any
        mail.send($mail_admin);
    with
        return (traceback()[1])[2];
    return ["New User Request Sent as:"] + msg;
};


new object $reaper: $user;

var $root manager = $reaper;
var $root quota = 75000;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['core];
var $root managed = [$reaper];
var $command_aliases command_aliases = [];
var $has_name name = ['prop, "Reaper", "Reaper"];
var $described prose = <$ctext_frob, [["A dark billowing cape covers his luminous and forboding form."], #[]]>;
var $location contents = [];
var $located location = $body_cave;
var $located obvious = 1;
var $body body_parts = #[];
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user creation_time = 780375877;
var $user parsers = [$command_parser];
var $user action = "";
var $user formatter = $plain_format;
var $user task_connections = #[];
var $mail_list mail = [];
var $mail_list senders = 1;
var $mail_list notify = [$reaper];
var $mail_ui subscribed = #[[$reaper, [791485891, 0]]];
var $mail_ui current = #[['location, 0], ['list, $reaper]];
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $command_cache shortcuts = 0;
var $command_cache modules = [];
var $thing gender = $gender_male;
var $root settings = #[["home", $body_cave]];
var $command_cache commands = 0;


new object $no_one: $user;

var $user task_connections = #[];
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user creation_time = 759878010;
var $user action = "";
var $user modes = #[];
var $user formatter = $plain_format;
var $user parsers = [$command_parser];
var $root inited = 1;
var $root manager = $no_one;
var $root quota = 75000;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root managed = [$no_one];
var $command_aliases command_aliases = [];
var $location contents = [];
var $located location = $body_cave;
var $located obvious = 1;
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list senders = 1;
var $mail_list readers = [$no_one];
var $mail_list notify = [$no_one];
var $mail_list last_letter = 0;
var $mail_list mail = [];
var $mail_ui subscribed = #[[$no_one, [791485891, 0]]];
var $mail_ui current = #[['location, 0], ['list, $no_one]];
var $described prose = [];
var $has_name name = ['prop, "No One", "No One"];
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $command_cache modules = [];
var $thing gender = $gender_neuter;
var $root settings = #[["home", $body_cave], ["exit-style", 'brief]];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;
var $root trusted = [$smtp_interface, $page_ar];
var $root quota_exempt = 1;

frob method .mail_name() {
    arg frob;
    
    if (valid(frob[1]))
        return (frob[1]).mail_name();
    return frob[1];
};

public method .mail_as() {
    arg from, meta, subj, body, @recips;
    var mail, l;
    
    if (!(.trusts(caller())))
        (> .perms(sender()) <);
    mail = $mail_message.new_mail();
    mail.set_subject(subj);
    mail.set_text(body);
    if (from)
        mail.set_from((<this(), [from]>));
    if (meta)
        mail.set_meta(meta);
    if (caller() == $smtp_interface)
        mail.is_frominet();
    catch any {
        mail.send(@recips);
    } with {
        // dont call .log_traceback because it calls this, recursion bad
        $sys.log((this() + " traceback: ") + ((traceback()[1])[2]));
        $sys.log((this() + " traceback: ") + traceback());
    }
};

frob method .name() {
    arg frob, @args;
    
    if (valid(frob[1]))
        return (frob[1]).name();
    return frob[1];
};

frob method .namef() {
    arg frob, @args;
    
    if (valid(frob[1]))
        return (frob[1]).namef(@args);
    return frob[1];
};


new object $player: $user;

var $root manager = $player;
var $root created_on = 809926794;
var $root inited = 1;
var $root quota = 75000;
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user parsers = [$command_parser];
var $user action = "";
var $user formatter = $plain_format;
var $user task_connections = #[];
var $located location = $body_cave;
var $located obvious = 1;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[["@sheet|@score", [["@sheet|@score", "*", "@sheet|@score <any>", 'sheet_cmd, #[[1, ['any, []]]]]]], ["@new-char?acter", [["@new-char?acter", "*", "@new-char?acter <any>", 'new_character_cmd, #[[1, ['any, []]]]]]], ["@char?acters", [["@char?acters", "*", "@char?acters <any>", 'characters_cmd, #[[1, ['any, []]]]]]], ["@del-char?acter", [["@del-char?acter", "*", "@del-char?acter <any>", 'del_character_cmd, #[[1, ['any, []]]]]]]];
var $player character = 0;
var $player characters = 0;
var $has_name name = ['proper, "player", "player"];
var $location contents = [];
var $described prose = [];
var $mail_ui current = #[['location, 0], ['list, $player]];
var $mail_ui subscribed = #[[$player, [813278562, 0]], [$mail_list_news, [813278562, 0]]];
var $mail_list mail = [];
var $mail_list senders = 1;
var $mail_list readers = [$player];
var $mail_list notify = [$player];
var $command_aliases command_aliases = [];
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $root flags = ['core, 'methods, 'code, 'variables, 'general_cache];
var $root managed = [$player];
var $command_cache modules = [];
var $thing gender = $gender_neuter;
var $root settings = #[["home", $body_cave]];
var $player chargen_origin = 0;

protected method .lower_attribute() {
    arg attribute, difference;
    var new;
    
    new = (get_var(attribute)[1]) - difference;
    set_var(attribute, get_var(attribute).replace(1, new));
};

public method .attribute(): nooverride, synchronized {
    arg attribute;
    
    if (caller() != definer())
        (> .perms(sender(), $storyteller) <);
    return get_var(attribute);
};

public method .new_character_cmd() {
    arg @args;
    
    (> .perms(caller(), 'command) <);
    if (character)
        return ("You already have a character active (" + character) + ")";
    catch any
        character = $character.new();
    with
        return ["Unable to enter character creation:", (traceback()[1])[2]];
    characters ?= [];
    (.location()).announce((.name()) + " fades away to generate a new character.", this());
    chargen_origin = .location();
    .move_to($nowhere);
    .add_parser($chargen_parser);
    .tell("** Raw character generation subsystem, will get better later");
    .tell("** Based off En Requiem: http://web.roguetrader.com/EnRequiem/");
    .tell("** type 'help' for help");
};

protected method .raise_attribute() {
    arg attribute, difference;
    var new;
    
    new = (get_var(attribute)[1]) + difference;
    if (new > (get_var(attribute)[2]))
        new = get_var(attribute)[2];
    set_var(attribute, get_var(attribute).replace(1, new));
};

public method .dead() {
    return dead;
};

protected method .sheet_cmd() {
    arg cmdstr, cmd, args;
    var t, out, g;
    
    (> .perms(caller(), 'command) <);
    if (args && (!(.is($storyteller))))
        return "Only storytellers can see other players stats.";
    if (!character)
        return "You do not have a character active.";
    return character.format_sheet();
};

public method .set_attribute() {
    arg attribute, value;
    
    (> .perms(sender()) <);
    set_var(attribute, [value, value]);
};

public method .format_score() {
    arg base, cur;
    
    return pad((base == cur) ? tostr(base) : ((cur + "/") + base), 8);
};

public method .help_charcmd() {
    arg @args;
    
    .tell("** Special commands: HELP, LOWER, RAISE, SHEET, DONE and ABORT");
    .tell("** As well as +X and -X as shortcuts for raise and lower");
    .tell("** All other normal commands are available");
};

public method .lower_charcmd() {
    arg @args;
    var attr, amt, syn, msg;
    
    syn = ["Syntax: lower <attribute> <amount>", "    OR: -<amount> <attribute>", "    OR: -<attribute>"];
    if (listlen(args) == 1) {
        if ((args[1]).is_numeric())
            return syn;
        attr = args[1];
        amt = 1;
    } else if (listlen(args) == 2) {
        [attr, amt] = args;
    } else {
        return syn;
    }
    amt = toint(amt);
    attr = (| attr.to_symbol() |);
    if (!(attr in ($character.attributes())))
        return "Invalid Attribute: " + attr;
    if (type((amt = character.ok_to_lower_initial(attr, amt))) == 'string)
        return amt;
    character.set_attribute(attr, amt);
    return (("Set " + uppercase(tostr(attr))) + " to ") + amt;
};

public method .raise_charcmd() {
    arg @args;
    var attr, amt, syn, msg;
    
    syn = ["Syntax: raise <attribute> <amount>", "    OR: +<amount> <attribute>", "    OR: +<attribute>"];
    if (listlen(args) == 1) {
        if ((args[1]).is_numeric())
            return syn;
        attr = args[1];
        amt = 1;
    } else if (listlen(args) == 2) {
        [attr, amt] = args;
    } else {
        return syn;
    }
    amt = toint(amt);
    attr = (| attr.to_symbol() |);
    if (!(attr in ($character.attributes())))
        return "Invalid Attribute: " + attr;
    if (type((amt = character.ok_to_raise_initial(attr, amt))) == 'string)
        return amt;
    character.set_attribute(attr, amt);
    return (("Set " + uppercase(tostr(attr))) + " to ") + amt;
};

public method .sheet_charcmd() {
    arg @args;
    var tot, group, line, x, out;
    
    tot = map x in ($character.attributes()) to ((character.attribute(x))[1]);
    tot = tot.sum();
    out = ["", ((("Attribute Points Remaining: " + (115 - tot)) + " (") + tot) + " of 115)"];
    tot = map x in ($character.physical_attributes()) to ((character.attribute(x))[1]);
    tot = tot.sum();
    out += [((("                  Physical: " + (56 - tot)) + " (") + tot) + ", cap 56)"];
    tot = map x in ($character.mental_attributes()) to ((character.attribute(x))[1]);
    tot = tot.sum();
    out += [((("                    Mental: " + (56 - tot)) + " (") + tot) + ", cap 56)"];
    tot = map x in ($character.meta_attributes()) to ((character.attribute(x))[1]);
    tot = tot.sum();
    out += [((("                 Meta-Phys: " + (30 - tot)) + " (") + tot) + ", cap 30)"];
    return (character.format_sheet()) + out;
};

public method .done_charcmd() {
    arg @args;
    
    .tell("** Done Generating, cleaning up...");
    characters += [character];
    clear_var('character);
    .del_parser($chargen_parser);
    if (chargen_origin)
        .move_to(chargen_origin);
    else
        .move_to($world.starting_place());
    (| clear_var('chargen_origin) |);
};

public method .abort_charcmd() {
    arg @args;
    
    .tell("** Aborting Character Generation, cleaning up...");
    catch any
        character.destroy();
    with
        .tell(["** Unable to destroy character sheet:", (traceback()[1])[1]]);
    clear_var('character);
    .del_parser($chargen_parser);
    if (chargen_origin)
        .move_to(chargen_origin);
    else
        .move_to($world.starting_place());
    (| clear_var('chargen_origin) |);
};

public method .characters_cmd() {
    arg @args;
    var out, c, x, line;
    
    (> .perms(caller(), 'command) <);
    out = [];
    for x in [1 .. listlen(characters || [])] {
        c = characters[x];
        line = (c == character) ? "*" : " ";
        out += [strfmt("%2r: %s ", x, line) + (c.namef('ref))];
    }
    if (!out)
        out = ["    <None>"];
    return (["Characters:"] + out) + ["---"];
};

public method .del_character_cmd() {
    arg cmdstr, cmd, str;
    var delchar, x, yesno, name;
    
    (> .perms(caller(), 'command) <);
    catch any {
        delchar = characters.match_object(str);
    } with {
        if ((x = str.is_numeric()) && (delchar = (| characters[x] |))) {
            // Good
        } else {
            return [("Syntax: " + cmd) + " <character>", ("    OR: " + cmd) + " <character index>"];
        }
    }
    name = delchar.namef('ref);
    yesno = (> (.prompt(("Delete " + name) + "? [no] ")).is_boolean() <);
    if (yesno <= 0)
        return "Ok, Aborting...";
    catch any
        delchar.destroy();
    with
        return [("** Unable to destroy character " + name) + ":", (traceback()[1])[1]];
    characters = setremove(characters, delchar);
    return ((("Deleted " + name) + ", ") + listlen(characters)) + " characters remaining.";
};

public method .characters() {
    return characters;
};

public method .character() {
    return character;
};


new object $builder: $player;

var $root inited = 1;
var $root manager = $builder;
var $root quota = 75000;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables, 'general_cache];
var $root managed = [$builder];
var $location contents = [];
var $located location = $body_cave;
var $located obvious = 1;
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user modes = #[];
var $user formatter = $plain_format;
var $user parsers = [$command_parser];
var $user task_connections = #[];
var $command_aliases command_aliases = [];
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list senders = 1;
var $mail_list readers = [];
var $mail_list notify = [$builder];
var $mail_list last_letter = 0;
var $mail_list mail = [];
var $mail_ui subscribed = #[[$builder, [791485891, 0]]];
var $mail_ui current = #[['location, 0], ['list, $builder]];
var $described prose = [];
var $has_name name = ['prop, "Generic Builder", "Generic Builder"];
var $has_commands local = #[["@realm?s", [["@realm?s", "", "@realm?s", 'realms_cmd, #[]]]], ["@child?ren|@kids", [["@child?ren|@kids", "*", "@child?ren|@kids <object>", 'children_cmd, #[[1, ['object, []]]]]]], ["@par?ents", [["@par?ents", "*", "@par?ents <object>", 'parents_cmd, #[[1, ['object, []]]]]]], ["@build", [["@build", "*", "@build <any:-conf?igure>", 'build_cmd, #[[1, ['any_opt, ["conf?igure"]]]]]]], ["@attach", [["@attach", "* to *", "@attach <any> to <descendant of $place>", 'attach_cmd, #[[1, ['any, []]], [3, ['descendant, [$place]]]]]]], ["@destroy", [["@destroy", "*", "@destroy <list object>", 'destroy_cmd, #[[1, ['list, ['object, []]]]]]]], ["@dig", [["@dig", "*", "@dig <any>", 'dig_cmd, #[[1, ['any, []]]]]]], ["@teleport|@go", [["@teleport|@go", "*", "@teleport|@go <any>", 'teleport_cmd, #[[1, ['any, []]]]]]], ["@def-msg|@def-message", [["@def-msg|@def-message", "*", "@def-msg|@def-message <any>", 'define_msg_cmd, #[[1, ['any, []]]]]]], ["@undef-msg|@undef-message", [["@undef-msg|@undef-message", "*", "@undef-msg|@undef-message <any>", 'undefine_msg_cmd, #[[1, ['any, []]]]]]], ["@mv|@move", [["@mv|@move", "*", "@mv|@move <objref:+c?omment>", 'move_cmd, #[[1, ['objref_opt, ["c?omment"]]]]]]], ["@action-request|@ar", [["@action-request|@ar", "*", "@action-request|@ar <any>", 'action_request_cmd, #[[1, ['any, []]]]]]], ["@join", [["@join", "*", "@join <any>", 'join_cmd, #[[1, ['any, []]]]]]], ["@chown", [["@chown", "*", "@chown <any>", 'chown_cmd, #[[1, ['any, []]]]]]]];
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $command_cache modules = [];
var $foundation defined_msgs = #[["teleport", #[['branches, ["source", "dest", "actor"]]]]];
var $foundation msgs = #[["teleport", #[["actor", <$ctext_frob, [["You teleport to ", <$generator, ["dest", [], [], 'gen_dest]>, "."], #[['this, $builder]]]>], ["source", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " teleports to ", <$generator, ["dest", [], [], 'gen_dest]>, "."], #[['this, $builder]]]>], ["dest", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " teleports here from ", <$generator, ["source", [], [], 'gen_source]>, "."], #[['this, $builder]]]>]]]];
var $thing gender = $gender_neuter;
var $root settings = #[["home", $body_cave]];
var $command_cache commands = 0;
var $command_cache shortcuts = 0;

protected method .children_cmd() {
    arg cmdstr, cmd, what;
    
    (> .perms(caller(), 'command) <);
    return [("Children of " + (what.namef('xref))) + ":"] + (._list_objects(what.children(), 'parents));
};

protected method .parents_cmd() {
    arg cmdstr, cmd, what;
    
    (> .perms(caller(), 'command) <);
    return [((("Parent" + ((((.parents()).length()) > 1) ? "s" : "")) + " of ") + (what.namef('ref))) + ":"] + (._list_objects(what.parents(), 'children));
};

protected method .destroy_cmd() {
    arg cmdstr, cmd, objs;
    var name, ans, obj, fail;
    
    (> .perms(caller(), 'command) <);
    cmd = cmd.trim();
    for obj in (filter obj in (objs) where (obj.is($user))) {
        .tell(("You shouldn't @destroy users (" + (obj.name())) + "), use @reap.");
        fail++;
    }
    if (fail) {
        .tell("Destroying a user directly may not cleanup everything properly.");
        .tell("Objects managed by the user will be given to $reaper.");
        ans = (> .prompt("Given this information, do you want to continue? [no] ") <);
        if (!(ans in ["y", "yes"]))
            return "Ok, aborting..";
    }
    for obj in (objs) {
        catch any {
            name = obj.namef('xref);
            (> obj.destroy() <);
            if (valid(obj))
                .tell(("Unable to destroy " + name) + " immediately.");
            else
                .tell(("Successfully destroyed " + name) + ".");
        } with {
            return (traceback()[1])[2];
        }
    }
};

protected method .build_get_location() {
    arg name;
    var dest, m, realm, parent, str;
    
    (> .perms(sender()) <);
    .build_hint(1);
    if (name) {
        if ((m = match_template(name, "to *")))
            name = m[2];
        name = (| $code_lib.parse_name(name) |);
    }
    while (!name) {
        catch any {
            name = (> .build_get_name("Destination: ") <);
            str = (name[1])[1];
            if ((m = regexp(str, "^ *\$([a-z0-9_]+) *(.*)$"))) {
                name = replace(name, 1, replace(name[1], 1, m[2]));
                catch ~namenf, ~symbol {
                    parent = (> lookup(tosym(m[1])) <);
                } with {
                    .tell((traceback()[1])[1]);
                    continue;
                }
                if (!(parent.is($place))) {
                    .tell(("Parent object " + (parent.namef('ref))) + " is not a place!");
                    continue;
                } else if ((!(parent.has_flag('fertile))) && (!(parent.is_writable_by(this())))) {
                    .tell(("Parent object " + (parent.namef('ref))) + " is not fertile!");
                    continue;
                }
            }
        } with {
            if (error() == ~skip) {
                .tell("You cannot skip this step!");
                continue;
            }
            rethrow(error());
        }
    }
    
    // first try to see if it already exists--only do this if they used
    // the direct $dbref too many conflicts otherwise.
    catch any {
        dest = (> $object_lib.to_dbref((name[1])[1]) <);
        (dest.is($place)) || throw(~place, (dest.namef('ref)) + " is not a place.");
        return [dest, 0];
    }
    
    // create it
    .build_hint(2);
    if (!parent)
        dest = (> ($place_lib.get_default('place)).spawn() <);
    else
        dest = (> parent.spawn() <);
    .build_set_name(dest, @name);
    .build_hint(4);
    catch any {
        realm = (> .build_query_realm(dest) <);
    } with {
        if (error() == ~skip)
            return dest;
        .build_cleanup([dest, 1]);
        rethrow(error());
    }
    
    // set the realm
    dest.set_setting_realm($place, "realm", realm);
    
    // add this room to realm's 'local' variable
    realm.add_local(dest);
    
    // okee, done
    return [dest, 1];
};

protected method .build_cmd() {
    arg cmdstr, cmd, args;
    var dest, source, path, set, str, i;
    
    (> .perms(caller(), 'command) <);
    str = (args[1]).join();
    source = .location();
    args = args[2];
    if (!(| source.will_attach('source) |))
        return "This room is not publicly extendable.";
    
    // Establish the objects
    catch any {
        dest = (> .build_get_location(str) <);
        if (!(| (dest[1]).will_attach('dest) |)) {
            .tell(((dest[1]).name()) + " will not allow you to attach to it!");
            .build_cleanup(dest);
            return "** Build Aborted **";
        }
        path = (> .build_get_path(source, dest[1]) <);
    } with {
        if (dest)
            .build_cleanup(dest);
        if (path)
            .build_cleanup([path, 1]);
        if (error() == ~abort)
            return "** Build Aborted **";
        return [(traceback()[1])[2], "** Build Aborted **"];
    }
    .tell(("Completed building to " + ((dest[1]).name())) + ".");
    if ((i = "conf?igure" in (args.slice(1)))) {
        if (!((args[i])[3]))
            return "Skipping post-configuration.";
    }
    .tell("post-configuration..");
    
    // Flesh them out      
    set = #[['named_name, 1]];
    if (dest[2])
        (> (dest[1]).configure(set) <);
    if (path)
        (> path.configure(set) <);
    return "Completed post-configuration.";
};

protected method .build_hint() {
    arg n;
    
    (> .perms(sender()) <);
    if ((| .get_setting("experienced", $user) |))
        return;
    .tell($place_lib.build_hint(n));
};

protected method .attach_cmd() {
    arg cmdstr, cmd, source, prep, dest;
    var path;
    
    (> .perms(caller(), 'command) <);
    if (!source) {
        source = .location();
    } else {
        catch any
            source = (> .match_environment(source) <);
        with
            return (traceback()[1])[2];
        if (!(source.is($place)))
            return (source.namef('ref)) + " is not a $place.";
    }
    catch ~abort, ~skip
        path = (> .build_get_path(source, dest) <);
    with
        return "Aborted.";
    catch any {
        path.attach(source, dest);
        (> path.configure(#[['named_name, 1]]) <);
    } with {
        .tell("Ack, unable to attach path because:");
        .tell("  " + ((traceback()[1])[2]));
        (| path.destroy() |);
        return;
    }
    return ("Successfully attached path " + (path.name())) + ".";
};

protected method .realms_cmd() {
    arg cmdstr, cmd;
    var x, realms;
    
    (> .perms(caller(), 'command) <);
    realms = ($place_lib.known_realms()).union($realm.descendants());
    .tell(["Realms:", ""] + ((realms.mmap('name)).prefix("    ")));
};

protected method .move_cmd() {
    arg cmdstr, cmd, args;
    var what, dest, loc, opts, src, fromto;
    
    (> .perms(caller(), 'command) <);
    [src, args, opts] = args;
    if (args && (type(args[1]) == 'string)) {
        if ((args[1]) == "to")
            args = delete(args, 1);
        if (!args)
            throw(~stop, "You must move to somewhere.");
        catch ~obj, ~namenf, ~ambig
            dest = $parse_lib.ref(join(args));
        with
            throw(~stop, (traceback()[1])[2]);
    } else {
        dest = args;
    }
    what = src[2];
    dest = dest[2];
    catch any {
        loc = what.location();
        fromto = ((" from " + ((| loc.name() |) || $nowhere)) + " to ") + (dest.name());
        (| what.tell(((("You are suddenly yanked" + fromto) + " by ") + (.name())) + ".") |);
        (> what.move_to(dest) <);
    
        // hook into messages eventually
        (| loc.announce((what.name()) + " suddenly disappears.") |);
        (| dest.announce((what.name()) + " suddenly appears.", what) |);
        return (("You move " + (what.name())) + fromto) + ".";
    } with {
        (| what.tell(("You feel as if " + (.name())) + " was incapable of moving you, you did not go anywhere.") |);
        return (traceback()[1])[2];
    }
};

protected method .build_cleanup() {
    arg @what;
    var obj;
    
    (> .perms(caller(), definer()) <);
    for obj in (what) {
        if (valid(obj[1]) && (obj[2])) {
            .tell(("Destroying " + ((obj[1]).name())) + "...");
            (| (obj[1]).destroy() |);
        }
    }
};

protected method .build_query_exit() {
    arg source, dest, @args;
    var exit, line, name, def, from, str, m, parent;
    
    from = "from " + (source.name());
    line = (("Exit " + from) + " to ") + (dest.name());
    if (args) {
        def = args[1];
        line += (" [" + def) + "] ";
    } else {
        line += ": ";
    }
    while (!name) {
        catch ~skip
            name = (> .build_get_name(line, def) <);
        with
            return 0;
        if (((name[1])[1]) == "@none")
            return 0;
    }
    return name;
};

protected method .build_set_name() {
    arg obj, name, templates, @args;
    var t, x;
    
    catch any {
        obj = obj.set_name(@name, @args);
    } with {
        .tell("Unable to set name; " + ((traceback()[1])[2]));
        .tell("Setting name as " + (obj.objname()));
        obj = obj.set_name(tostr(obj.objname()));
    }
    for t in (templates)
        obj = obj.add_name_template(t, @args);
    return obj;
};

protected method .build_prompt() {
    arg prompt, @def;
    var name, ans;
    
    [(def ?= "")] = def;
    while (!ans) {
        ans = (> .prompt(prompt) <);
        if (ans == "@skip")
            throw(~skip, "Skipped");
        if (!ans) {
            if (!def)
                continue;
            ans = def;
        }
    }
    return ans;
};

protected method .build_get_name() {
    arg prompt, @def;
    var name, out;
    
    .build_hint(3);
    while (!out) {
        name = (> .build_prompt(prompt, @def) <);
        if (!(out = (| $code_lib.parse_name(name) |)))
            .tell("Invalid name.");
    }
    return out;
};

protected method .build_query_realm() {
    arg there;
    var line, realm, r, prompt;
    
    prompt = ((("What realm is " + (there.name())) + " in? [") + (((.location()).realm()).name())) + "] ";
    while (!realm) {
        line = (> .build_prompt(prompt, tostr((.location()).realm())) <);
        if (!line) {
            realm = (.location()).realm();
        } else if (line == "@realms") {
            r = ($place_lib.known_realms()).union($realm.descendants());
            .tell(["Realms:", ""] + ((r.mmap('name)).prefix("    ")));
        } else {
            realm = $place_lib.match_realm(line);
            if (!realm) {
                .tell(("Unknown realm \"" + line) + "\", try @realms.");
            } else if (!(realm.is($realm))) {
                .tell((realm.namef('ref)) + " is not a realm, try @realms.");
                realm = 0;
            }
        }
    }
    return realm;
};

protected method .build_get_path() {
    arg source, dest;
    var eleave, earrive, opp, t, path;
    
    // Get the exits
    // catch any {
    while (!path) {
        eleave = (> .build_query_exit(source, dest) <);
        if (eleave) {
            // try really hard to figure this out
            if (!(opp = $place_lib.opposite_direction((eleave[1])[1]))) {
                for t in (eleave[2]) {
                    t = strsed(t, "[^a-z]+", "", "g");
                    if ((opp = $place_lib.opposite_direction(t)))
                        break;
                }
            }
            if (opp) {
                opp = strsed(explode(opp, "|")[1], "[^a-z]+", "", "g");
                earrive = (> .build_query_exit(dest, source, opp) <);
            } else {
                earrive = (> .build_query_exit(dest, source) <);
            }
        }
    
        //} with {
        //    if (eleave) {
        //        .build_cleanup([eleave, 1]);
        //        if (earrive)
        //            .build_cleanup([earrive, 1]);
        //    }
        //    rethrow(error());
        //}
        catch any
            path = .build_generate_path(source, dest, eleave, earrive);
        with
            .tell((traceback()[1])[2]);
    }
    return path;
};

protected method .dig_cmd() {
    arg cmdstr, cmd, args;
    var m, syn, name, dest, dnew, parent, name, dname, lname, arrive, aname, path, loc;
    
    (> .perms(caller(), 'command) <);
    syn = ["Syntax: `@dig <new place>` OR", "        `@dig <leaving exit>[;<arriving exit>] to <objref or new place>`", "You may also want to try @build."];
    if (!args)
        return syn;
    loc = .location();
    
    // are they essentially just @spawn'ing?
    if (!(m = match_template(args, "* to *"))) {
        if (match_regexp(args, "^\$[a-z0-9_]+$"))
            return syn;
        if (!(name = (> $code_lib.parse_name(args) <)))
            return "Invalid name.";
        [parent, dest] = (> .build_parse_name((name[1])[1], $place) <);
        name = replace(name, 1, replace(name[1], 1, dest));
        catch any
            dest = (> parent.spawn() <);
        with
            return (traceback()[1])[2];
        .build_set_name(dest, @name);
        dest.set_realm(loc.realm());
        return ("New place created " + (dest.namef('ref))) + ".";
    }
    
    // can we extend from this room?
    if (!(| loc.will_attach('source) |))
        return "This room is not publicly extendable.";
    
    // do some basic parsing before we needlessly create anything
    [args, m, name] = m;
    [lname, (aname ?= "")] = split(args, " *[|;] *");
    if ((!lname) || (!name))
        return syn;
    
    // create or parse the destination first
    name = name.trim();
    if (match_regexp(name, "^\$[a-z0-9_]+$")) {
        if (!(dest = (| lookup(tosym(substr(name, 2))) |)))
            return "Invalid object name.";
        if (!(dest.is($place)))
            return ("Destination " + (dest.namef('ref))) + " is not a place.";
    } else {
        if (!(name = (> $code_lib.parse_name(name) <)))
            return "Invalid name.";
        [parent, dest] = (> .build_parse_name((name[1])[1], $place) <);
        name = replace(name, 1, replace(name[1], 1, dest));
        catch any
            dest = (> parent.spawn() <);
        with
            return (traceback()[1])[2];
        .build_set_name(dest, @name);
        dest.set_realm(loc.realm());
        .tell(("Created new place " + (dest.namef('ref))) + ".");
        dnew = 1;
    }
    
    // now parse and attach the exits
    // first the leaving exit..
    if (!(name = (| $code_lib.parse_name(lname) |)))
        return ("Invalid exit name '" + lname) + "'";
    
    //catch ~stop {
    //    leave = (> .build_create_and_attach_exit(name, loc, dest) <);
    //
    // (> .build_attach_exit(leave, loc, dest) <);
    //    .tell("Attached exit " + leave.name() + " from " + loc.name());
    //} with {
    //    .tell(traceback()[1][2]);
    //    return .build_cleanup([dest, dnew]);
    //}
    // see if they want a return exit, if they didn't say anything
    aname = aname.trim();
    if (!aname) {
        if (!(dname = $place_lib.opposite_direction(lname)))
            dname = lname;
        arrive = (> (.prompt(("Specify return exit, or 'none' for no return exit [" + dname) + "] ")).trim() <);
        if (!arrive)
            aname = dname;
        else if (arrive != "none")
            aname = strsub(arrive, "|", ",");
    }
    
    // now the (optional) arrival exit
    if (aname) {
        if (!(dname = (| $code_lib.parse_name(aname) |)))
            return ("Invalid exit name '" + cname) + "'";
    
        //    catch ~stop {
        //       arrive = (> .build_create_and_attach_exit(name, dest, loc) <);
        // (> .build_attach_exit(arrive, dest, loc) <);
        //        .tell("Attached exit " + arrive.name() + " from " + dest.name());
        //    } with {
        //        .tell(traceback()[1][2]);
        // thirty second leeway guess to if we created it or not
        // ... what I do to keep from wrapping
        //        dnew = dnew.or(leave.created_on() > time() - 30 ? 2 : 0);
        //        return .build_cleanup([dest, dnew.and(1)], [leave, dnew.and(2)]);
        //    }
    }
    catch ~stop {
        if (aname) {
            path = (> .build_generate_path(loc, dest, name, dname) <);
    
            // (> .build_attach_exit(arrive, dest, loc) <);
        } else {
            path = (> .build_generate_path(loc, dest, name) <);
        }
        .tell((("Attached way " + (path.name())) + " from ") + (loc.name()));
    } with {
        .tell((traceback()[1])[2]);
    
        // thirty second leeway guess to if we created it or not
        // ... what I do to keep from wrapping
        dnew = dnew.or((path && ((path.created_on()) > (time() - 30))) ? 2 : 0);
        return .build_cleanup([dest, dnew.and(1)], [path, dnew.and(2)]);
    }
};

protected method .teleport_cmd() {
    arg cmdstr, com, dest;
    var loc, p;
    
    (> .perms(caller(), 'command) <);
    if (!dest) {
        .tell("Specify a destination.");
        return;
    }
    if (dest == "home")
        loc = .home();
    else
        loc = (| .match_environment(dest) |);
    
    // if we have still not found a location...
    if (!loc) {
        catch any {
            loc = $place_db.search(dest);
        } with {
            switch (error()) {
                case ~ambig:
                    .tell("Several rooms match that name: " + ((((traceback()[1])[3]).mmap('namef)).to_english()));
                case ~namenf:
                    .tell(("Unable to find place \"" + dest) + "\".");
                    return;
                default:
                    return (traceback()[1])[2];
            }
        }
    }
    if (!loc) {
        .tell(("Unable to find place \"" + dest) + "\".");
        return;
    }
    if (loc == (.location())) {
        .tell("You are already there!");
        return;
    }
    if (!(.teleport(loc)))
        .tell("Sorry.");
};

protected method .build_parse_name() {
    arg str, class;
    var m, parent, what;
    
    if ((m = regexp(str, "^ *\$([a-z0-9_]+) *: *(.*)$"))) {
        parent = m[1];
        what = m[2];
        if (parent) {
            catch ~namenf, ~symbol
                parent = (> lookup(tosym(parent)) <);
            with
                throw(~stop, ("The object '$" + parent) + "' is not valid.");
            if (!(parent.is(class)))
                throw(~stop, ((("Parent object " + parent) + " is not ") + ((class.objname()).add_indefinite())) + "!");
        }
    } else {
        what = str;
    }
    if (!parent)
        parent = $place_lib.get_default(class.objname());
    return [parent, what];
};

protected method .teleport() {
    arg dest;
    var m, source, vars;
    
    source = .location();
    catch any {
        .move_to(dest);
    } with {
        .tell((traceback()[1])[2]);
        return 0;
    }
    vars = #[["$actor", this()], ["actor", .name()], ["$source", source], ["source", source.name()], ["$dest", dest], ["dest", dest.name()]];
    m = .eval_message("teleport", $builder, vars);
    dest.announce(m);
    source.announce(m);
};

protected method .define_msg_cmd() {
    arg cmdstr, cmd, args;
    var what, opts, def, o, i, br, ref, compiler, eval, getter;
    
    (> .perms(caller(), 'command) <);
    [args, opts] = (> $parse_lib.opt(args, "b?ranches", "c?ompiler", "e?valuator", "g?etter") <);
    args = join(args);
    what = split(args, " *: *");
    if (listlen(what) != 2)
        return "Invalid message reference " + args;
    [def, what] = what;
    what = what.trim();
    if (match_regexp(what, "[=.]"))
        return ("You cannot set the default with " + cmd) + ".";
    def = (> .match_env_nice(def) <);
    if (!(def.is_writable_by(this())))
        return ("You cannot define messages on " + (def.namef('ref))) + ".";
    if (type(def) == 'frob)
        return "You cannot define messages on a frob.";
    catch any {
        (> def.define_msg(what) <);
        ref = (def + ":") + what;
        .tell(("Message " + ref) + " defined.");
    } with {
        return (traceback()[1])[2];
    }
    o = opts.slice(1);
    if ((i = "b?ranches" in o)) {
        br = (((opts[i])[4]).trim()).split(" *, *");
        catch any {
            def.set_msg_attr(what, 'branches, br);
            .tell("Message branches defined:");
            for i in (br)
                .tell((("  " + ref) + ".") + i);
        } with {
            .tell((traceback()[1])[2]);
        }
    }
    if ((i = "e?valuator" in o)) {
        eval = (opts[i])[4];
        if (!eval) {
            .tell("No evaluator specified with +evaluator=??");
        } else {
            eval = (> .match_env_nice(eval) <);
            if (!(eval.is($evaluator)))
                return "Invalid evaluator object: " + evaluator;
            catch any {
                def.set_msg_attr(what, 'evaluator, eval);
                .tell((("Set evaluator for " + ref) + " to ") + eval);
            } with {
                .tell((traceback()[1])[2]);
            }
        }
    }
    if ((i = "c?ompiler" in o)) {
        compiler = (opts[i])[4];
        if (!compiler) {
            .tell("No compiler specified with +compiler=??");
        } else {
            compiler = (> .match_env_nice(compiler) <);
            if (!(compiler.is($compiler)))
                .tell("Invalid compiler object: " + compiler);
            catch any {
                def.set_msg_attr(what, 'compiler, compiler);
                .tell((("Set compiler for " + ref) + " to ") + compiler);
            } with {
                .tell((traceback()[1])[2]);
            }
        }
    }
    if ((i = "g?etter" in o)) {
        getter = (opts[i])[4];
        if (!getter) {
            .tell("No getter specified with +getter=??");
        } else {
            getter = (> tosym(getter) <);
            catch any {
                def.set_msg_attr(what, 'getter, getter);
                .tell((("Set getter for " + ref) + " to ") + getter);
            } with {
                .tell((traceback()[1])[2]);
            }
        }
    }
};

protected method .undefine_msg_cmd() {
    arg cmdstr, cmd, args;
    var what, opts, def;
    
    (> .perms(caller(), 'command) <);
    
    // it niggles the string enough to 'clean' up little mistakes
    [args, opts] = (> $parse_lib.opt(args, "b?ranches", "c?ompiler") <);
    args = join(args);
    what = split(args, " *: *");
    if (listlen(what) != 2)
        return "Invalid message reference " + args;
    [def, what] = what;
    what = what.trim();
    def = (> .match_env_nice(def) <);
    if (!(def.is_writable_by(this())))
        return ("You cannot define messages on " + (def.namef('ref))) + ".";
    catch any {
        (> def.undefine_msg(what) <);
        .tell(((("Message " + def) + ":") + what) + " undefined.");
    } with {
        return (traceback()[1])[2];
    }
};

private method ._ar__mailmsg() {
    arg request, msg;
    var u, recip, text, mail, id, fmt, c, cmts;
    
    u = request.submitted_by();
    id = request.id();
    if (valid(u) && (u.is($mail_list))) {
        text = (u.mail_name()) + " and *bugs";
        .tell("** Specify recipients for this comment, or 'none'");
        recip = (> .prompt(("** Mail comment to [" + text) + "] ") <);
        if (!recip)
            recip = text;
        if ((recip == "no") || (recip == "none"))
            return "** Not mailing.";
        recip = .parse_mail_recipient_list(recip);
        if (!recip)
            return "** No valid recipients.";
        mail = $mail_message.new_mail();
        mail.set_subject((("Comment on AR #" + id) + ": ") + (request.summary()));
        text = ["Reported By: " + (request.submitted_by())];
        text += ["Reported On: " + ($time.format("%d-%h-%Y", request.submitted_on()))];
        text += [""];
        text += ((request.text()).mmap('wrap_lines, 70, "> ", 1)).flatten();
        cmts = request.comments();
        msg = (cmts.last())[3];
        cmts = sublist(cmts, 1, listlen(cmts) - 1);
        for c in (cmts) {
            fmt = "On " + ($time.format("%d-%h-%Y ", c[1]));
            fmt += ((c[2]).namef('ref)) + " Comments:";
            text += ["", fmt] + (((c[3]).mmap('wrap_lines, 70, "> ", 1)).flatten());
        }
        text += [""] + msg;
        mail.set_text(text);
        catch any
            mail.send(@recip);
        with
            return (traceback()[1])[2];
        return "** Mail sent.";
    }
};

root method .core_builder() {
    // for now we dont core the bug system
    (| .del_command("@bug?s <any>", 'bug_cmd) |);
    (| .del_method('bug_cmd) |);
};

protected method .build_generate_path() {
    arg source, dest, spname, @dpname;
    var parent, path, sname, dname, line;
    
    sname = spname[1];
    [parent, path] = (> .build_parse_name(sname[1], $path) <);
    sname = replace(sname, 1, path);
    spname = replace(spname, 1, sname);
    path = (| source.match_environment(path) |);
    if (path) {
        if (path.is($path))
            throw(~stop, (((sname[1]) + " is already a path from ") + (source.name())) + ".");
        if (path.source(dest))
            throw(~stop, (path.namef('ref)) + " is alread linked.");
    }
    if (dpname) {
        [dpname] = dpname;
        dname = dpname[1];
        [parent, path] = (> .build_parse_name(dname[1], $path) <);
        dname = replace(dname, 1, path);
        dpname = replace(dpname, 1, dname);
        path = (| dest.match_environment(path) |);
        if (path) {
            if (path.is($path))
                throw(~stop, (((dname[1]) + " is already a path from ") + (dest.name())) + ".");
            if (path.source(source))
                throw(~stop, (path.namef('ref)) + " is alread linked.");
        }
    }
    if (!path) {
        catch any
            path = (> parent.new() <);
        with
            throw(~stop, "Unable to create path: " + ((traceback()[1])[2]));
    }
    catch any {
        path.attach(source, dest);
        .build_set_name(path, @spname, source);
        if (dpname) {
            path.attach(dest, source);
            .build_set_name(path, @dpname, dest);
        }
    } with {
        .tell(("Unable to attach " + (path.name())) + " because: ");
        .tell("  " + ((traceback()[1])[2]));
        line = (> .prompt("Continue building? ") <);
        if (line in ["no", "n"])
            throw(~abort, "Aborted");
    }
    return path;
};

protected method .action_request_cmd() {
    arg cmdstr, cmd, args;
    var syn, opts, request, command;
    
    syn = ("Syntax: " + cmd) + " [+<ar group>] <cmt|list|view|claim|dismiss|fix> [addtl]";
    [args, opts] = (> $parse_lib.opt(args, "a?ll", "f?ull") <);
    if (!args)
        return ._ar__interactive();
    if ((listlen(args) > 1) && ((args[1]).is_numeric()))
        args = [args[2], args[1]] + sublist(args, 3);
    [command, @args] = args;
    if (match_template(command, "com?ment|cmt")) {
        request = (> ._ar__get_request(args, cmd + " comment") <);
        return (> ._ar__comment(sublist(args, 2), opts, request) <);
    } else if (match_template(command, "l?ist")) {
        return (> ._ar__list(args, opts) <);
    } else if (match_template(command, "v?iew")) {
        request = (> ._ar__get_request(args, cmd + " view") <);
        return (> ._ar__view(sublist(args, 2), opts, request) <);
    } else if (match_template(command, "cl?aim")) {
        request = (> ._ar__get_request(args, cmd + " claim") <);
        return (> ._ar__claim(sublist(args, 2), opts, request) <);
    } else if (match_template(command, "r?esolv|f?ix")) {
        request = (> ._ar__get_request(args, cmd + " fix") <);
        return (> ._ar__fix(sublist(args, 2), opts, request) <);
    } else if (match_template(command, "d?ismiss")) {
        request = (> ._ar__get_request(args, cmd + " dismiss") <);
        return (> ._ar__dismiss(sublist(args, 2), opts, request) <);
    } else {
        if ((!args) && (command.is_numeric())) {
            request = (> ._ar__get_request([command], cmd + " view") <);
            return (> ._ar__view([], opts, request) <);
        }
        return [syn, ("Unsupported command '" + command) + "'"];
    }
};

protected method ._ar__list() {
    arg args, opts;
    var requests, w, all, r, g, list, group;
    
    group = (> ._ar__get_group(args, opts) <);
    if (!group)
        return "Goodbye.";
    if (group != 'All) {
        requests = filter r in (group.requests()) where (!((r[2])[2]));
        requests = #[[group, requests]];
        .tell(("** Un-Resolved " + (group.name())) + " Action Requests:");
        w = (.linelen()) - 20;
    } else {
        requests = #[];
        for g in (setremove($argroup.children(), $dismissed_problems)) {
            list = filter r in (g.requests()) where (!((r[2])[2]));
            if (list)
                requests = dict_add(requests, g, list);
        }
        all = 1;
        .tell("** ALL Un-Resolved Action Requests:");
        w = (.linelen()) - 34;
    }
    return ._ar__listgrp(requests, w, all);
};

protected method ._ar__get_group() {
    arg args, opts, @notall;
    var group, groups, s, menu;
    
    groups = $argroup.children();
    if (opts) {
        if (("a?ll" in (opts.slice(1))) && (!notall))
            group = 'All;
        else if (!(group = (| groups.match_object((opts[1])[2]) |)))
            throw(~stop, ("Invalid AR Group '" + ((opts[1])[2])) + "'");
    } else {
        if (notall)
            menu = [];
        else
            menu = ["0=>ALL GROUPS"];
        for group in [1 .. listlen(groups)]
            menu += [(group + "=>") + ((groups[group]).name())];
        group = 0;
        menu += ["X=>Exit"];
        while (1) {
            s = (> .do_menu("AR Groups", "Select AR Group", @menu) <);
            if ((!s) || (s == "X"))
                return 0;
            if (s.is_numeric()) {
                if ((!(group = (| groups[toint(s)] |))) && (s == "0")) {
                    if (!notall)
                        group = 'All;
                    group = 0;
                }
            }
            if (!group)
                .tell(["**", ("** Sorry, '" + s) + "' is not a valid group."]);
            else
                break;
        }
    }
    return group;
};

protected method ._ar__view() {
    arg args, opts, request;
    
    return request.format();
};

protected method ._ar__fix() {
    arg args, opts, request;
    var line, cmt, n;
    
    n = (request.group()).name();
    if (request.resolved_on())
        return (((n + " Action Request #") + (request.id())) + " has already been resolved by ") + ((request.resolved_by()).namef('ref));
    .tell(request.format());
    line = (> .prompt(("Mark " + n) + " Action Request as resolved? [yes] ") <);
    if ((line.is_boolean()) == 0)
        return "** Aborting.";
    .tell("** Enter any final remarks, or nothing for no remarks.");
    cmt = .read("** Enter \".\" to finish or \"@abort\" to abort.");
    if (type(cmt) != 'list)
        return [];
    request.resolve();
    .tell(("** " + n) + " Action Request has been marked as resolved.");
    if (cmt)
        request.add_comment(cmt);
    return ._ar__mailmsg(request, cmt);
};

protected method ._ar__comment() {
    arg args, opts, request;
    var text, fmt, cmt, n, u, msg, id;
    
    n = (request.group()).name();
    id = request.id();
    .tell("** Commenting on Action Request #" + id);
    cmt = .read("** Enter \".\" to finish or \"@abort\" to abort.");
    if ((type(cmt) != 'list) || (!cmt))
        return "** No comments added.";
    request.add_comment(cmt);
    .tell((("** Comments added to " + n) + " AR #") + id);
    return ._ar__mailmsg(request, cmt);
};

protected method ._ar__claim() {
    arg args, opts, request;
    var n, id, s, cmt;
    
    n = (request.group()).name();
    id = request.id();
    if (request.claimed_on()) {
        .tell((((n + " Action Request #") + id) + " has already been claimed by ") + ((request.claimed_by()).namef('ref)));
        s = (> .prompt("Reclaim it in your name? [no] ") <);
        if ((!s) || ((s.is_boolean()) == 0))
            return "** Aborting.";
    }
    .tell(request.format());
    s = (> .prompt(("Claim this " + n) + " Action Request? [yes] ") <);
    if ((s.is_boolean()) == 0)
        return "** Aborting.";
    .tell("** Enter any remarks, or nothing for no remarks.");
    cmt = .read("** Enter \".\" to finish or \"@abort\" to abort claiming.");
    if (type(cmt) != 'list)
        return;
    if (cmt)
        request.add_comment(cmt);
    request.claim();
    return (("** You have claimed " + n) + " Action Request #") + id;
};

protected method ._ar__interactive() {
    var choice, category, bug, list, line, menu;
    
    while (choice != 'exit) {
        choice = .do_menu("Action Requests", "", "1=>Scan unclaimed open requests", "2=>Scan your open requests", "X=>Exit", 'exit);
        switch (choice) {
            case "1":
                (> ._ar__ilist('unclaimed) <);
            case "2":
                (> ._ar__ilist('mine) <);
            case 'exit:
                return "Goodbye.";
        }
    }
};

protected method ._ar__listgrp() {
    arg requests, w, full;
    var group, request, r, id, date, summary, resolved, str, list, out;
    
    list = #[];
    out = [];
    for group in (dict_keys(requests)) {
        for request in (requests[group]) {
            id = request[1];
            [r, resolved, date, summary] = request[2];
            date = $time.format("%d-%h-%Y", date);
            if (full)
                str = strfmt("%4r: %11l %11l  %*e", id, group.name(), date, w, summary).trim('right);
            else
                str = strfmt("%4r: %13l  %*e", id, date, w, summary).trim('right);
            out += [str];
            list = dict_add(list, id, r);
        }
    }
    .tell(out);
    .tell(("--- " + listlen(dict_keys(list))) + " Total");
    return list;
};

protected method ._ar__ilist() {
    arg how;
    var requests, list, g, r, pr, list, keys, choice;
    
    while (1) {
        if (how == 'mine) {
            requests = #[];
            for g in (setremove($argroup.children(), $dismissed_problems)) {
                list = filter r in (g.requests()) where ((!((r[2])[2])) && (((r[2])[5]) == this()));
                if (list)
                    requests = dict_add(requests, g, list);
            }
            .tell("** Your Un-Resolved Action Requests:");
            list = ._ar__listgrp(requests, (.linelen()) - 32, 1);
        } else {
            list = 0;
            catch ~abort
                list = (> ._ar__list([], []) <);
            if (list == #[])
                continue;
            if ((!list) || (list == "Goodbye."))
                return;
        }
        pr = (> .prompt("Select Action Request, or [RET] to exit") <);
        if ((!pr) || match_template(pr, "x|ex?it"))
            return;
        if ((!(pr.is_numeric())) || (!dict_contains(list, toint(pr)))) {
            .tell("Invalid Action Request");
        } else {
            pr = toint(pr);
            keys = dict_keys(list);
            while ((choice = ._ar__iview(list[pr]))) {
                if (choice == 'next) {
                    r = pr in keys;
                    if (r < listlen(keys)) {
                        pr = keys[r + 1];
                    } else {
                        .tell("No Next Action Request.");
                        break;
                    }
                } else {
                    r = pr in keys;
                    if (r != 1) {
                        pr = keys[r - 1];
                    } else {
                        .tell("No Previous Action Request.");
                        break;
                    }
                }
            }
        }
    }
};

protected method ._ar__dismiss() {
    arg args, opts, request;
    var line, cmt, n, id;
    
    n = (request.group()).name();
    id = request.id();
    if ((request.group()) == $dismissed_problems)
        return ((n + " Action Request #") + id) + " has already been dismissed";
    .tell(request.format());
    line = (> .prompt(((("Dismiss " + n) + " Action Request #") + id) + "? [yes] ") <);
    if ((line.is_boolean()) == 0)
        return "** Aborting.";
    .tell("** Enter any remarks, or nothing for no remarks.");
    cmt = .read("** Enter \".\" to finish or \"@abort\" to abort.");
    if (type(cmt) != 'list)
        return;
    if (cmt)
        request.add_comment(cmt);
    request.change_group($dismissed_problems);
    return ("** " + n) + " Action Request has been marked as resolved.";
};

protected method ._ar__iview() {
    arg pr;
    var cmd, msg, args, opts;
    
    msg = "[Return] [N]ext [P]rev [C]laim [F]ix [D]ismiss [A]ppend [M]ove";
    while (1) {
        .tell(pr.format());
        [args, opts] = (> $parse_lib.getopt(.prompt(msg)) <);
        if ((!args) || match_template(args[1], "x|ex?it"))
            return 0;
        [cmd, @args] = args;
        if (match_template(cmd, "n?ext"))
            return 'next;
        if (match_template(cmd, "p?revious"))
            return 'prev;
        if (match_template(cmd, "c?laim"))
            .tell(._ar__claim(args, opts, pr));
        else if (match_template(cmd, "f?ix|r?esolve"))
            .tell(._ar__fix(args, opts, pr));
        else if (match_template(cmd, "d?ismiss"))
            .tell(._ar__dismiss(args, opts, pr));
        else if (match_template(cmd, "a?ppend|cmt|com?ment"))
            .tell(._ar__comment(args, opts, pr));
        else if (match_template(cmd, "m?ove"))
            .tell(._ar__move(args, opts, pr));
    }
};

protected method ._ar__get_request() {
    arg args, cmd;
    var request, g, menu;
    
    if (!args)
        throw(~stop, ("No request specified with '" + cmd) + "'");
    [request, @args] = args;
    if ((request[1]) == "$") {
        catch any
            request = $object_lib.to_dbref(request);
        with
            throw(~stop, (traceback()[1])[2]);
        if ((!(request.is($action_request))) || (request == $action_request))
            throw(~stop, (request.namef('ref)) + " is not a Action Request.");
    } else {
        if ((request[1]) == "#")
            request = substr(request, 2);
        request = toint(request);
        if (request <= 0)
            throw(~stop, "Invalid request number #" + request);
        for g in ($argroup.children()) {
            if (dict_contains(g.requests(), request))
                return ((g.requests())[request])[1];
        }
        throw(~stop, "Unable to find action request #" + request);
    }
};

protected method .join_cmd() {
    arg cmdstr, cmd, who;
    var loc, p, user;
    
    (> .perms(caller(), 'command) <);
    if (!who) {
        .tell("Specify a user to join.");
        return;
    }
    catch any {
        if ((who[1]) in "$#") {
            user = (> $object_lib.to_dbref(who) <);
            if (!(user.has_ancestor($thing)))
                return "You can only join things in the VR.";
        } else {
            user = (> $user_db.search(who) <);
        }
    } with {
        .tell((traceback()[1])[2]);
        return;
    }
    loc = user.location();
    if (loc == (.location())) {
        .tell(("You are already with " + (user.name())) + "!");
        return;
    }
    if (!(.teleport(loc)))
        .tell("Sorry.");
    else
        .tell(("You join " + (user.name())) + ".");
};

protected method ._ar__move() {
    arg args, opts, request;
    var group;
    
    while (1) {
        .tell("** Changing AR Group for AR #" + (request.id()));
        catch ~abort
            group = (> ._ar__get_group(args, opts, 'notall) <);
        if (!group)
            return "** Not changing group.";
        if (group == (request.group()))
            return (("** #" + (request.id())) + " is already in ") + (request.group());
        request.change_group(group);
        return ((("** " + (request.id())) + " is now in the ") + (group.name())) + " group";
    }
};


new object $storyteller: $builder;

var $root manager = $storyteller;
var $located location = $body_cave;
var $root created_on = 809928922;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $user task_connections = #[];
var $user formatter = $plain_format;
var $location contents = [];
var $root managed = [$storyteller];
var $user password = "*";
var $command_cache shortcuts = 0;
var $command_cache modules = [];
var $thing gender = $gender_neuter;
var $command_cache commands = 0;
var $has_name name = ['prop, "Storyteller", "Storyteller"];


new object $dmi_data_ui: $user_interfaces;

var $root manager = $dmi_data_ui;
var $root managed = [$dmi_data_ui];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 861514233;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[["@verbal-index", [["@verbal-index", "", "@verbal-index", 'verbal_index_cmd, #[]]]], ["@dmethod", [["@dmethod", "*", "@dmethod <objref>", 'describe_method_english_cmd, #[[1, ['objref, []]]]]]], ["@add-arg", [["@add-arg", "*", "@add-arg <objref: +converter +converter-args +default +name>", 'add_arg_cmd, #[[1, ['objref_opt, ["converter", "converter-args", "default", "name"]]]]]]], ["@del-arg", [["@del-arg", "*", "@del-arg <objref: +name>", 'del_arg_cmd, #[[1, ['objref_opt, ["name"]]]]]]]];
var $root inited = 1;
var $command_cache modules = [];
var $root credit = ["Bruce Mitchener, Jr <bruce@puremagic.com>"];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;

public method .dmi_del_arg() {
    arg object, method, argument;
    var defining_object;
    
    defining_object = (> $interface_registry.where_is(object, method) <);
    (> defining_object.del_data_from_method(method, 'args, argument) <);
};

public method .set_auth() {
    arg object, method, authorization_data;
    var defining_object;
    
    defining_object = (> $interface_registry.where_is(object, method) <);
    (> defining_object.add_data_to_method(method, 'auth, authorization_data) <);
};

public method .dmi_add_arg() {
    arg object, method, argument, default_value, converter;
    var defining_object;
    
    catch ~matchnf {
        defining_object = $interface_registry.where_is(object, method);
    } with {
        if (object.is($page))
            defining_object = object;
        else
            rethrow(error());
    }
    (> defining_object.add_data_to_method(method, 'args, argument, [default_value, converter]) <);
};

public method .verbal_index_cmd() {
    arg cmdstr, cmd;
    
    sender().tell($interface_registry.verbal_index());
};

public method .arg_description_to_english() {
    arg arg_name, arg_description;
    var str_list, converter, default_value, converter_arg;
    
    str_list = ["Arg:             " + arg_name];
    default_value = arg_description[1];
    converter = arg_description[2];
    if (default_value != [])
        str_list += ["    Default:     " + toliteral(default_value[1])];
    else
        str_list += ["    Default:     None."];
    if ((converter.length()) == 3)
        str_list += [((((("    Converter:   " + tostr(converter[1])) + ".") + tostr(converter[2])) + "( <arg value>, ") + (map converter_arg in (converter[3]) to (toliteral(converter_arg)).join(", "))) + ")"];
    else
        str_list += ["    Converter:   None."];
    return str_list;
};

public method .method_description_to_english() {
    arg object, method;
    var args, argument, argname, argorder, str_list, description;
    
    description = (> $interface_registry.describe(object, method) <);
    args = description['args];
    argorder = (| description['arg_order] |) || (args.keys());
    str_list = [((("Method:          " + tostr(object)) + ".") + tostr(method)) + "()"];
    str_list += ["Authentication:  " + toliteral((| description['auth] |) || "unspecified")];
    for argument in (argorder)
        str_list += .arg_description_to_english(argument, args[argument]);
    str_list += ["---"];
    return str_list;
};

public method .describe_method_english_cmd() {
    arg cmdstr, cmd, args;
    var i, pattern, ref, methods, s, def, method, opts, str, m, d, out, type;
    
    (> .perms(caller(), 'command) <);
    ref = args;
    if ((ref[1]) == 'variable)
        return ((("The reference " + (ref[3])) + ",") + ((ref[4]) || "")) + " is not for a method.";
    if ((ref[1]) == 'object)
        return ("The reference " + (ref[3])) + " is not for a method.";
    def = (| (ref[2]).find_method(tosym(ref[4])) |);
    if (def) {
        pattern = ref[4];
        methods = [tosym(ref[4])];
    } else {
        if (ref[4])
            pattern = ref[4];
        else
            pattern = .get_setting("match-default", $programmer);
        def = ref[3];
        m = .get_setting("match-with", $programmer);
        methods = [];
        for method in (def.methods()) {
            if (tostr(method).(m)(pattern))
                methods += [method];
        }
        if (!methods)
            return .tell((("No method found matching " + def) + ".") + pattern);
    }
    cmd = .get_setting("@program-options", $programmer);
    out = [];
    for method in (methods)
        out += .method_description_to_english(def, method);
    return out;
};

public method .add_arg_cmd() {
    arg cmd, cmstr, args;
    var opts, argname, argdefault, argconverter, object, method, config, objref, argconverterargs;
    
    object = (args[1])[2];
    method = tosym((args[1])[4]);
    opts = args[3];
    config = #[];
    config = (> ._get_opt("name", 'string, opts, config) <);
    config = (> ._get_opt("default", 'data_list, opts, config) <);
    config = (> ._get_opt("converter", 'objref, opts, config) <);
    config = (> ._get_opt("converter-args", 'data_list, opts, config) <);
    argname = (| config['name] |);
    if (!argname)
        return "Must specify the name of the argument to add";
    if (argname)
        [argname] = argname;
    argdefault = (| config['default] |) || [];
    objref = (| config['converter] |) || [];
    argconverterargs = [];
    if (objref && (type(objref[1]) == 'list)) {
        argconverterargs = objref[2];
        objref = objref[1];
    }
    argconverter = [objref[2], tosym(objref[4]), argconverterargs];
    (> .dmi_add_arg(object, method, argname, argdefault, argconverter) <);
    return .arg_description_to_english(argname, ((object.describe_method(method))['args])[argname]);
    return ("Argument, " + argname) + ", successfully added.  Mail Bruce to have this give the definition of the argument.";
};

public method ._get_opt() {
    arg opt, type, opts, dict;
    var i, value, m;
    
    if (!(i = opt in (opts.slice(1))))
        return dict;
    value = (opts[i])[4];
    if (!value)
        throw(~stop, ("No value for option \"" + opt) + "\".");
    catch any {
        switch (type) {
            case 'string:
                value = [value];
            case 'objref:
                value = (> $parse_lib.ref(value) <);
            case 'symbol:
                value = [(> value.to_symbol() <)];
            case 'data_list:
                value = (> fromliteral(value) <);
                if (type(value) != 'list)
                    value = [value];
        }
    } with {
        rethrow(~stop);
    }
    opt = opt.strip("?");
    if ((m = match_pattern(opt, "*-args"))) {
        opt = tosym(m[1]);
        if (!dict_contains(dict, opt))
            throw(~stop, ((("Arguments defined for " + opt) + " without defining ") + opt) + " method.");
        value = [dict[opt], [@value]];
        return dict_add(dict, opt, value);
    } else {
        return dict_add(dict, tosym(opt), value);
    }
};

public method .del_arg_cmd() {
    arg cmd, cmstr, args;
    var opts, argname, argdefault, argconverter, object, method, config, objref, argconverterargs;
    
    object = (args[1])[2];
    method = tosym((args[1])[4]);
    opts = args[3];
    config = #[];
    config = (> ._get_opt("name", 'string, opts, config) <);
    argname = (| config['name] |);
    if (!argname)
        return "Must specify the name of the argument to add";
    if (argname)
        [argname] = argname;
    (> .dmi_del_arg(object, method, argname) <);
    return ("Argument, " + argname) + ", successfully deleted.";
};


new object $programmer: $storyteller, $dmi_data_ui;

var $root inited = 1;
var $root manager = $programmer;
var $root quota = 75000;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables, 'general_cache];
var $root managed = [$programmer];
var $location contents = [];
var $located location = $body_cave;
var $located obvious = 1;
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user modes = #[];
var $user formatter = $plain_format;
var $user parsers = [$command_parser];
var $user task_connections = #[];
var $programmer eval_prefix = 0;
var $programmer eval_tick_offset = 0;
var $programmer eval_offset = 0;
var $command_aliases command_aliases = [];
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list senders = 1;
var $mail_list readers = [];
var $mail_list notify = [$programmer];
var $mail_list last_letter = 0;
var $mail_list mail = [];
var $mail_ui subscribed = #[[$programmer, [791485891, 0]]];
var $mail_ui current = #[['location, 0], ['list, $programmer]];
var $described prose = [];
var $has_name name = ['prop, "Generic Programmer", "Generic Programmer"];
var $has_commands local = #[["@id", [["@id", "*", "@id <any>", 'id_cmd, #[[1, ['any, []]]]]]], ["@which", [["@which", "*", "@which <any>", 'which_cmd, #[[1, ['any, []]]]]]], ["@eval", [["@eval", "*", "@eval <any>", 'eval_cmd, #[[1, ['any, []]]]]]], ["@add-c?ommand|@ac", [["@add-c?ommand|@ac", "*", "@add-c?ommand|@ac <any>", 'add_command_cmd, #[[1, ['any, []]]]]]], ["@del-c?ommand|@dc", [["@del-c?ommand|@dc", "*", "@del-c?ommand|@dc <any>", 'del_command_cmd, #[[1, ['any, []]]]]]], ["@chpar?ents", [["@chpar?ents", "*", "@chpar?ents <any>", 'chparents_cmd, #[[1, ['any, []]]]]]], ["@add-s?hortcut|@as", [["@add-s?hortcut|@as", "*", "@add-s?hortcut|@as <any>", 'add_shortcut_cmd, #[[1, ['any, []]]]]]], ["@del-m?ethod|@delm?ethod|@dm", [["@del-m?ethod|@delm?ethod|@dm", "*", "@del-m?ethod|@delm?ethod|@dm <objref>", 'del_method_cmd, #[[1, ['objref, []]]]]]], ["@trace-method|@trace", [["@trace-method|@trace", "*", "@trace-method|@trace <objref>", 'trace_method_cmd, #[[1, ['objref, []]]]]]], ["@ledit", [["@ledit", "*", "@ledit <objref: +e?dited>", 'local_edit_cmd, #[[1, ['objref_opt, ["e?dited"]]]]]]], ["@program", [["@program", "*", "@program <objref: +w?arnings +e?dited=1 +a?ccess=1 +f?lags=1>", 'program_cmd, #[[1, ['objref_opt, ["w?arnings", "e?dited", "a?ccess", "f?lags"]]]]], ["@program", "* with *", "@program <objref: +w?arnings +e?dited=1 +a?ccess=1 +f?lags=1> with <any>", 'program_cmd, #[[1, ['objref_opt, ["w?arnings", "e?dited", "a?ccess", "f?lags"]]]], [3, ['any, []]]]]], ["@del-v?ariable|@dv", [["@del-v?ariable|@dv", "*", "@del-v?ariable|@dv <objref>", 'del_var_cmd, #[[1, ['objref, []]]]]]], ["@show", [["@show", "*", "@show <objref: +c?hop>", 'show_cmd, #[[1, ['objref_opt, ["c?hop"]]]]]]], ["@del-s?hortcut|@ds", [["@del-s?hortcut|@ds", "*", "@del-s?hortcut|@ds <any>", 'del_shortcut_cmd, #[[1, ['any, []]]]]]], ["@add-p?arent|@ap", [["@add-p?arent|@ap", "*", "@add-p?arent|@ap <any>", 'add_parent_cmd, #[[1, ['any, []]]]]]], ["@del-p?arent|@dp", [["@del-p?arent|@dp", "*", "@del-p?arent|@dp <any>", 'del_parent_cmd, #[[1, ['any, []]]]]]], ["@grep", [["@grep", "*", "@grep <any:+d?escend +f?ull +l?ist +r?eplace-with=1>", 'grep_cmd, #[[1, ['any_opt, ["d?escend", "f?ull", "l?ist", "r?eplace-with"]]]]]]], ["@chmod|@mmod|@omod|@chflag?s", [["@chmod|@mmod|@omod|@chflag?s", "*", "@chmod|@mmod|@omod|@chflag?s <any>", 'chmod_cmd, #[[1, ['any, []]]]]]], ["@dump", [["@dump", "*", "@dump <any: +t?extdump +m?ethods +v?ariables +h?eader>", 'dump_cmd, #[[1, ['any_opt, ["t?extdump", "m?ethods", "v?ariables", "h?eader"]]]]]]], ["@list", [["@list", "*", "@list <objref: +n?umbers +t?extdump>", 'list_cmd, #[[1, ['objref_opt, ["n?umbers", "t?extdump"]]]]]]], ["@add-v?ariable|@av", [["@add-v?ariable|@av", "*", "@add-v?ariable|@av <any>", 'add_var_cmd, #[[1, ['any, []]]]]]], ["@hl?ist|@help-list", [["@hl?ist|@help-list", "*", "@hl?ist|@help-list <any>", 'help_list_cmd, #[[1, ['any, []]]]]]], ["@hw?rite|@help-write", [["@hw?rite|@help-write", "*", "@hw?rite|@help-write <any>", 'help_write_cmd, #[[1, ['any, []]]]]]], ["@spawn", [["@spawn", "*", "@spawn <any>", 'spawn_cmd, #[[1, ['any, []]]]]]], ["@ancestors", [["@ancestors", "*", "@ancestors <any>", 'ancestors_cmd, #[[1, ['any, []]]]]]], ["@nh?n|@new-help|@new-help-node", [["@nh?n|@new-help|@new-help-node", "*", "@nh?n|@new-help|@new-help-node <any:+n?amed=1 +o?bjname=1 +i?ndex=1>", 'new_help_node_cmd, #[[1, ['any_opt, ["n?amed", "o?bjname", "i?ndex"]]]]]]], ["@config-set?ting|@configure-set?ting", [["@config-set?ting|@configure-set?ting", "*", "@config-set?ting|@configure-set?ting <any>", 'configure_setting_cmd, #[[1, ['any, []]]]]]], ["@def-set?ting|@define-set?ting", [["@def-set?ting|@define-set?ting", "*", "@def-set?ting|@define-set?ting <any>", 'define_setting_cmd, #[[1, ['any, []]]]]]], ["@undef-set?ting|@undefine-set?ting", [["@undef-set?ting|@undefine-set?ting", "*", "@undef-set?ting|@undefine-set?ting <any>", 'undefine_setting_cmd, #[[1, ['any, []]]]]]], ["@descend?ants", [["@descend?ants", "*", "@descend?ants <objref:+a?ll +r?edundant +o?nly +n?ot>", 'descendants_cmd, #[[1, ['objref_opt, ["a?ll", "r?edundant", "o?nly", "n?ot"]]]]]]], ["@d?isplay", [["@d?isplay", "*", "@d?isplay <objref: +c?hop +g?enerations>", 'display_cmd, #[[1, ['objref_opt, ["c?hop", "g?enerations"]]]]]]], ["@cp|@copy", [["@cp|@copy", "*", "@cp|@copy <objref:+c?omment>", 'move_cmd, #[[1, ['objref_opt, ["c?omment"]]]]]]], ["@rehash", [["@rehash", "*", "@rehash <any:+r?aw +c?lient>", 'rehash_cmd, #[[1, ['any_opt, ["r?aw", "c?lient"]]]]]]]];
var $has_commands shortcuts = #[[";*", ['eval_cmd, ["eval", 1]]]];
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $root defined_settings = #[["match-with", #[['parse, ['parse_match_with]]]], ["match-default", #[]], ["@program-options", #[]], ["@list-options", #[]]];
var $thing gender = $gender_neuter;
var $root settings = #[["match-default", "*"], ["home", $body_cave], ["@list-options", ""], ["@program-options", ""], ["match-with", 'match_pattern], ["extended-parsers", []]];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;

protected method .eval_cmd() {
    arg cmdstr, com, str;
    var result, adjust, vars, v, evalp, times, line, reg, obj, definer, ref, debug;
    
    (> .perms(caller(), 'command) <);
    evalp = .eval_prefix();
    vars = (evalp.keys()).join(", ");
    v = (evalp.values()).join();
    
    // clean it up
    str = strsed(str, "^;*", "");
    
    // perform escape substitution
    if (str && ((str[1]) == "|"))
        str = substr(str, 2);
    else
        str = (> .eval_subs(str) <);
    
    // check for debug flags
    if ((reg = regexp(str, "^(trace|debug|profile|ops|opcodes) *;*(.*)$"))) {
        [debug, str] = reg;
        if (debug == "ops")
            debug = "opcodes";
        debug = tosym(debug);
    } else {
        debug = 0;
    }
    
    // who are we evaluating as
    if ((reg = regexp(str, "^ *as +([^; ]+)"))) {
        catch ~objnf, ~namenf, ~ambig
            ref = $parse_lib.ref(reg[1]);
        with
            (> .tell_error("", (traceback()[1])[2]) <);
        obj = ref[2];
        definer = ref[3];
        str = strsed(str, "^ *as +([^; ]+)[ ;]+", "");
        if ((!(definer.is_writable_by(this()))) || (!(obj.is_writable_by(this()))))
            return ("You do not have permission to evaluate on " + (reg[1])) + ".";
        if (!(obj.is(definer)))
            return (obj + " isn't a child of ") + definer;
    } else {
        obj = (definer = this());
    }
    
    // are we just adjusting our offset?
    if (!str) {
        result = (> .evaluate(((("var " + vars) + ";") + v) + "return (> 1 <);", obj, definer, 'no_offset) <);
        result = replace(result[1], 1, ((result[1])[1]) - 1);
        if (eval_offset)
            line = strfmt("adjusted by %s ticks and %s.%6{0}r seconds.", (eval_offset[1]) - (result[1]), (eval_offset[2]) - (result[2]), abs((eval_offset[3]) - (result[3])));
        else
            line = strfmt("set to %s ticks and %s.%6{0}r seconds.", @result);
        eval_offset = result;
        return "Eval offset " + line;
    }
    
    // format it
    if (match_begin(str, "var") && (reg = regexp(str, "var ([^;]+)"))) {
        str = strsed(str, "var ([^;]+);", "");
        str = ((((("var " + vars) + ", ") + (reg.join(","))) + ";") + v) + str;
    } else if ("return" in str) {
        str = ((("var " + vars) + ";") + v) + str;
    } else {
        str = strsed(str, " *;* *$", "");
        str = ((((("var " + vars) + ";") + v) + "return (> ") + str) + " <);";
    }
    if (debug) {
        result = (> .evaluate(str, obj, definer, debug) <);
        debug = (| result[3] |);
    } else {
        result = (> .evaluate(str, obj, definer, debug) <);
    }
    [times, result] = result;
    
    // Display the errors, or the result.
    if ((result[1]) == 'errors) {
        .tell(result[2]);
    } else if ((result[1]) == 'traceback) {
        .tell((result[2]).fmt_tb());
        line = strfmt("[ seconds: %l.%6{0}r; operations: %s", times[2], times[3], times[1]);
        if (times[2])
            line += (" (" + ((times[1]) / (times[2]))) + " ticks per second)";
        return line + " ]";
    } else {
        if (type(result[2]) == 'objnum)
            .tell("=> " + ((| (result[2]).namef('xref) |) || (result[2])));
        else
            .tell("=> " + toliteral(result[2]));
        if (debug)
            .tell(debug);
        line = strfmt("[ seconds: %l.%6{0}r; operations: %s", times[2], times[3], times[1]);
        if (times[2])
            line += (" (" + ((times[1]) / (times[2]))) + " ticks per second)";
        return line + " ]";
    }
};

protected method .program_cmd() {
    arg cmdstr, com, args, @more;
    var ref, o, i, ops, ign, ed, fl, meth, ex, acc, warn, errs, code, line, errs, code;
    
    (> .perms(caller(), 'command) <);
    ops = args[3];
    ref = args[1];
    
    // verify what we have is correct
    if (!(meth = (| tosym(ref[4]) |))) {
        ign++;
        .tell(("The method name '" + (((ref[4]) == 0) ? "" : (ref[4]))) + "' is not acceptable.");
    }
    if ((!ign) && ((ref[3]) && (!((ref[3]).is_writable_by(this()))))) {
        ign++;
        .tell(("You cannot program on " + ((ref[3]).namef('ref))) + ".");
    }
    if ((!ign) && ((| (ref[3]).find_method(meth) |) == (ref[3])))
        ex++;
    
    // ok, go on with options
    o = ops.slice(1);
    if ((i = "e?dited" in o)) {
        if (!((ops[i])[3])) {
            if (!($sys.is_admin(this()))) {
                ign++;
                .tell("Only admins can shut off edited comments.");
            }
        } else {
            ed = 1;
        }
    } else {
        ed = 1;
    }
    if (ed) {
        ed = (("// $#Edited: " + ($time.format("%d %b %y %H:%M"))) + " ") + this();
        if (i && ((ops[i])[4]))
            ed += ": " + ((ops[i])[4]);
    }
    if ((i = "f?lags" in o))
        fl = $parse_lib.parse_method_flags((ops[i])[4]);
    else if (ex)
        fl = (ref[3]).method_flags(meth);
    else
        fl = [];
    if ((i = "a?ccess" in o))
        acc = $parse_lib.parse_method_access((ops[i])[4]);
    else if (ex)
        acc = (ref[3]).method_access(meth);
    else
        acc = 'public;
    if ((i = "w?arnings" in o))
        warn = (ops[i])[4];
    else
        warn = 1;
    
    // now get on with it already
    if (ign)
        line = "Ignoring input until \".\" or \"@abort\"";
    else if (ex)
        line = ((((("Reprogramming " + acc) + " method ") + (ref[3])) + ".") + meth) + "()";
    else
        line = ((((("Programming " + acc) + " method ") + (ref[3])) + ".") + meth) + "()";
    if (fl)
        line += (" [" + (fl.to_english())) + "]";
    code = more ? (more.subrange(2)) : (.read(("-- " + line) + " --"));
    if (type(code) == 'symbol) {
        switch (code) {
            case 'aborted:
                return;
            case 'engaged:
                return "Sorry, you are already reading on this connection.";
            default:
                return "Unknown response from the read parser: " + code;
        }
    }
    if (ign)
        return "Finished ignoring input.";
    if (ed)
        code += [ed];
    catch any {
        if ((errs = (ref[3]).add_method(code, meth)))
            return errs.prefix("** ");
        (> (ref[3]).set_method_flags(meth, fl) <);
        (> (ref[3]).set_method_access(meth, acc) <);
        if ((line = (> $code_lib.verify_code(code, meth, warn) <)))
            .tell(line);
        return ((((("Method " + (ref[3])) + ".") + meth) + "() ") + (ex ? "re" : "")) + "compiled.";
    } with {
        return (traceback()[1])[2];
    }
};

protected method .show_cmd() {
    arg cmdstr, com, args;
    var show, match, i, chop, f, obj, out;
    
    (> .perms(caller(), 'command) <);
    if (((args[1])[1]) == 'object)
        show = ['method, 'variable];
    else if ((args[1])[5])
        show = [(args[1])[1], (args[1])[5]];
    else
        show = [(args[1])[1]];
    if ((i = "c?hop" in ((args[3]).slice(1))))
        chop = ((args[3])[i])[3];
    else
        chop = 1;
    if ((args[1])[4])
        f = (args[1])[4];
    else
        f = .get_setting("match-default", $programmer);
    match = .get_setting("match-with", $programmer);
    obj = (args[1])[3];
    if (type(obj) == 'frob)
        return ["The target object was a frob.  Please use @exam instead."];
    .tell([((("Object:  " + obj) + " [") + ((obj.size()).to_english())) + " bytes]", "Parents: " + ((obj.parents()).join(", "))]);
    if ('method in show) {
        if (!(obj.has_flag('methods, this())))
            .tell("  ** No permission to list methods **");
        else
            .tell(._show__methods(obj, f, match, chop));
    }
    if ('variable in show) {
        if (!(obj.has_flag('variables, this())))
            .tell("  ** No permission to show variables **");
        else
            .tell(._show__variables(obj, f, match, chop));
    }
    .tell("---");
};

protected method ._move_method() {
    arg remove, fobj, fname, tobj, tname, comment;
    var code, line, result, access, flags;
    
    if ((fobj == tobj) && remove) {
        if ((| tobj.find_method(tname) |) == tobj)
            tobj.del_method(tname);
        return (> fobj.rename_method(fname, tname) <);
    }
    code = (> fobj.list_method(fname) <);
    flags = (> fobj.method_flags(fname) <);
    access = (> fobj.method_access(fname) <);
    if (comment) {
        line = (((((((("// $#" + (remove ? "Moved" : "Copied")) + " ") + ($time.format("%d %b %y %H:%M"))) + " from ") + fobj) + ".") + fname) + "() by ") + this();
        if (type(comment) == 'string)
            line += ": " + comment;
        code += [line];
    }
    if ((> tobj.add_method(code, tname) <))
        throw(~compile, "Error encountered upon moving method!");
    (> tobj.set_method_flags(tname, flags) <);
    (> tobj.set_method_access(tname, access) <);
    if (remove)
        (> fobj.del_method(fname) <);
};

protected method .del_method_cmd() {
    arg cmdstr, cmd, objref;
    var name, obj;
    
    (> .perms(caller(), 'command) <);
    if (!(objref[4]))
        return .tell(("No method specified to delete from " + (objref[3])) + ".");
    if (!(| (name = tosym(objref[4])) |))
        return .tell(("Invalid method name \"" + (objref[4])) + "\".");
    catch any {
        (> (objref[3]).del_method(name) <);
        .tell(((("Method " + (objref[3])) + ".") + name) + "() deleted.");
    } with {
        if (error() == ~methodnf)
            .tell(((("Method " + (objref[3])) + ".") + name) + "() does not exist.");
        else
            .tell((traceback()[1])[2]);
    }
};

protected method .move_cmd() {
    arg cmdstr, cmd, args;
    var src, dest, comment, i, how, ref, opts;
    
    (> .perms(caller(), 'command) <);
    
    // is this actually @copy|@cp?
    how = match_begin(cmd, "@c") ? 'copy : 'move;
    
    // handle args
    [src, args, opts] = args;
    if (args && ((args[1]) == "to"))
        args = delete(args, 1);
    if (!args)
        throw(~stop, ("You must " + how) + " to something.");
    catch ~objnf, ~namenf, ~match
        dest = $parse_lib.ref(join(args));
    with
        throw(~stop, (traceback()[1])[2]);
    
    // drop back to $builder.move_cmd if it is just an object
    if ((src[1]) == 'object) {
        if (how == 'copy)
            throw(~stop, "You cannot copy objects!");
        return (> pass(cmdstr, cmd, [src, dest, opts]) <);
    }
    
    // options
    if ((i = "c?omment" in (opts.slice(1))))
        comment = ((opts[i])[4]) || ((opts[i])[3]);
    else
        comment = 1;
    
    // twiddle with things a little
    if ((dest[1]) == 'object)
        dest = [src[1], dest[2], dest[3], src[4], 0];
    
    // oops, crossed wires
    if ((src[1]) != (dest[1])) {
        ref = (tostr(src[1]).prefix_a_or_an()) + " to ";
        ref += tostr(dest[1]).prefix_a_or_an();
        throw(~stop, (("You cannot " + how) + " ") + ref);
    }
    if (!(src[4]))
        return ("Invalid " + (src[1])) + " reference, no name specified.";
    if (!(dest[4]))
        dest = replace(dest, 4, src[4]);
    if (((src[3]) == (dest[3])) && ((src[4]) == (dest[4])))
        return ((("Why do you want to " + how) + " the ") + (src[1])) + " to itself?";
    catch ~symbol {
        src = replace(src, 4, (src[4]).to_symbol());
        dest = replace(dest, 4, (dest[4]).to_symbol());
    } with {
        return ("You cannot specify wildcards in the " + (src[1])) + " name.";
    }
    if ((how == 'move) && (!((src[3]).is_writable_by(this()))))
        return ("You do not have permission to move from " + (src[3])) + ".";
    if (!((dest[3]).is_writable_by(this())))
        return ((("You do not have permission to " + how) + " to ") + (dest[3])) + ".";
    catch any
        (> .(tosym("_move_" + (src[1])))(how == 'move, src[3], src[4], dest[3], dest[4], comment) <);
    with
        return (traceback()[1])[2];
    return ((((("You " + how) + " ") + ($parse_lib.buildref(@src))) + " to ") + ($parse_lib.buildref(@dest))) + ".";
};

protected method .list_cmd() {
    arg cmdstr, cmd, args;
    var i, pattern, ref, methods, s, def, method, opts, str, m, d, out, type;
    
    (> .perms(caller(), 'command) <);
    if ((opts = .get_setting("@list-options", $programmer))) {
        opts = (> $parse_lib.opt(opts, "n?umbers", "t?extdump") <);
        opts = union(args[3], opts[2]);
    } else {
        opts = args[3];
    }
    if ((i = (| "n?umbers" in (opts.slice(1)) |)) && ((opts[i])[3]))
        type = 'numbered;
    else if ((i = (| "t?extdump" in (opts.slice(1)) |)) && ((opts[i])[3]))
        type = 'textdump;
    else
        type = 'normal;
    ref = args[1];
    if ((ref[1]) == 'variable)
        return ((("The reference " + (ref[3])) + ",") + ((ref[4]) || "")) + " is not for a method.";
    if ((ref[1]) == 'object)
        return ("The reference " + (ref[3])) + " is not for a method.";
    if (!((ref[2]).has_flag('methods)))
        return .tell(("You don't have permission to find methods on " + (ref[2])) + ".");
    if (!((ref[2]).has_flag('code)))
        return .tell(("You don't have permission to list methods on " + (ref[2])) + ".");
    def = (| (ref[2]).find_method(tosym(ref[4])) |);
    if (def) {
        pattern = ref[4];
        methods = [tosym(ref[4])];
    } else {
        if (ref[4])
            pattern = ref[4];
        else
            pattern = .get_setting("match-default", $programmer);
        def = ref[3];
        m = .get_setting("match-with", $programmer);
        methods = [];
        for method in (def.methods()) {
            if (tostr(method).(m)(pattern) != 0)
                methods += [method];
        }
        if (!methods)
            return .tell((("No method found matching " + def) + ".") + pattern);
    }
    cmd = .get_setting("@program-options", $programmer);
    out = [];
    for method in (methods) {
        .ptell(.format_method(def, method, type, cmd), #[]);
        pause();
    }
};

protected method .id_cmd() {
    arg cmdstr, cmd, obj;
    
    (> .perms(caller(), 'command) <);
    obj = (> .match_env_nice(obj) <);
    if (type(obj) == 'frob)
        return ["The target object was a frob."];
    .tell((((((((obj.namef('xref)) + " ") + ($object_lib.see_perms(obj))) + " ") + toliteral(obj.parents())) + " ") + tostr(obj.size())) + " bytes");
};

protected method .dump_cmd() {
    arg cmdstr, cmd, args;
    var opts, objs, o, obj, i, tdfmt, meths, vars, header, bad_objs;
    
    (> .perms(caller(), 'command) <);
    opts = args[2];
    args = args[1];
    o = opts.slice(1);
    (i = "t?extdump" in o) && (tdfmt = (opts[i])[3]);
    (i = "m?ethods" in o) ? (meths = (opts[i])[3]) : (meths = 1);
    (i = "v?ariables" in o) ? (vars = (opts[i])[3]) : (vars = 1);
    (i = "h?eader" in o) ? (header = (opts[i])[3]) : (header = 1);
    if ((!meths) && (!vars))
        return "Perhaps you will want to dump methods and/or vars next time?";
    objs = [];
    bad_objs = [];
    for o in (args) {
        catch any {
            obj = (> .match_env_nice(o) <);
            if (type(obj) == 'frob)
                bad_objs += [o];
            else
                objs += [obj];
        } with {
            .tell((traceback()[1])[2]);
        }
    }
    if (!objs) {
        if ((bad_objs.length()) > 0)
            .tell("NOTE:  these objects were frobs and couldn't be @dump'd: " + (bad_objs.to_english()));
        return "Dump nothing?";
    }
    if (tdfmt)
        .dump_fmt_textdump(objs, meths, vars, header);
    else
        .dump_fmt_commands(objs, meths, vars, header);
    if ((bad_objs.length()) > 0)
        .tell("NOTE:  these objects were frobs and couldn't be @dump'd: " + (bad_objs.to_english()));
};

protected method ._show__methods() {
    arg obj, f, match, chop;
    var methods, types, m, t, out;
    
    types = #[];
    for m in (obj.methods()) {
        if (tostr(m).(match)(f) != 0)
            types = types.add_elem(obj.method_access(m), ((("." + m) + "(") + ((obj.method_info(m))[1])) + ")");
    }
    
    // hard-listing the types guarantee's their order
    out = [];
    for t in (['root, 'driver, 'public, 'protected, 'private, 'frob]) {
        if (!(types.contains(t)))
            continue;
        out += [(((tostr(t).capitalize()) + " methods matching \"") + f) + "\":"];
        for m in (types[t])
            out += ["  " + m];
    }
    return out;
};

protected method .descendants_cmd() {
    arg cmdstr, cmd, args;
    var obj, max, line, opts, i, r, not, only, f;
    
    (> .perms(caller(), 'command) <);
    
    // parse args
    [obj, args, opts] = args;
    if ((obj[1]) != 'object)
        return "Object reference must simply be a dbref.";
    if ((obj[2]) != (obj[3]))
        .tell(("Ignoring specified definer " + (obj[2])) + ".");
    obj = obj[3];
    only = (not = []);
    max = 1;
    if ((i = "o?nly" in (opts.slice(1)))) {
        only = map f in ((((opts[i])[4]).split(" *, *")).nonzero()) to (f.to_symbol());
        opts = delete(opts, i);
    }
    if ((i = "n?ot" in (opts.slice(1)))) {
        not = map f in ((((opts[i])[4]).split(" *, *")).nonzero()) to (f.to_symbol());
        opts = delete(opts, i);
    }
    if ((i = "r?edundant" in (opts.slice(1)))) {
        r = (opts[i])[3];
        opts = delete(opts, i);
    }
    if ((i = "a?ll" in (opts.slice(1)))) {
        if ((opts[i])[3])
            max = 0;
        opts = delete(opts, i);
    }
    if (opts) {
        if ((max = find i in (opts) where ((i[2]).is_numeric()))) {
            max = toint((opts[max])[2]);
            if (max < 1)
                return "Maximum levels must be greater than zero.";
        }
    }
    
    // do it
    line = ("-- Descendants of " + obj) + " [";
    .tell((line + (((obj.parents()).mmap('objname)).to_english())) + "]");
    if (max) {
        line = (max + " level") + ((max > 1) ? "s" : "");
        max++;
    } else {
        line = "all levels";
    }
    if (r)
        line += ", redundant entries";
    .tell("-- " + line);
    if (only)
        .tell("-- only objects with flag(s): +" + (only.join(" AND +")));
    if (not)
        .tell("-- not objects with flag(s): +" + (not.join(" OR +")));
    return [obj.format_descendants("", #[], 0, max, only, not, r), "--"];
};

protected method .chparents_cmd() {
    arg cmdstr, cmd, args;
    var syn, p, x, obj, parents, match;
    
    (> .perms(caller(), 'command) <);
    syn = ("Syntax: `" + cmd) + " <child> [to] <parent>, <parent>, ...`";
    if ((match = match_template(args, "* to *"))) {
        obj = match[1];
        parents = match[3];
    } else if ((args = explode(args))) {
        if (listlen(args) == 1)
            return syn;
        obj = args[1];
        parents = sublist(args, 2).join();
    } else {
        return syn;
    }
    obj = (> .match_env_nice(obj) <);
    if (("," in parents) || (" and " in parents))
        parents = parents.explode_english_list();
    else
        parents = parents.explode();
    if (!parents)
        return "No parents to change to.";
    parents = map p in (parents) to ((> .match_env_nice(p) <));
    catch any {
        obj.chparents(@parents);
        return ((("Changed parents for " + obj) + " to ") + (parents.to_english())) + ".";
    } with {
        return (traceback()[1])[2];
    }
};

protected method ._display_methods() {
    arg obj, info, chop, f;
    var type, types, line, out, m, len;
    
    len = .linelen();
    out = [];
    for type in (info.keys()) {
        line = (tostr(type).capitalize()) + " Methods";
        if (f)
            line += (" matching \"" + f) + "\"";
        out += [line + ":"];
        for m in (info[type]) {
            line = strfmt("%5l %4r %l.%l(%l)", $object_lib.parse_method_flags(m[8]), m[6], ((m[1]) != obj) ? (m[1]) : "", m[2], m[3]);
            if (chop)
                line = line.chop(len);
            out += [line];
            refresh();
        }
    }
    return out;
};

protected method .eval_subs() {
    arg code;
    var out, m, sub, tok;
    
    // HORRIBLY inefficient         
    tok = ("#@#ESCQUOTE-" + time()) + "#@#";
    code = strsub(code, "\\\"", tok);
    out = "";
    while ((m = match_pattern(code, "*\"*\"*"))) {
        out += (((> ._eval_subs(m[1]) <) + "\"") + (m[2])) + "\"";
        code = m[3];
    }
    if (code)
        out += (> ._eval_subs(code) <);
    return strsub(out, tok, "\\\"");
};

public method .eval_prefix() {
    return dict_union(#[["me", ("me = " + this()) + ";"], ["here", ("here = " + (.location())) + ";"]], eval_prefix || #[]);
};

protected method .del_command_cmd() {
    arg cmdstr, cmd, args;
    var ref, t, objref;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    if (listlen(args) > 2) {
        if ((args[2]) == "from")
            args = delete(args, 2);
        t = delete(args, listlen(args)).join();
        objref = args.last();
    } else if (listlen(args) == 2) {
        t = args[1];
        objref = args[2];
    } else {
        return ("Syntax: `" + cmd) + " \"template\" [from] <objref>";
    }
    catch any {
        ref = (> $parse_lib.ref(objref) <);
        if ((ref[1]) != 'method)
            return ("The reference " + objref) + " is not for a method.";
        if ((!(ref[4])) || (!((ref[4]).valid_ident())))
            return ((("Invalid method name " + (ref[3])) + ".") + (ref[4])) + "().";
        if (!(> (ref[2]).del_command(t, tosym(ref[4])) <))
            return strfmt("Command %d is not defined on %s.", t, ref[2]);
    } with {
        return (traceback()[1])[2];
    }
    return strfmt("Command %d removed from %s.%s()", t, ref[3], ref[4]);
};

protected method .which_cmd() {
    arg cmdstr, command, str;
    var l, out, d, m, p, c, cache, cmds, cmd, matches, def;
    
    (> .perms(caller(), 'command) <);
    if (!str)
        return ("Syntax: `" + command) + " <partial or full template>`";
    str = str.word(1);
    
    // local commands
    matches = #[];
    for p in ([this()] + (.command_modules())) {
        for def in (p.all_local_commands()) {
            for cmd in (def[2]) {
                for c in ((cmd[1]).explode("|")) {
                    if (str in (c.strip("?"))) {
                        for m in (cmd[2])
                            matches = matches.setadd_elem(m[3], [def[1], m[4], 'local]);
                    }
                }
                refresh();
            }
            refresh();
        }
        refresh();
    }
    
    // remote commands
    cache = #[];
    for cmds in (dict_values($remote_cache.command_cache())) {
        for def in (cmds) {
            if (!dict_contains(cache, def[1])) {
                for c in ((def[1]).explode("|")) {
                    if (str in (c.strip("?"))) {
                        for m in ((def[2]).command_info('remote, def[1]))
                            matches = matches.setadd_elem(m[3], [def[2], m[4], 'remote]);
                    }
                }
                cache = dict_add(cache, def[1], 1);
            }
        }
        refresh();
    }
    
    // return results
    if (!matches)
        return ("No commands found matching the template \"" + str) + "\".";
    l = ((.linelen()) - 2) / 2;
    out = [("Commands matching the template \"" + str) + "\":  (* == remote command)"];
    for c in (matches) {
        cmd = ("\"" + (c[1])) + "\"";
        for def in (c[2]) {
            d = ((def[1]) + ".") + (def[2]);
            if ((def[2]) == 'remote)
                p = "* ";
            else
                p = "  ";
            if (strlen(cmd) > (l - 2))
                out += [p + cmd, "          " + d];
            else
                out += [(p + strfmt("%*l ", l, cmd)) + d];
        }
        refresh();
    }
    return out + ["---"];
};

protected method .add_command_cmd() {
    arg cmdstr, cmd, str;
    var ref, t, args, objref;
    
    (> .perms(caller(), 'command) <);
    args = str.explode_quoted();
    if (listlen(args) > 2) {
        if ((args[2]) in ["to", "for"])
            args = delete(args, 2);
        t = delete(args, listlen(args)).join();
        objref = args.last();
    } else if (listlen(args) == 2) {
        t = args[1];
        objref = args[2];
    } else {
        return ("Syntax: `" + cmd) + " \"template\" [to|for] <objref>";
    }
    catch any {
        ref = (> $parse_lib.ref(objref) <);
        if ((ref[1]) != 'method)
            return ("The reference " + objref) + " is not for a method.";
        if ((!(ref[4])) || (!((ref[4]).valid_ident())))
            return ((("Invalid method name " + (ref[3])) + ".") + (ref[4])) + "().";
        (> (ref[2]).add_command(t, tosym(ref[4])) <);
    } with {
        return (traceback()[1])[2];
    }
    return strfmt("Command %d added to %s.%s()", t, ref[3], ref[4]);
};

protected method .local_edit_cmd() {
    arg cmdstr, cmd, args;
    var ref, edited, code, def, meth, i;
    
    (> .perms(caller(), 'command) <);
    ref = args[1];
    if ((ref[1]) == 'variable)
        return ((("The reference " + (ref[3])) + ",") + ((ref[4]) || "")) + " is not for a method.";
    if ((ref[1]) == 'object)
        return ("The reference " + (ref[3])) + " is not for a method.";
    if ((ref[3]) && (!((ref[3]).is_writable_by(this()))))
        return "You cannot program on that object.";
    if ((!(ref[4])) || (!((ref[4]).valid_ident())))
        return ("The method name '" + (ref[4])) + "' is not acceptable.";
    meth = tosym(ref[4]);
    catch ~methodnf {
        def = (ref[3]).find_method(meth);
        if (!(def.is_writable_by(this())))
            return ("You cannot program on " + def) + ".";
    } with {
        return ((("Method " + (ref[3])) + ".") + meth) + "() not found.";
    }
    if ((i = "e?dited" in ((args[3]).slice(1)))) {
        if (!(((args[3])[i])[3])) {
            if (!($sys.is_admin(this())))
                return "Only admins can shut off edited comments.";
        } else {
            edited = 1;
        }
    } else {
        edited = 1;
    }
    if (edited) {
        edited = (("// $#Edited: " + ($time.format("%d %b %y %H:%M"))) + " ") + this();
        if (i && (((args[3])[i])[4]))
            edited += ": " + (((args[3])[i])[4]);
    }
    catch ~perm
        code = def.list_method(meth);
    with
        return (traceback()[1])[2];
    return .ptell(([(((((("#$# edit name: " + def) + ".") + meth) + " upload: @program ") + def) + ".") + meth] + (code.prefix("    "))) + ["."], #[['nomod, 1]]);
};

protected method .display_cmd() {
    arg cmdstr, cmd, args;
    var opts, slice, what, match, i, chop, f, gen, def, obj, out;
    
    (> .perms(caller(), 'command) <);
    opts = args[3];
    args = args[1];
    chop = 1;
    slice = opts.slice(1);
    if ((i = "c?hop" in slice) && (!((opts[i])[3])))
        chop = 0;
    else
        chop = .linelen();
    def = args[3];
    if ((i = "g?enerations" in slice)) {
        gen = (opts[i])[4];
        if (gen.is_numeric())
            gen = ['generations, toint(gen)];
        else if (gen)
            gen = ['ancestors_descending, (> .match_env_nice(gen) <)];
        else
            gen = ['ancestry, def];
        def = 0;
    } else {
        gen = ['generations, 1];
    }
    what = [args[1]] + ((| args[5] |) ? [args[5]] : []);
    obj = args[2];
    if (type(obj) == 'frob)
        return ["The target object was a frob.  Please use @exam instead."];
    out = $object_lib.format_object(obj, chop);
    if (!(args[4]))
        f = .get_setting("match-default", $programmer);
    else
        f = args[4];
    match = .get_setting("match-with", $programmer);
    catch ~perm {
        if ('method in what)
            out += ._display_methods(obj, obj.list_methods(gen, def, f, match), chop, f);
    } with {
        out += ["  ** No permission to list methods **"];
    }
    catch ~perm {
        if ('variable in what)
            out += ._display_variables(obj, obj.variable_info(gen, def, f, match), chop, f);
    } with {
        out += ["  ** No permission to show variables **"];
    }
    return out + ["---"];
};

protected method .eval_offset() {
    return eval_offset || #[['mtime, 0], ['time, 0], ['ticks, 0]];
};

protected method .del_var_cmd() {
    arg cmdstr, cmd, ref;
    
    (> .perms(caller(), 'command) <);
    if (((ref[1]) != 'variable) || (!(ref[4])))
        return "Invalid obj,variable reference.";
    catch ~symbol
        (ref[3]).del_var(tosym(ref[4]));
    with
        return (traceback()[1])[2];
    return ((("Object variable " + (ref[3])) + ",") + (ref[4])) + " deleted.";
};

protected method .add_var_cmd() {
    arg cmdstr, cmd, args;
    var ref, value, syn;
    
    (> .perms(caller(), 'command) <);
    syn = "@av <object>,<variable>[=<value>]";
    if (!args)
        (> .tell_error(syn, "Invalid obj,variable reference.") <);
    catch any
        ref = (> $parse_lib.ref(args.word(1)) <);
    with
        (> .tell_error(syn, (traceback()[1])[2]) <);
    if (((ref[1]) != 'variable) || (!(ref[4])))
        (> .tell_error(syn, "Invalid obj,variable reference.") <);
    if (" " in args) {
        args = substr(args, (" " in args) + 1);
        if (args && ((args[1]) == "="))
            args = substr(args, (" " in args) + 1);
        if (args) {
            value = .eval([("return " + args) + ";"]);
            if ((value[1]) == 'errors)
                (> .tell_error(syn, ("Unable to parse value \"" + args) + "\".") <);
            value = value[2];
        } else {
            value = 0;
        }
    } else {
        value = 0;
    }
    catch any {
        (> (ref[3]).add_var(tosym(ref[4]), value) <);
    } with {
        if (error() in [~varexists, ~symbol])
            return (traceback()[1])[2];
        rethrow(error());
    }
    return ((((("Object variable " + (ref[3])) + ",") + (ref[4])) + " added with value ") + value) + ".";
};

protected method .add_parent_cmd() {
    arg cmdstr, cmd, args;
    var syn, obj, parent;
    
    (> .perms(caller(), 'command) <);
    args = args.explode();
    if ((listlen(args) > 2) && ((args[2]) == "to"))
        args = delete(args, 2);
    if (listlen(args) != 2)
        return ("Syntax: `" + cmd) + " <parent> [to] <object>`";
    parent = (> .match_env_nice(args[1]) <);
    obj = (> .match_env_nice(args[2]) <);
    catch any {
        (> obj.add_parent(parent) <);
        return ((("Added parent to " + (obj.namef('ref))) + ", parents: ") + ((obj.parents()).to_english())) + ".";
    } with {
        return (traceback()[1])[2];
    }
};

protected method .del_parent_cmd() {
    arg cmdstr, cmd, args;
    var syn, obj, parent;
    
    (> .perms(caller(), 'command) <);
    syn = cmd + " <parent> [from] <object>";
    args = args.explode();
    if ((listlen(args) > 2) && ((args[2]) == "from"))
        args = delete(args, 2);
    if (listlen(args) != 2)
        (> .tell_error(syn) <);
    if (!args)
        (> .tell_error(syn) <);
    parent = (> .match_env_nice(args[1]) <);
    obj = (> .match_env_nice(args[2]) <);
    catch any {
        (> obj.del_parent(parent) <);
        return ((("Deleted parent from " + (obj.namef('ref))) + ", parents: ") + ((obj.parents()).to_english())) + ".";
    } with {
        (> .tell_error("", (traceback()[1])[2]) <);
    }
};

protected method .trace_method_cmd() {
    arg cmdstr, cmd, ref;
    var method, current, trace, syn, minfo, line, anc, len, out, m;
    
    (> .perms(caller(), 'command) <);
    if ((ref[1]) != 'method)
        return toliteral(cmd) + " requires a full method reference.";
    catch any {
        method = (> tosym(ref[4]) <);
        current = (> (ref[2]).find_method(method) <);
        trace = [];
        while (current) {
            trace += [current];
            current = (| (ref[2]).find_next_method(method, current) |);
        }
    } with {
        if (error() == ~symbol)
            return ("Invalid method name \"" + (ref[4])) + "\".";
        return (traceback()[1])[2];
    }
    .tell(((("Method trace of " + (ref[2])) + ".") + (ref[4])) + "():");
    len = .linelen();
    out = [];
    for anc in (trace.reverse()) {
        m = anc.method_info(method);
        out += [strfmt("%5l %4r %l.%l(%l)", $object_lib.parse_method_flags(m[6]), m[4], anc, method, m[1])];
    }
    return out;
};

public method .evaluate() {
    arg str, obj, definer, @mode;
    var start, end, time, ticks, mtime, times1, times2, method, errs, trace, result, is_error;
    
    mode = mode ? (mode[1]) : 0;
    (> .perms(caller(), $programmer) <);
    method = tosym("tmp_eval_" + time());
    if ((errs = (> definer.add_method([str], method, 'evalonly) <))) {
        if (mode)
            return [[0, 0, 0], ['errors, errs, 0, 0], []];
        else
            return [[0, 0, 0], ['errors, errs, 0, 0]];
    }
    if (mode == 'opcodes) {
        times1 = [tick(), time(), mtime()];
        result = obj.method_bytecode(method);
        times2 = [mtime(), time(), tick()];
    } else {
        catch any {
            if (mode in ['trace, 'profile])
                debug_callers(1);
            else if (mode == 'debug)
                debug_callers(2);
            times1 = [tick(), time(), mtime()];
            result = (> obj.(method)() <);
            times2 = [mtime(), time(), tick()];
            trace = call_trace();
            debug_callers(0);
        } with {
            times2 = [mtime(), time(), tick()];
            result = traceback();
            is_error = 1;
            debug_callers(0);
        }
    }
    (| definer.del_method(method) |);
    
    // figure up the actual times
    time = (times2[2]) - (times1[2]);
    ticks = (times2[3]) - (times1[1]);
    if ((times2[1]) > (times1[3]))
        mtime = (times2[1]) - (times1[3]);
    else if (time)
        mtime = ((time * 1000000) + (1000000 - (times1[3]))) + (times2[1]);
    else
        mtime = (1000000 - (times2[1])) + (times1[3]);
    
    // offset it?
    if (eval_offset && (mode != 'no_offset)) {
        ticks -= eval_offset[1];
        time -= eval_offset[2];
        mtime -= eval_offset[3];
    }
    if (trace)
        return [[ticks, time, abs(mtime)], ['result, result], $code_lib.generate_debug_listing(trace, mode)];
    return [[ticks, time, abs(mtime)], [is_error ? 'traceback : 'result, result]];
};

protected method ._list_method() {
    arg obj, method, @args;
    var code, opt, flags, f;
    
    [(args ?= 0), (opt ?= "")] = args;
    code = obj.list_method(method);
    flags = obj.method_flags(method);
    if (args) {
        code = code.numbered_text();
        return ([(((((("-- " + (obj.method_access(method))) + " method ") + obj) + ".") + method) + "()") + (flags ? (": " + (flags.join(", "))) : "")] + code) + ["--"];
    } else {
        return ([$object_lib.format_method_header(obj, method, opt, flags, obj.method_access(method))] + (code.prefix("  "))) + ["."];
    }
};

protected method ._display_variables() {
    arg obj, info, chop, f;
    var line, i, len, out, fmt;
    
    len = .linelen();
    line = "Object Variables";
    if (f)
        line += (" matching \"" + f) + "\"";
    out = [line];
    for i in (info.reverse()) {
        line = strfmt("  %s,%s: %d", ((i[1]) != obj) ? (i[1]) : "", i[2], i[3]);
        if (chop)
            line = line.chop(len);
        out += [line];
        refresh();
    }
    return out;
};

public method .parse_methodcmd_options() {
    arg syntax, args, @more;
    var o, opt, opts, out, r, l;
    
    [(o ?= []), (opts ?= [])] = more;
    o += [["pub?lic"], ["r?oot"], ["dr?iver"], ["pri?vate"], ["pro?tected"], ["no?override"], ["s?yncronized"], ["l?ocked"], ["na?tive"]];
    opts = dict_union(#[['exists, 0], ['ignore, 0], ['mflags, []], ['mstate, 'public], ['error, 0]], opts);
    args = $parse_lib.getopt(args, o);
    if (!(args[1])) {
        out = [];
        for opt in (o)
            out += ["  +|-" + (opt[1])];
        (> .tell_error(syntax, ["Valid options:"] + (out.lcolumnize())) <);
    }
    r = (| $parse_lib.ref((args[1]).join()) |);
    if (!r) {
        opts = opts.add('error, "Invalid <object>.<method> reference.");
        opts = opts.add('ignore, 1);
    }
    if (!((r[4]).valid_ident())) {
        opts = opts.add('error, (((r[2]) + ".") + tostr(r[4])) + "() is not a valid method reference.");
        opts = opts.add('ignore, 1);
    }
    r = replace(r, 4, tosym(r[4]));
    if ((r[2]) && (!((r[2]).is_writable_by(this())))) {
        opts = opts.add('error, ("You cannot program " + (r[2])) + ".");
        opts = opts.add('ignore, 1);
    }
    if ((| (r[2]).find_method(r[4]) |) == (r[2])) {
        opts = opts.add('mflags, (r[2]).method_flags(r[4]));
        opts = opts.add('mstate, (r[2]).method_access(r[4]));
        opts = opts.add('exists, 1);
    }
    opts = opts.add('object, r[2]);
    opts = opts.add('method, r[4]);
    for opt in (args[2]) {
        switch (opt[1]) {
            case "pub?lic", "r?oot", "dr?iver", "pri?vate", "pro?tected":
                opts = opts.add('mstate, (opt[1]).to_symbol());
            case "no?override", "s?yncronized":
                opts = opts.add('mflags, (opts['mflags]).setadd((opt[1]).to_symbol()));
            case "l?ocked":
                .tell("You cannot set the locked flag on a method.");
            case "n?ative":
                .tell("You cannot set the native flag on a method.");
            default:
                if (!(opt[1])) {
                    .tell(("Unknown option: \"" + (opt[2])) + "\"");
                    .tell("Valid options: " + ((o.slice(1)).to_english()));
                    continue;
                }
                opts = opts.add((opt[1]).to_symbol(), [opt[3], opt[4]]);
        }
    }
    return opts;
};

public method .clear_eval() {
    (| clear_var('eval_offset) |);
};

protected method .add_shortcut_cmd() {
    arg cmdstr, cmd, args;
    var ref, syn;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    syn = cmd + " \"<shortcut>\" [to] \"<command>\" [on] \"<object>\"";
    if ((listlen(args) == 5) && (((args[2]) == "to") && ((args[4]) == "on")))
        args = [args[1], args[3], args[5]];
    if (listlen(args) != 3)
        return ("Syntax: `" + syn) + "`";
    ref = (> $parse_lib.ref(args[3]) <);
    if (((ref[1]) != 'method) || ((!(ref[4])) || (!(| tosym(ref[4]) |))))
        return ("Invalid method reference reference \"" + (args[3])) + "\".";
    catch any
        (> (ref[2]).add_shortcut(args[1], args[2], tosym(ref[4])) <);
    with
        return (traceback()[1])[2];
    return strfmt("Added shortcut %d to command %d on %s.%s().", args[1], args[2], ref[2], ref[4]);
};

protected method .new_editor_session() {
    arg ref, opts, type;
    var def, code, name, errs, data;
    
    switch (ref[1]) {
        case 'variable:
            code = ("return " + (ref[4])) + ";";
            def = ((ref[2]) + ",") + (ref[4]);
            name = (ref[4]).to_symbol();
            if (!(name in ((ref[2]).variables())))
                return [("The object variable " + def) + " does not exist.", ("You have to '@add-variable " + def) + "' before you can edit it."];
            name = tosym("tmp_edit_" + time());
            catch any {
                if ((errs = (ref[2]).add_method([code], name, 'evalonly)))
                    return [(("Unable to retrieve " + def) + ": ") + (errs.join())];
            } with {
                return [(("Unable to retrieve " + def) + ": ") + (errs.join())];
            }
            catch any {
                data = (ref[2]).(name)();
            } with {
                (| (ref[2]).del_method(name) |);
                return [(("Unable to retrieve " + def) + ": ") + ((traceback()[1])[2])];
            }
            (| (ref[2]).del_method(name) |);
            data = $data_lib.unparse_indent(data);
            (> .invoke_editor(this(), '_edit_variable_callback, data, [ref[2], ref[4]]) <);
        case 'method:
            name = (| tosym(ref[4]) |);
            if (!name)
                return [("Invalid method name ." + (ref[4])) + "()"];
            def = (| (ref[2]).find_method(name) |);
            if (!def) {
                def = ref[3];
                code = [];
            } else {
                code = def.list_method(name);
            }
            (> .invoke_editor(this(), '_edit_method_callback, code, [def, tosym(ref[4])]) <);
        default:
            return (> pass(ref, opts, type) <);
    }
    if (.active_editor())
        return [("Editing " + ((.active_editor()).session_name())) + ".", "Type 'help' to list available commands."];
    else
        return ["Remote editing invoked."];
};

protected method ._edit_method_callback() {
    arg code, client_data;
    var errors, edited, object, method, warns, sender;
    
    (> .perms(caller(), $editor_reference) <);
    [object, method] = client_data;
    sender = this();
    code += [(("// $#Edited: " + ($time.format("%d %b %y %H:%M"))) + " ") + sender];
    errors = (> object.add_method(code, method) <);
    if (errors)
        return ['failure, errors];
    warns = (> $code_lib.verify_code(code, method, 1) <);
    return ['success, [warns + ["Method compiled."]]];
};

protected method ._show__variables() {
    arg obj, f, match, chop;
    var parent, out, v, line, len;
    
    out = [];
    len = .linelen();
    for parent in (obj.data()) {
        if (valid(parent[1])) {
            out += [(((parent[1]) + " variables matching \"") + f) + "\":"];
            if ((parent[1]).has_flag('variables, this())) {
                for v in (parent[2]) {
                    if (tostr(v[1]).(match)(f) == 0)
                        continue;
                    line = (("  " + (v[1])) + ": ") + toliteral(v[2]);
                    if (chop)
                        line = line.chop(len);
                    out += [line];
                }
            } else {
                out += ["  ** Permission Denied **"];
            }
        } else {
            out += [($object_lib.get_name(parent[1])) + " Variables:"];
            for v in (parent[2]) {
                if (tostr(v[1]).(match)(f) == 0)
                    continue;
                line = (("  " + (v[1])) + ": ") + toliteral(v[2]);
                if (chop)
                    line = line.chop(len);
                out += [line];
            }
        }
        refresh();
    }
    return out;
};

public method ._move_variable() {
    arg remove, fobj, fname, tobj, tname, comment;
    var value, line, result, tmp;
    
    value = (> fobj.eval([("return " + fname) + ";"]) <);
    if ((value[1]) != 'result)
        throw(~eval, "An error was encountered upon evaluation.");
    value = value[2];
    (> tobj.add_var(tname, value) <);
    if (remove)
        (> fobj.del_var(fname) <);
};

protected method .del_shortcut_cmd() {
    arg cmdstr, cmd, args;
    var ref, syn;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    if ((listlen(args) == 3) && ((args[2]) == "from"))
        args = delete(args, 2);
    if (listlen(args) != 2)
        return ("Syntax: `" + cmd) + " \"<shortcut>\" [from] <objref>";
    ref = (> $parse_lib.ref(args[2]) <);
    if (((ref[1]) != 'method) || ((!(ref[4])) || (!(| tosym(ref[4]) |))))
        return ("Invalid method reference reference \"" + (args[2])) + "\".";
    catch any
        (> (ref[2]).del_shortcut(args[1]) <);
    with
        return (traceback()[1])[2];
    return strfmt("Deleted shortcut %d from %s.%s().", args[1], ref[2], ref[4]);
};

protected method .grep_cmd() {
    arg cmdstr, cmd, args;
    var more, regexp, from, syn, opts, d, f, l, r, rep, slice, objs, obj, out;
    
    (> .perms(caller(), 'command) <);
    [more, opts] = args;
    if ((more.length()) < 2)
        return ("=> Syntax: `" + cmd) + " [options] <regexp> <object> <object>..";
    regexp = more[1];
    more = more.subrange(2);
    
    // handle the options
    slice = opts.slice(1);
    if ((r = (| "r?eplace-with" in slice |))) {
        rep = (opts[r])[4];
        r = (opts[r])[3];
    }
    if ((d = (| "d?escend" in ((args[2]).slice(1)) |)))
        d = (opts[d])[3];
    if ((l = (| "l?ist" in ((args[2]).slice(1)) |)))
        l = (opts[l])[3];
    if ((f = (| "f?ull" in ((args[2]).slice(1)) |)))
        f = (opts[f])[3];
    
    // now we check for conflicting or incorrect options..
    if (d && (!(.is($admin))))
        return "Only administrators may use the +descend option, talk to one.";
    if (d && ((more.length()) > 1))
        return "+descend can only be used with a single object as the target.";
    if (r && (f || l))
        return "+replace-with option cannot be used with +full or +list.";
    if (f && l)
        return "+full cannot be used with +list.";
    
    // the pause() flushes so we can see the 'Searching for ..'
    // Do this now because .descendants() can lag
    .tell(("Searching for \"" + regexp) + "\"...");
    pause();
    
    // figure out our targets
    if (d) {
        obj = (> .match_env_nice(more[1]) <);
        objs = [obj, @obj.descendants()];
    } else {
        objs = [];
        for obj in (more)
            objs += [(> .match_env_nice(obj) <)];
    }
    
    // verify its a valid regexp
    catch ~regexp
        match_regexp("", regexp);
    with
        return "Invalid regular expression: " + ((traceback()[1])[2]);
    
    // call the right grep method
    if (r)
        return (> ._grep__replace(regexp, objs, rep) <);
    else if (l)
        return (> ._grep__list(regexp, objs) <);
    else if (f)
        return (> ._grep__full(regexp, objs) <);
    else
        return (> ._grep__brief(regexp, objs) <);
};

protected method ._grep__replace() {
    arg regexp, objs, replace;
    var obj, method;
    
    for obj in (objs) {
        if (!valid(obj))
            continue;
        if (!(obj.is_writable_by(this()))) {
            .tell(("You cannot write on " + obj) + ", skipping..");
            continue;
        }
        for method in (obj.methods()) {
            (> ._grep__replace_method(obj, method, regexp, replace) <);
            refresh();
        }
        refresh();
    }
    return "Done.";
};

protected method ._grep__list() {
    arg regexp, objs;
    var obj, code, x, l, lr, what, loop, method, opt;
    
    opt = .get_setting("@program-options", $programmer);
    for obj in (objs) {
        if (!valid(obj))
            continue;
        if (!(obj.has_flag('code))) {
            .tell(("You cannot read method code on " + obj) + ", skipping..");
            continue;
        }
        for method in (obj.methods()) {
            code = obj.list_method(method);
            for l in (code) {
                if (match_regexp(l, regexp)) {
                    .tell(([$object_lib.format_method_header(obj, method, opt, obj.method_flags(method), obj.method_access(method))] + (code.prefix("  "))) + ["."]);
                    break;
                }
                refresh();
            }
            refresh();
        }
        refresh();
    }
    return "---";
};

protected method ._grep__full() {
    arg regexp, objs;
    var obj, method, out, x, l, code;
    
    for obj in (objs) {
        if (!valid(obj))
            continue;
        if (!(obj.has_flag('code))) {
            .tell(("You cannot read method code on " + obj) + ", skipping..");
            continue;
        }
        out = [];
        for method in (obj.methods()) {
            code = obj.list_method(method);
            for x in [1 .. listlen(code)] {
                l = code[x];
                if (match_regexp(l, regexp))
                    out += [(((((obj + ".") + method) + "() line ") + x) + ": ") + l];
                refresh();
            }
            refresh();
        }
        if (out)
            .tell(out);
        refresh();
    }
    return "---";
};

protected method ._grep__brief() {
    arg regexp, objs;
    var obj, method, out, x, l, line, lines, code;
    
    for obj in (objs) {
        if (!valid(obj))
            continue;
        if (!(obj.has_flag('code))) {
            .tell(("You cannot read method code on " + obj) + ", skipping..");
            continue;
        }
        out = [];
        for method in (obj.methods()) {
            code = obj.list_method(method);
            lines = [];
            for x in [1 .. listlen(code)] {
                l = code[x];
                if (match_regexp(l, regexp))
                    lines += [x];
                refresh();
            }
            if (lines)
                out += [(((obj + ".") + method) + "(): ") + (lines.to_english())];
            refresh();
        }
        if (out)
            .tell(out);
        refresh();
    }
    return "---";
};

protected method ._grep__replace_method() {
    arg obj, method, regexp, replace;
    var old_code, code, x, l, lr, errs, what;
    
    old_code = (code = obj.list_method(method));
    for x in [1 .. listlen(code)] {
        l = code[x];
        if (!match_regexp(l, regexp))
            continue;
        lr = strsed(l, regexp, replace, "g");
        .tell([((((("Change " + obj) + ".") + method) + "() line ") + x) + " from:", "  " + l, "to:", "  " + lr]);
        what = (> .prompt("? (yes, no, abort, abort-all) [yes] ") <);
        if ((!what) || (what in ["yes", "y"])) {
            code = replace(code, x, lr);
        } else if (what == "abort") {
            .tell("Aborting method ..");
            return;
        } else if (what == "abort-all") {
            throw(~stop, "Aborting grep replace");
        } else if (!(what in ["no", "n"])) {
            .tell(("Unknown command '" + what) + "', assuming 'no'.");
        }
        refresh();
    }
    if ((old_code != code) && (errs = obj.add_method(code, method)))
        .tell(((([((("Error in compilation of updated method " + obj) + ".") + method) + "():"] + (errs.prefix("  "))) + ["-- Method code: "]) + (code.prefix("  "))) + ["--"]);
};

protected method .chmod_cmd() {
    arg cmdstr, cmd, args;
    var a, ts, t, opts, b, objs, o, precedence, ref, flags, match, m;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    ts = ["cod?e", "cor?e", "d?river", "fe?rtile", "fo?rked", "fr?ob", "l?ocked", "m?ethods", "na?tive", "no?override", "pri?vate", "pro?tected", "pu?blic", "r?oot", "v?ariables"];
    if (!args)
        return ("=> Syntax: `" + cmd) + " <options> <object> [<object ..]`";
    opts = #[];
    objs = [];
    for a in (args) {
        if (a && ((a[1]) in ["+", "-"])) {
            b = (a[1]) == "+";
            a = substr(a, 2);
            match = 0;
            for t in (ts) {
                if (match_template(a, t)) {
                    opts = dict_add(opts, tosym(t.strip()), b);
                    match++;
                    break;
                }
            }
            if (!match) {
                catch ~symbol
                    opts = dict_add(opts, tosym(a), b);
                with
                    .tell(("Invalid option '" + a) + "' (non-alphanumeric characters)");
            }
        } else {
            objs += [a];
        }
    }
    if (!objs)
        return [("=> Syntax: `" + cmd) + " <options> <object> [<object ..]`", "No objects specified."];
    if (!opts)
        return [("=> Syntax: `" + cmd) + " <options> <object> [<object ..]`", "No options specified."];
    
    // ok, now handle it, keep precedence for their own sake
    for o in (objs) {
        catch any {
            ref = $parse_lib.ref(o);
        } with {
            .tell((traceback()[1])[2]);
            continue;
        }
        if (!precedence) {
            precedence = ref[1];
        } else if ((ref[1]) != precedence) {
            .tell(((("Item '" + o) + "' is not a ") + precedence) + " reference.");
            .tell("All references must be the same type.");
            continue;
        }
        o = ref[3];
        for a in (dict_keys(opts)) {
            catch any {
                switch (a) {
                    case 'driver, 'private, 'protected, 'public, 'root, 'frob:
                        if (precedence != 'method) {
                            .tell((("Option " + ((opts[a]) ? "+" : "-")) + a) + " is only applicable to methods.");
                            continue;
                        }
                        m = (> tosym(ref[4]) <);
                        (> o.set_method_access(m, a) <);
                        .tell(((("Set " + ($parse_lib.buildref(@ref))) + " access to ") + a) + ".");
                    case 'nooverride, 'locked, 'native, 'forked:
                        if (precedence != 'method) {
                            .tell((("Option " + ((opts[a]) ? "+" : "-")) + a) + " is only applicable to methods.");
                            continue;
                        }
                        m = (> tosym(ref[4]) <);
                        if (opts[a]) {
                            o.set_method_flags(m, setadd(o.method_flags(m), a));
                            .tell((((("Added Method Flag +" + a) + " to ") + ($parse_lib.buildref(@ref))) + ", flags: ") + (((o.method_flags(m)).prefix("+")).join()));
                        } else {
                            o.set_method_flags(m, setremove(o.method_flags(m), a));
                            .tell((((("Removed Method Flag +" + a) + " from ") + ($parse_lib.buildref(@ref))) + ", flags: ") + (((o.method_flags(m)).prefix("+")).join()));
                        }
                    default:
                        if (precedence != 'object) {
                            .tell((("Option " + ((opts[a]) ? "+" : "-")) + a) + " is only applicable to objects.");
                            continue;
                        }
                        if (opts[a]) {
                            o.add_flag(a);
                            .tell((((("Added Object Flag +" + a) + " to ") + (o.namef('ref))) + ", flags: ") + (((o.flags()).prefix("+")).join()));
                        } else {
                            o.del_flag(a);
                            .tell((((("Removed Object Flag +" + a) + " from ") + (o.namef('ref))) + ", flags: ") + (((o.flags()).prefix("+")).join()));
                        }
                }
            } with {
                .tell((traceback()[1])[2]);
            }
        }
        refresh();
    }
};

protected method .dump_fmt_textdump() {
    arg objs, meths, vars, header;
    var data, obj, out, a, v, m;
    
    // this uses .tell() to keep its internal overhead from bloating
    // it could be faster by building a list and printing it all at once
    // but this is nicer on the server (especially when dumping large objects).
    for obj in (objs) {
        refresh();
        if (header)
            .tell([((("object " + obj) + ": ") + ((obj.parents()).join(", "))) + ";", ""]);
        if (vars) {
            catch ~perm {
                data = (> obj.data() <);
                for a in (dict_keys(data)) {
                    refresh();
                    for v in (data[a])
                        .tell(strfmt("var %l %l = %d;", a, @v));
                }
            } with {
                .tell((traceback()[1])[2]);
            }
        }
        .tell("");
        if (meths) {
            catch ~perm {
                for m in ((> obj.methods() <)) {
                    refresh();
                    .tell([""] + (.format_method(obj, m, 'textdump)));
                }
            } with {
                .tell((traceback()[1])[2]);
            }
        }
    }
};

protected method .dump_fmt_commands() {
    arg objs, meths, vars, header;
    var data, obj, out, a, v, m, line, pars, cmdopts;
    
    // this uses .tell() to keep its internal overhead from bloating
    // it could be faster by building a list and printing it all at once
    // but this is nicer on the server (especially when dumping large objects).
    for obj in (objs) {
        refresh();
        if (header) {
            if (obj == $root) {
                pars = $root;
                line = "";
            } else {
                pars = obj.parents();
                line = (((((((";var p, new; if(!(| valid(" + obj) + ") |)) ") + "{ new = ") + (pars[1])) + ".spawn();") + " new.set_objname('") + (obj.objname())) + ");}";
                if (listlen(pars) > 1)
                    line += (" obj.chparents(" + join(pars, ",")) + ");";
                .tell(line);
            }
        }
        if (vars) {
            catch ~perm {
                data = (> obj.data() <);
                for a in (dict_keys(data)) {
                    refresh();
                    for v in (data[a]) {
                        if (a == obj)
                            .tell(strfmt("@av %l,%l = %d", obj, @v));
                        .tell(strfmt(";|as %l<%l>;%l = %d;", obj, a, @v));
                    }
                }
            } with {
                .tell((traceback()[1])[2]);
            }
        }
        if (meths) {
            cmdopts = .get_setting("@program-options", $programmer);
            catch ~perm {
                for m in ((> obj.methods() <)) {
                    refresh();
                    .tell(.format_method(obj, m, 'normal, cmdopts));
                }
            } with {
                .tell((traceback()[1])[2]);
            }
        }
    }
};

protected method .format_method() {
    arg obj, method, format, @opts;
    var code, opt, flags, f;
    
    // this needs to be on $programmer ot get the programmers perms
    [(opt ?= "")] = opts;
    code = obj.list_method(method);
    flags = obj.method_flags(method);
    switch (format) {
        case 'textdump:
            return (([(((((((obj.method_access(method)) + " method ") + obj) + ".") + method) + "()") + (flags ? (": " + (flags.join(", "))) : "")) + " {"] + (code.prefix("    "))) + ["};"]) + ((obj.credit()).prefix("// "));
        case 'numbered:
            code = code.numbered_text();
            return (([(((((("-- " + (obj.method_access(method))) + " method ") + obj) + ".") + method) + "()") + (flags ? (": " + (flags.join(", "))) : "")] + code) + ["--"]) + ((obj.credit()).prefix("// "));
        default:
            return (([$object_lib.format_method_header(obj, method, opt, flags, obj.method_access(method))] + (code.prefix("  "))) + ["."]) + ((obj.credit()).prefix("// "));
    }
};

protected method .help_write_cmd() {
    arg cmdstr, cmd, str;
    var node, text, errors, ignore;
    
    (> .perms(caller(), 'command) <);
    if (!str) {
        node = .current_node();
    } else {
        catch any {
            node = .parse_help_reference(str);
        } with {
            .tell(("-- " + ((traceback()[1])[2])) + " --");
            .read("-- Ignoring until '.' or @abort --");
            return "Done ignoring.";
        }
    }
    if (!(node.is($help_node))) {
        ignore++;
        .tell((node.namef('ref)) + " is not a descendant of $help_node, ignoring.");
    }
    if (!(node.is_writable_by(this()))) {
        ignore++;
        .tell(("You cannot write help on " + (node.name())) + ", ignoring.");
    }
    text = .read(("-- Enter CML text for " + (node.namef('ref))) + " --");
    if (text == 'aborted)
        return;
    if (ignore)
        return "Done ignoring.";
    catch any
        node.set_body(text);
    with
        return "Error storing text: " + ((traceback()[1])[2]);
    return ("New help text set for " + (node.namef('ref))) + ".";
};

protected method .help_list_cmd() {
    arg cmdstr, cmd, str;
    var node, out;
    
    (> .perms(caller(), 'command) <);
    if (!str)
        node = .current_node();
    else
        node = .parse_help_reference(str);
    if (!(node.is($help_node)))
        return (node.namef('ref)) + " is not a descendant of $help_node.";
    return (["@hwrite " + node] + ((node.body()).uncompile())) + ["."];
};

protected method .new_help_node_cmd() {
    arg cmdstr, cmd, args;
    var new, name, p, parent, i, syn, m, index, opts, objname, o;
    
    (> .perms(caller(), 'command) <);
    syn = ("=> Syntax: `" + cmd) + " [<parent node>] [options]`";
    [args, opts] = args;
    o = opts.slice(1);
    if ((i = "n?amed" in o)) {
        name = (opts[i])[4];
        if (!name)
            return [syn, "Option +n?amed requires a followup argument."];
    }
    if ((i = "o?bjname" in o)) {
        objname = (| ((opts[i])[4]).to_symbol() |);
        if (!objname)
            return [syn, "Option +o?bjname requires a followup argument."];
    }
    
    // now use 'i' as the string rep of 'index'
    if ((i = "i?ndex" in o)) {
        i = (opts[i])[4];
        if (!i)
            return [syn, "Option +i?ndex requires a followup argument."];
    }
    
    // now figure out the parent node
    if (args) {
        p = args[1];
        catch any
            parent = (> .parse_help_reference(p) <);
        with
            return (traceback()[1])[2];
    } else {
        parent = .current_node();
    }
    
    // figure out the index
    if (i) {
        if ((i[1]) in ["$", "#"])
            index = (| $object_lib.to_dbref(i) |);
        else
            index = $help_index.match_children(i);
        if (!index)
            return [syn, ("!  Unable to find index '" + i) + "'"];
        if (!(index.has_ancestor($help_index)))
            return [syn, ("!  '" + (index.namef('ref))) + "' is not a help index."];
    }
    
    // create it
    new = (> parent.spawn() <);
    .tell(((("Created new node " + new) + " from ") + (parent.namef('ref))) + ".");
    
    // change its objname?
    if (objname) {
        catch any {
            (> new.set_objname(objname) <);
            .tell(("Changed node's objname to " + new) + ".");
        } with {
            .tell("set_objname(): " + ((traceback()[1])[2]));
        }
    }
    
    // set its name?
    if (name) {
        catch any {
            (> new.set_name(name) <);
            .tell(("Changed node's name to " + (new.name())) + ".");
        } with {
            .tell("set_name(): " + ((traceback()[1])[2]));
        }
    } else {
        .tell(("No name specified, set it with `@rename " + new) + " to <name>`");
    }
    
    // set its index?
    if (index) {
        catch any {
            (> new.set_index(index) <);
            .tell(("Set node's index to " + (index.namef('ref))) + ".");
        } with {
            .tell("set_index(): " + ((traceback()[1])[2]));
        }
    } else {
        .tell(("No index specified, set it with `@set " + new) + ":index=<index>`");
    }
};

public method .spawn_cmd() {
    arg cmdstr, cmd, args;
    var match, name, parents, p, line, set, nprog, new, t;
    
    (> .perms(caller(), 'command) <);
    if ((match = match_template(args, "* named *"))) {
        name = match[3];
        args = explode(match[1]);
    } else {
        args = args.explode_quoted();
        if (!args)
            return "Spawn from nothing?";
        name = "";
    }
    
    // programmers get additional privs
    nprog = !(.is($programmer));
    parents = [];
    for p in (args) {
        catch any {
            p = (> .match_env_nice(p) <);
        } with {
            .tell((traceback()[1])[2]);
            continue;
        }
        if ((!(p.is($thing))) && nprog) {
            .tell((p.namef('ref)) + " is not a VR object, you may only spawn VR objects.");
            continue;
        }
        if (!(p.has_flag('fertile))) {
            .tell((p.namef('ref)) + " is not a fertile object.");
            continue;
        }
        parents += [p];
    }
    parents = parents.compress();
    if (!parents)
        return "No capable parents.";
    if (name) {
        catch any
            name = (> $code_lib.parse_name(name) <);
        with
            return (traceback()[1])[2];
    }
    
    // spawn from the first parent, add the others
    catch any {
        new = (> (parents[1]).spawn() <);
        (> new.chparents(@parents) <);
    
        // let the user know whats up
        .tell(((("Spawned new object " + (new.namef('ref))) + " from ") + (map p in (parents) to (p.namef('ref)).to_english())) + ".");
        if (new.is($located))
            (> new.move_to(this()) <);
        if (name && ((((name[1])[1])[1]) == "$")) {
            name = (> tosym(((name[1])[1]).subrange(2)) <);
            (> new.set_objname(name) <);
            return ("Object name changed to: " + new) + ".";
        } else if (name) {
            if (!(new.has_ancestor($has_name)))
                return new + " cannot be given a VR name.";
            (> new.set_name(@name[1]) <);
            for t in (name[2])
                (> new.add_name_template(t) <);
            return (((("Renamed " + new) + " to \"") + (new.name())) + "\"") + ((new.name_templates()) ? ((" (" + ((new.name_templates()).to_english())) + ")") : "");
        }
    } with {
        .tell((traceback()[1])[2]);
        if (valid(new)) {
            line = new.namef('xref);
            new.destroy();
            if (valid(new))
                return ("Unable to destroy new object " + line) + ".";
            else
                return ("Sucessfully destroyed new object " + line) + ".";
        }
    }
};

protected method .ancestors_cmd() {
    arg cmdstr, cmd, args;
    var syn, obj, maxlevels, line;
    
    (> .perms(caller(), 'command) <);
    syn = cmd + " <obj> [<levels>]";
    args = args.explode();
    if (!((args.length()) in [1, 2]))
        return syn;
    obj = (> .match_env_nice(args[1]) <);
    if ((args.length()) == 2) {
        if ((args[2]) == "all")
            maxlevels = 0;
        else
            maxlevels = abs(toint(args[2])) + 1;
    } else {
        maxlevels = 3;
    }
    line = ("Ancestors of " + obj) + ":";
    if (maxlevels) {
        line += tostr(maxlevels - 1);
        line = ((line + " level") + (((maxlevels - 1) > 1) ? "s" : "s")) + ":";
    } else {
        line += "all levels:";
    }
    .tell(line);
    .tell(obj._display_ancestors("", #[], 0, maxlevels));
    .tell("---");
};

public method .undefine_setting_cmd() {
    arg cmdstr, cmd, args;
    var name, definer, syn, name, m;
    
    syn = ("Syntax: `" + cmd) + " <definer>:<setting>`";
    if (!(m = regexp(args, "^ *([^:]+):([^ $]+)")))
        return syn;
    [definer, name] = m;
    catch any
        definer = (> .match_environment(definer) <);
    with
        return (traceback()[1])[2];
    if (!name)
        return syn;
    catch any
        (> definer.undefine_setting(name) <);
    with
        return (traceback()[1])[2];
    return ((("Undefined setting " + definer) + ":") + name) + ".";
};

public method .configure_setting_cmd() {
    arg cmdstr, cmd, args;
    var def_opts, opts, o, name, config, m, definer, syn, type, def, val;
    
    syn = ("Syntax: `" + cmd) + " <definer>:<setting>[=default] [options]`";
    def_opts = [];
    for o in (["get", "set", "parse"])
        def_opts += [[o, 1], [o + "-a?rgs", 1]];
    def_opts += [["c?lear", 1], ["f?ormat", 1], ["a?ccess", 1], ["t?ype", 1]];
    [args, opts] = $parse_lib.getopt(args, def_opts);
    args = join(args, " ");
    if (!args) {
        .tell(syn);
        for o in (def_opts.slice(1))
            .tell(((("   +" + o) + "=<") + ((o.strip("?")).replace("-", " "))) + ">");
        return "Types can be any ColdC type and \"boolean\"";
    }
    if ((m = regexp(args, "^([^=]+) *= *(.*)$")))
        [args, def] = m;
    else
        def = "";
    if ((m = regexp(args, "^([^:]+) *: *([\@a-z0-9-]+)")))
        [definer, name] = m;
    else
        definer = args;
    catch any
        definer = (> .match_environment(definer) <);
    with
        return (traceback()[1])[2];
    if (!name)
        return syn;
    catch ~setnf
        definer = definer.setting_definer(name);
    with
        return (traceback()[1])[2];
    
    // setup some default config opts based off the desired type
    config = #[];
    if ((m = "t?ype" in (opts.slice(1)))) {
        type = (| ((opts[m])[4]).to_symbol() |);
        if ((!type) || (!($settings.is_valid_type(type))))
            return "Types can be any ColdC type and " + (($settings.valid_types()).to_english("", " or "));
        switch (type) {
            case 'boolean:
                config = #[['parse, ['is_boolean]], ['format, ['format_boolean]]];
            case 'itemlist:
                // do nothing, we re-adjust things later
            default:
                config = #[['parse, ['is_type, type]]];
        }
    }
    
    // now build default config--not the most efficient way--but cleaner
    config = (> ._def_setcmd_opt("get", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("get-a?rgs", 'data_list, opts, config) <);
    config = (> ._def_setcmd_opt("set", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("set-a?rgs", 'data_list, opts, config) <);
    config = (> ._def_setcmd_opt("parse", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("parse-a?rgs", 'data_list, opts, config) <);
    config = (> ._def_setcmd_opt("c?lear", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("f?ormat", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("a?ccess", 'symbol, opts, config) <);
    if (type == 'itemlist) {
        config = config.add('parse, ['parse_itemlist, @(| config['parse] |) || []]);
        if (!(config.contains('format)))
            config = config.add('format, ['format_itemlist]);
    }
    
    // now reconfig it
    for o in (config) {
        catch any
            (> definer.set_setting_attr(name, @o) <);
        with
            .tell((traceback()[1])[2]);
    }
    .tell(((("Reconfigured setting " + definer) + ":") + name) + " as:");
    config = (definer.defined_settings())[name];
    for o in (config) {
        val = o[2];
        o = o[1];
        .tell((("    +" + strsub(tostr(o), "_", "-")) + "=") + (val[1]));
        if (listlen(val) > 1)
            .tell((("    +" + strsub(tostr(o), "_", "-")) + "-args=") + (map m in (sublist(val, 2)) to (toliteral(m)).join(",")));
    }
};

public method .define_setting_cmd() {
    arg cmdstr, cmd, args;
    var def_opts, opts, o, name, config, m, definer, syn, type, def, val;
    
    syn = ("Syntax: `" + cmd) + " <definer>:<setting>[=default] [options]`";
    def_opts = [];
    for o in (["get", "set", "parse"])
        def_opts += [[o, 1], [o + "-a?rgs", 1]];
    def_opts += [["c?lear", 1], ["f?ormat", 1], ["a?ccess", 1], ["t?ype", 1]];
    [args, opts] = $parse_lib.getopt(args, def_opts);
    args = join(args, " ");
    if (!args) {
        .tell(syn);
        for o in (def_opts.slice(1))
            .tell(((("   +" + o) + "=<") + ((o.strip("?")).replace("-", " "))) + ">");
        return "Types can be any ColdC type and \"boolean\"";
    }
    if ((m = regexp(args, "^([^=]+) *= *(.*)$")))
        [args, def] = m;
    else
        def = "";
    m = split(args, " *: *");
    if (listlen(m) != 2)
        return syn;
    [definer, name] = m;
    if ((m = regexp(name, "[^\@a-z0-9-]"))) {
        .tell((("Invalid character '" + (m[1])) + "' in setting name: ") + name);
        throw(~stop, "Setting name may only contain a-z, 0-9 and a dash");
    }
    catch any
        definer = (> .match_environment(definer) <);
    with
        return (traceback()[1])[2];
    if (!name)
        return syn;
    
    // setup some default config opts based off the desired type
    config = #[];
    if ((m = "t?ype" in (opts.slice(1)))) {
        type = (| ((opts[m])[4]).to_symbol() |);
        if ((!type) || (!($settings.is_valid_type(type))))
            return "Types can be any ColdC type and " + (($settings.valid_types()).to_english("", " or "));
        switch (type) {
            case 'boolean:
                config = #[['parse, ['is_boolean]], ['format, ['format_boolean]]];
            case 'itemlist:
                // do nothing, we re-adjust things later
            default:
                config = #[['parse, ['is_type, type]]];
        }
    }
    
    // now build default config--not the most efficient way--but cleaner
    config = (> ._def_setcmd_opt("get", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("get-a?rgs", 'data_list, opts, config) <);
    config = (> ._def_setcmd_opt("set", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("set-a?rgs", 'data_list, opts, config) <);
    config = (> ._def_setcmd_opt("parse", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("parse-a?rgs", 'data_list, opts, config) <);
    config = (> ._def_setcmd_opt("c?lear", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("f?ormat", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("a?ccess", 'symbol, opts, config) <);
    if (type == 'itemlist) {
        config = config.add('parse, ['parse_itemlist, @(| config['parse] |) || []]);
        if (!(config.contains('format)))
            config = config.add('format, ['format_itemlist]);
    }
    
    // now add it..
    catch any
        config = (> definer.define_setting(name, config) <);
    with
        return (traceback()[1])[2];
    .tell(((("-- Defined setting " + definer) + ":") + name) + " as:");
    for o in (config) {
        val = o[2];
        o = o[1];
        .tell((("    +" + strsub(tostr(o), "_", "-")) + "=") + (val[1]));
        if (listlen(val) > 1)
            .tell((("    +" + strsub(tostr(o), "_", "-")) + "-args=") + (sublist(val, 2).join(",")));
    }
    
    // and set the default value
    catch any {
        o = definer;
        o = o.set_setting(name, o, def);
        val = o.format_setting(name, o, o.get_setting(name, o));
        return ["-- Default Setting:", (("  " + name) + " = ") + val, "--"];
    } with {
        return (traceback()[1])[2];
    }
};

private method ._def_setcmd_opt() {
    arg opt, type, opts, dict;
    var i, value, m;
    
    if (!(i = opt in (opts.slice(1))))
        return dict;
    value = (opts[i])[4];
    if (!value)
        throw(~stop, ("No value for option \"" + opt) + "\".");
    catch any {
        switch (type) {
            case 'symbol:
                value = [(> value.to_symbol() <)];
            case 'data_list:
                value = (> fromliteral(value) <);
                if (type(value) != 'list)
                    value = [value];
        }
    } with {
        rethrow(~stop);
    }
    opt = opt.strip("?");
    if ((m = match_pattern(opt, "*-args"))) {
        opt = tosym(m[1]);
        if (!dict_contains(dict, opt))
            throw(~stop, ((("Arguments defined for " + opt) + " without defining ") + opt) + " method.");
        value = [(dict[opt])[1], @value];
        return dict_add(dict, opt, value);
    } else {
        return dict_add(dict, tosym(opt), value);
    }
};

public method .parse_match_with() {
    arg value, @args;
    
    if (value in ["regexp", "pattern", "begin"])
        return tosym("match_" + (value.lowercase()));
    throw(~perm, "You can match with: regexp, pattern, begin.");
};

protected method ._edit_variable_callback() {
    arg data, client_data;
    var name, def, errs, obj, variable;
    
    (> .perms(caller(), $editor_reference) <);
    [obj, variable] = client_data;
    data = ([variable + " = "] + data) + [";"];
    name = tosym("tmp_edit_" + time());
    def = (obj + ",") + variable;
    catch any {
        if ((errs = obj.add_method(data, name, 'evalonly)))
            return ['failure, [(("Unable to store " + def) + ": ") + (errs.join())]];
    } with {
        return ['failure, []];
    }
    catch any {
        data = obj.(name)();
    } with {
        (| obj.del_method(name) |);
        return ['failure, [(("Unable to store " + def) + ": ") + ((traceback()[1])[2])]];
    }
    (| obj.del_method(name) |);
    return ['success, [["Variable stored."]]];
};

protected method ._eval_subs() {
    arg code;
    var out, x;
    
    out = "";
    while ((x = match_regexp(code, "\^[a-z0-9_]+"))) {
        x = x[1];
        out += substr(code, 1, (x[1]) - 1);
        out += (> .match_env_nice(substr(code, (x[1]) + 1, (x[2]) - 1)) <);
        code = substr(code, x.sum());
    }
    if (code)
        out += code;
    return out;
};


new object $admin: $programmer;

var $root inited = 1;
var $root manager = $admin;
var $root quota = 75000;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables, 'general_cache];
var $root managed = [$admin];
var $location contents = [];
var $located location = $body_cave;
var $located obvious = 1;
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user modes = #[];
var $user formatter = $plain_format;
var $user parsers = [$command_parser];
var $user task_connections = #[];
var $programmer eval_prefix = #[["me", "me = this()"], ["here", "here = this().location()"]];
var $admin shutdown_started = 0;
var $command_aliases command_aliases = [];
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list senders = 1;
var $mail_list readers = [];
var $mail_list notify = [$admin];
var $mail_list last_letter = 0;
var $mail_list mail = [];
var $mail_ui subscribed = #[[$admin, [791485891, 0]]];
var $mail_ui current = #[['location, 0], ['list, $admin]];
var $described prose = [];
var $has_name name = ['prop, "Generic Admin", "Generic Admin"];
var $has_commands local = #[["@del-t?ask|@kill", [["@del-t?ask|@kill", "*", "@del-t?ask|@kill <any>", 'del_task_cmd, #[[1, ['any, []]]]]]], ["@backup", [["@backup", "", "@backup", 'backup_cmd, #[]]]], ["@shutdown", [["@shutdown", "*", "@shutdown <any>", 'shutdown_cmd, #[[1, ['any, []]]]]]], ["@mojo", [["@mojo", "*", "@mojo <any>", 'mojo_cmd, #[[1, ['any, []]]]]]], ["@adjust|@promote", [["@adjust|@promote", "* to *", "@adjust|@promote <user> to <any>", 'adjust_cmd, #[[1, ['user, []]], [3, ['any, []]]]]]], ["@new-password|@newpw?d", [["@new-password|@newpw?d", "*", "@new-password|@newpw?d <user>", 'new_password_cmd, #[[1, ['user, []]]]]]], ["@task?s", [["@task?s", "*", "@task?s <any>", 'tasks_cmd, #[[1, ['any, []]]]]]], ["@core", [["@core", "*", "@core <list object>", 'core_cmd, #[[1, ['list, ['object, []]]]]]]], ["@rehash-all", [["@rehash-all", "*", "@rehash-all <any:-p?urge>", 'rehash_all_cmd, #[[1, ['any_opt, ["p?urge"]]]]]]], ["@reap", [["@reap", "*", "@reap <any>", 'reap_cmd, #[[1, ['any, []]]]]]], ["@quota", [["@quota", "* to *", "@quota <object> to <any:+e?xempt>", 'quota_cmd, #[[1, ['object, []]], [3, ['any_opt, ["e?xempt"]]]]]]], ["@kick", [["@kick", "*", "@kick <any>", 'kick_cmd, #[[1, ['any, []]]]]]], ["@scour", [["@scour", "*", "@scour <any>", 'scour_cmd, #[[1, ['any, []]]]]]], ["@cache-stats", [["@cache-stats", "*", "@cache-stats <any>", 'cache_stats_cmd, #[[1, ['any, []]]]]]], ["@users", [["@users", "", "@users", 'user_breakdown_cmd, #[]]]]];
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $foundation defined_msgs = #[["mojo-on", #[['branches, ["general", "actor"]]]], ["mojo-off", #[['branches, ["general", "actor"]]]], ["mojo-look", #[['branches, ["general", "actor"]]]]];
var $foundation msgs = #[["mojo-on", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, "'s eyes glow as Mojo courses through ", <$generator, ["actor.pp", [], [], 'gen_actorpp]>, " body."], #[['this, $admin]]]>], ["actor", <$ctext_frob, [["Your eyes glow as Mojo courses through your body."], #[['this, $admin]]]>]]], ["mojo-off", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, "'s eyes stop glowing as the Mojo leaves ", <$generator, ["actor.pp", [], [], 'gen_actorpp]>, " body."], #[['this, $admin]]]>], ["actor", <$ctext_frob, [["Your eyes stop glowing as the Mojo leaves your body."], #[['this, $admin]]]>]]], ["mojo-look", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, "'s eyes ", <$generator, ["mojo.what", [], [], 'gen_mojowhat]>, "glow from Mojo."], #[['this, $admin]]]>], ["actor", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, "'s eyes ", <$generator, ["mojo.what", [], [], 'gen_mojowhat]>, "glow from mojo."], #[['this, $admin]]]>]]]];
var $thing gender = $gender_neuter;
var $root settings = #[["home", $body_cave], ["admin-role", ""]];
var $command_cache modules = [];
var $root defined_settings = #[["admin-role", #[]]];
var $command_cache commands = 0;
var $command_cache shortcuts = 0;

root method .init_admin() {
    $sys.new_admin();
};

protected method .del_task_cmd() {
    arg cmdstr, com, args;
    var syn, sys, task, t;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    syn = ("Syntax: `" + com) + " [*]<task>`";
    args = explode(args);
    if (!args)
        return syn;
    for t in (args) {
        if (t && ((t[1]) == "*")) {
            t = substr(t, 2);
            sys = 1;
        }
        task = toint(t);
        if (!task) {
            .tell(syn, ("Invalid task '" + t) + "'");
            continue;
        }
        if (sys) {
            $scheduler.cancel(task);
            .tell(("System task " + tostr(task)) + " canceled.");
        } else {
            catch any
                $scheduler.del_task(task);
            with
                (> .tell_error(syn, (traceback()[1])[2]) <);
            .tell(("Task " + tostr(task)) + " deleted.");
        }
    }
};

protected method .tasks_cmd() {
    arg cmdstr, cmd, args;
    var out, task, queue, time, args, fmt, tfmt, info, suspend, preempt, line, x;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    out = [];
    if (args) {
        for x in (explode(args)) {
            if ((x[1]) == "*")
                x = substr(x, 2);
            if (!(task = (| $scheduler.task_info(toint(x)) |))) {
                .tell(("Invalid task '" + x) + "'");
                continue;
            }
            out = ["Task: " + ((task[1])[1]), "", strfmt("  %8l %15L %s", "TICKS", "USER", "METHOD")];
    
            // add an option to not restrict this
            for info in (sublist(task, 3))
                out += [strfmt("  %8l %15L %s.%s()", info[7], info[4], info[1], info[8])];
        }
        return out;
    }
    queue = $scheduler.task_queue();
    if (queue) {
        tfmt = "%d %b %y %H:%M:%S";
        fmt = "%5L %20L %s";
        time = $time.format(tfmt);
        out = [strfmt(fmt, "ID", "EXEC TIME", "TASK"), strfmt(fmt, "---", "---------", "----")];
        fmt += ".%s(%s)";
        for task in (queue) {
            args = toliteral(task[8]);
            out += [strfmt(fmt, task[1], $time.format(tfmt, task[2]), task[4], task[6], substr(args, 2, strlen(args) - 2))];
        }
        if (out)
            out = ["-- Database Tasks --"] + out;
    }
    if ((queue = tasks())) {
        suspend = [];
        preempt = [];
        fmt = "%8l%8l%24L";
        for task in (queue) {
            refresh();
            info = $scheduler.task_info(task);
            line = strfmt(fmt, (info[1])[1], (info[3])[7], ((((info[3])[1]) + ".") + ((info[3])[8])) + "()", (info[3])[4]);
            catch any {
                task = ($scheduler.suspended_task(task)).join();
                if (strlen(task) > 38)
                    task = substr(task, 1, 35) + "...";
            } with {
                task = "";
            }
            if ((info[1])[2])
                preempt += [line + task];
            else
                suspend += [line + task];
        }
        tfmt = strfmt(fmt, "TASK", "TICKS", "METHOD") + "RESUMABLE BY";
        if (preempt)
            out += ["-- Preempted Tasks --", tfmt] + preempt;
        if (suspend)
            out += ["-- Suspended Tasks --", tfmt] + suspend;
    }
    return out || "-- No suspended or preempted tasks --";
};

protected method .backup_cmd() {
    arg cmdstr, com;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    .tell("Starting backup.");
    $sys.do_backup(this());
    .tell("Done.");
};

protected method .shutdown_cmd() {
    arg cmdstr, com, @args;
    var time, opt, why, answer, ans;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    args = (> $parse_lib.opt(args.join(), "t?ime") <);
    opt = "t?ime" in ((args[2]).slice(1));
    if (opt && ((((args[2])[opt])[4]).is_numeric()))
        time = toint(((args[2])[opt])[4]);
    else
        time = 5;
    if (!(why = (args[1]).join()))
        why = "Administrator's whim.";
    .tell(((("Shutdown " + ($motd.server_name())) + " in ") + tostr(time)) + " minutes");
    .tell("Reason for shutdown: " + why);
    ans = (> .prompt("Is this correct? [yes]: ") <);
    if (!ans)
        ans = "yes";
    if (!(ans in ["yes", "y"])) {
        .tell("I didn't think so, aborting shutdown...");
        return;
    }
    .tell("Ok!");
    $sys.do_shutdown(time, why);
};

protected method .adjust_cmd() {
    arg cmdstr, cmd, who, prep, str;
    var i, what, p, pwd, o, email, valid;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    valid = #[["user", $user], ["player", $player], ["builder", $builder], ["programmer", $programmer], ["admin", $admin]];
    what = (str.explode()).last();
    if (!(valid.contains(what)))
        return ("Promote to: " + ((valid.keys()).to_english())) + ".";
    
    // mail them the password--do this first incase we fail here
    if ($guest in (who.parents())) {
        who.set_setting("title", $user, "");
        pwd = $code_lib.random_password();
        who.set_password(pwd);
        email = who.user_info("email");
        if (!email)
            return (who.namef('ref)) + " does not have an email address!";
        catch any {
            $smtp.sendmail('admin, email, ("[" + ($motd.server_name())) + "] password change.", [((("The password for the user " + (who.name())) + " on ") + ($motd.server_name())) + " has been set as:", "", "    " + pwd, "", "This is an automatic message sent to the supplied address.  If this message is in error simply discard it.", "", "If no connections are made to this user within a week it will be purged."]);
        } with {
            if (error() == ~error) {
                .tell(("While trying to email '" + email) + "':");
                .tell((traceback()[1])[2]);
                return "** Aborting adjustment **";
            }
            .tell_traceback(traceback());
            return "** Unable to send mail message, no changes made **";
        }
    }
    
    // selectively cleanup their 'new' parents list, retain special parents
    p = who.parents();
    for o in ([$guest] + (valid.values()))
        p = setremove(p, o);
    
    // add the parent we care about to the front, call chparents()
    // we are admins, we can handle tracebacks if they occur.
    (> who.chparents(valid[what], @p) <);
    
    // update caches.
    who.cache_client_init();
    
    // let'em know what we did
    what = what.add_indefinite();
    who.tell((((.name()) + " has made you ") + what) + ".");
    
    // if we changed their password, let them know that too
    if (pwd) {
        who.tell(("** Your password has been emailed to " + email) + " **");
        who.tell("** You can change it with the command: `@password` **");
    }
    (.location()).announce(((("*poof* " + (who.name())) + " is now ") + what) + ".", who, this());
    return ((("Ok, " + (who.name())) + " is now ") + what) + ".";
};

protected method .grep_cmd() {
    arg @args;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo('benice) <);
    return (> pass(@args) <);
};

protected method .mojo() {
    arg @args;
    var mojo_what;
    
    if (!(this() in ($sys.system())))
        mojo_what = "do not ";
    else
        mojo_what = "";
    return .eval_message("mojo-look", $admin, #[["$actor", this()], ["actor", .name()], ["actor.pp", (.gender()).pronoun('pp)], ["mojo.what", mojo_what]]);
};

protected method .mojo_cmd() {
    arg cmdstr, cmd, str;
    var syn, line, vars;
    
    (> .perms(caller(), $user, $admin) <);
    syn = cmd + " on|off";
    if ((!str) || (!(str in ["on", "up", "off", "down"])))
        return .mojo(1);
    
    // this is horribly non-configurable--we need a standard set of subs.
    vars = #[["$actor", this()], ["actor", .name()], ["actor.pp", (.gender()).pronoun('pp)]];
    switch (str) {
        case "on", "up":
            if (this() in ($sys.system())) {
                return "You already have mojo turned on.";
            } else {
                $sys.add_to_system(this());
                (.location()).announce(.eval_message("mojo-on", $admin, vars));
            }
        case "off", "down":
            if (this() in ($sys.system())) {
                $sys.del_from_system(this());
                (.location()).announce(.eval_message("mojo-off", $admin, vars));
            } else {
                return "You don't have mojo turned on.";
            }
    }
};

public method .description() {
    arg flags;
    var vars, m;
    
    vars = #[["$actor", this()], ["actor", .name()], ["mojo.what", ""]];
    if (!(this() in ($sys.system())))
        vars = vars.add("mojo.what", "do not ");
    m = .eval_message("mojo-look", $admin, vars);
    return (> pass(flags) <) + [m];
};

protected method .logout() {
    arg @args;
    
    (| $sys.del_from_system(this()) |);
    return (> pass(@args) <);
};

protected method .check_mojo() {
    arg @benice;
    var answer, wording;
    
    if (benice)
        wording = " may require ";
    else
        wording = " requires ";
    if (!(this() in ($sys.system()))) {
        answer = (> .prompt(("This command" + wording) + "Mojo, turn it on? [yes] ") <);
        if (answer in ["no", "n"]) {
            .tell("Ok, aborting.");
            if (benice)
                return;
            throw(~stop, "");
        }
        .mojo_cmd("", "", "on");
    }
};

protected method .rehash_all_cmd() {
    arg cmdstr, cmd, args;
    var purge, o, objs, list;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    .tell("Rebuilding all caches..");
    pause();
    pause();
    
    // go atomic, we do not want confused users trying to run commands that
    // do not exist...
    $sys.atomic(1);
    catch any {
        // purge everything
        if ((o = (| "p?urge" in ((args[2]).slice(1)) |)))
            purge = ((args[2])[0])[3];
        else
            purge = 1;
        if (purge) {
            .tell("Purging caches..");
            for o in ($command_cache.descendants()) {
                (| o.purge_cache() |);
                refresh();
            }
        }
    
        // rehash non-general caches
        list = ($command_cache.children()).setremove($user_interfaces);
        list = ((list.mmap('descendants)).flatten()).compress();
        .tell(("Rehashing " + listlen(list)) + " general caches.");
        for o in (list) {
            if (!(o.is_general_cache())) {
                (| o.rehash_cache() |);
                refresh();
            }
        }
        $remote_cache.rehash_cache();
    
        // re-init user clients
        objs = (| $user_db.connected() |) || [this()];
        list = hash o in (objs) to ([(| o.location() |) || $void, 1]);
        for o in (objs + dict_keys(list)) {
            .tell("Initializing " + (o.namef('ref)));
            o.cache_client_init();
            refresh();
        }
    } with {
        .tell_traceback(traceback());
    }
    
    // ok, good...
    $sys.atomic(0);
    return "Done...";
};

protected method .finger_cmd() {
    arg cmdstr, cmd, who;
    var out, tmp;
    
    out = (> pass(cmdstr, cmd, who) <);
    if (!($sys.is_system(this())))
        return out;
    if (who.connected()) {
        out += ["  Connections:"];
        for tmp in (who.connections())
            out += [(((("    " + tmp) + ": [") + ($time.format("%d-%b-%Y/%H:%M:%S", tmp.active_since()))) + "] ") + (tmp.address())];
    }
    tmp = who.quota_byte_usage();
    return (out += ["  Quota:", "    Total:     " + ((who.quota()).to_english()), "    Used:      " + (tmp.to_english()), "    Remaining: " + (((who.quota()) - tmp).to_english())]);
};

protected method .new_password_cmd(): nooverride {
    arg cmdstr, cmd, user;
    var new, email;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    email = user.user_info("email");
    if (!email)
        return (user.namef('ref)) + " does not have an email address!";
    .tell("Generating password and mailing it to: " + email);
    new = $code_lib.random_password();
    catch any {
        $smtp.sendmail('admin, email, ("[" + ($motd.server_name())) + "] password change.", [((("The password for the user " + (user.name())) + " on ") + ($motd.server_name())) + " has been changed to:", "", "    " + new, "", "This is an automatic message sent to the supplied address.  If this message is in error simply discard it.", "", "This password was changed by " + (.name())]);
    } with {
        .tell_traceback(traceback());
        return "** Unable to send mail message, password not changed **";
    }
    user.set_password(new);
    user.tell([((("Your password has been reset by " + (.name())) + ".  The new password has been emailed to ") + email) + "."]);
    .tell((("You reset " + (user.name())) + "'s password to: ") + new);
};

protected method .core_cmd() {
    arg cmdstr, cmd, objs;
    var o, obj;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    for obj in (objs) {
        obj.add_flag('core);
        obj.change_manager(obj);
        for o in (obj.writers('literal))
            obj.del_writer(o);
        refresh();
        .tell(("Made " + (obj.namef('core))) + " a core object.");
    }
};

protected method .reap_users_cmd() {
    arg cmdstr, cmd, args;
    var u, thresh, t, reap, m, last, tl, v;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    
    // figure threshold
    if (args) {
        catch any
            thresh = $time.from_english(args);
        with
            return "You must specify the time.";
    } else {
        thresh = (86400 * 30) * 3;
    }
    t = time();
    reap = [];
    .tell([("--- Reap Possibilities starting " + ($time.to_english(thresh))) + " ago", strfmt("%28L %4l %4l %12l %l", "User", "MNGD", "WRTS", "Last On", "Age"), strfmt("%28L %4l %4l %12l %l", "----", "----", "----", "-------", "---")]);
    for u in ($user.descendants()) {
        if ((u.connected()) || ((u.has_flag('core)) || (u.is($admin))))
            continue;
        tl = (last = abs(u.connected_at()));
        if ((tl + thresh) > t)
            continue;
        m = "";
        tl = t - tl;
        if (tl / 31449600) {
            v = tl / 31449600;
            m = (v + " year") + ((v > 1) ? "s" : "");
            tl = tl % 31449600;
        }
        if (tl / 2592000) {
            v = tl / 2592000;
            m += (((m ? " " : "") + v) + " month") + ((v > 1) ? "s" : "");
            tl = tl % 2592000;
        }
        if (tl / 604800) {
            v = tl / 604800;
            m += (((m ? " " : "") + v) + " week") + ((v > 1) ? "s" : "");
        }
        if (!m)
            m = "newborn";
        reap += [[last, strfmt("%28L %4l %4l %12l %l", u.namef('xref), listlen(u.managed()), listlen(u.writes()), $time.format("%v", last), m)]];
    }
    .tell(((reap.sort()).slice(2)).reverse());
    return "---";
};

public method .uninit_admin() {
    $sys.old_admin();
};

protected method .reap_cmd() {
    arg cmdstr, cmd, args;
    var opts, thresh, i;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    [args, opts] = (> $parse_lib.opt(args, "t?ime", "m?ail") <);
    args = args.join();
    if ((i = "t?ime" in (opts.slice(1)))) {
        catch any
            thresh = $time.from_english((opts[i])[4]);
        with
            return (traceback()[1])[2];
    }
    if ("m?ail" in (opts.slice(1)))
        return ._reap__mail(args, thresh || (86400 * 7));
    if (args)
        return (> ._reap__user(args) <);
    else
        return (> ._reap__list(thresh || ((86400 * 30) * 3)) <);
};

private method ._reap__list() {
    arg thresh;
    var t, reap, u, tl, m, v, n, last;
    
    t = time();
    reap = [];
    .tell([("--- Reap Possibilities (Not connected for " + ($time.to_english(thresh))) + ")", strfmt("E %21L %3l %10l %10l %10l %l", "User", "MNG", "Created", "Notified", "Last On", "Idle"), strfmt("- %21L %3l %10l %10l %10l %l", "----", "---", "-------", "-------", "-------", "----")]);
    for u in ($user.descendants()) {
        pause();
        if ((u.connected()) || ((u.has_flag('core)) || (u.is($admin))))
            continue;
        tl = (last = abs(u.connected_at()));
        if ((tl + thresh) > t)
            continue;
        m = "";
        tl = t - tl;
        if (tl / 31449600) {
            v = tl / 31449600;
            m = (v + " yr") + ((v > 1) ? "s" : "");
            tl = tl % 31449600;
        }
        if (tl / 2592000) {
            v = tl / 2592000;
            m += (((m ? " " : "") + v) + " mnth") + ((v > 1) ? "s" : "");
            tl = tl % 2592000;
        }
        if (tl / 604800) {
            v = tl / 604800;
            m += (((m ? " " : "") + v) + " wk") + ((v > 1) ? "s" : "");
        }
        if (!m)
            m = "newborn";
        if (u._reap__notified())
            n = $time.format("%e-%b-%y", u._reap__notified());
        else
            n = "";
        reap += [[last, strfmt("%s %21L %3l %10l %10l %10l %l", ((u.get_setting("rl-email", $user_info))[2]) ? " " : "!", u.name(), listlen(u.managed()), $time.format("%e-%b-%y", u.created_on()), n, $time.format("%e-%b-%y", last), m)]];
    }
    .tell(((reap.sort()).slice(2)).reverse());
    return "---";
};

private method ._reap__user() {
    arg str;
    var user, ans, managed, obj, reapq, nuke, name, keep;
    
    user = (| $user_db.search(str) |);
    if (!user) {
        catch any
            user = $object_lib.to_dbref(str);
        with
            return ("Unable to find user " + str) + ".";
    }
    if (!(> $parse_lib.ask(("Reap " + (user.namef('ref))) + "? [no] ") <))
        return "Aborting reap.";
    managed = setremove(user.managed(), user);
    nuke = (keep = []);
    if (managed) {
        .tell(["", (((user.namef('ref)) + " has ") + (managed.length())) + " object(s)."]);
        reapq = ["Scan this list item by item? [yes] "];
        if ((> $parse_lib.ask(reapq, "(yes|y)", "yes") <)) {
            reapq = ["", ("Reap this object managed by " + (user.namef('ref))) + "? [yes] "];
            for obj in (managed) {
                .tell("");
                .tell($object_lib.format_object(obj, 0));
                if ((> $parse_lib.ask(reapq, "(yes|y)", "yes") <))
                    nuke = setadd(nuke, obj);
                else
                    keep = setadd(keep, obj);
            }
        } else {
            nuke = managed;
        }
    } else {
        .tell(("User " + (user.namef('ref))) + " owns no objects");
    }
    if (nuke) {
        .tell(["WRT TST Object", "--- --- ------"]);
        for obj in (nuke)
            .tell(strfmt("%3r %3r %s", listlen(obj.writers('literal)), listlen(obj.trusted('literal)), obj.namef('ref)));
        .tell("");
        if ((> $parse_lib.ask("Destroy these objects? [yes] ", "(yes|y)", "yes") <)) {
            for obj in (nuke) {
                // must have been nuked already
                if (!valid(obj))
                    continue;
                name = obj.namef('ref);
                catch any {
                    obj.destroy();
                } with {
                    .tell("--- While Destroying " + name);
                    .tell_traceback(traceback());
                }
            }
        }
    }
    for obj in (keep)
        .tell((("Changed Manager for " + (obj.namef('ref))) + " to ") + ($reaper.namef('ref)));
    if (!(> $parse_lib.ask(("Destroy " + (user.namef('ref))) + "? ") <))
        return "Not destroying " + (user.namef('ref));
    name = user.namef('ref);
    catch any {
        user.destroy();
    } with {
        .tell("--- While Destroying " + name);
        .tell_traceback(traceback());
    }
    return ("Done reaping " + name) + ".";
};

private method ._reap__mail() {
    arg str, interval;
    var email, msg, subj, ps, po, user;
    
    user = (| $user_db.search(str) |);
    if (!user) {
        catch any
            user = $object_lib.to_dbref(str);
        with
            return ("Unable to find user " + str) + ".";
    }
    email = user.user_info("email");
    ps = (user.gender()).pronoun('ps);
    po = (user.gender()).pronoun('po);
    subj = ("[" + ($motd.server_name())) + "] IMMINENT USER REAPING";
    msg = (((((((((("Your user account " + (user.namef('ref))) + " on ") + ($motd.server_name())) + " is slated for reaping, possibly due to inactivity.  If you do not connect within ") + ($time.to_english(interval))) + " ") + ps) + " and all objects managed by ") + po) + " will be destroyed.  This is an automatic message sent to the supplied email address.  If this message is in error simply discard it.").wrap_lines(75);
    .tell("---");
    .tell("To: " + email);
    .tell("Subject: " + subj);
    .tell("");
    .tell(msg);
    .tell("---");
    if (!(> $parse_lib.ask("Send this email message? [yes] ", "(yes|y)", "yes") <))
        return "Message not sent.";
    catch any {
        $smtp.sendmail('admin, email, subj, msg);
    } with {
        .tell_traceback(traceback());
        return "** Unable to send message";
    }
    user.set_reap_notified(time());
    return "Message sent.";
};

protected method .quota_cmd() {
    arg cmd, cmdstr, object, prep, ops;
    var object, value, exempt;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    value = ops[1];
    value = (value && (| toint(value[1]) |)) ? toint(value[1]) : (-1);
    exempt = "e?xempt" in ((ops[2]).slice(1));
    exempt = exempt ? (((ops[2])[exempt])[3]) : (-1);
    if (value != (-1)) {
        object.set_quota(value);
        .tell((((object.name()) + " now has a quota of ") + (value.to_english())) + ".");
    }
    if (exempt != (-1)) {
        object.set_quota_exempt(exempt);
        .tell((((object.name()) + " is ") + (exempt ? "now" : "no longer")) + " quota exempt.");
    }
};

protected method .login() {
    arg connection;
    
    pass(connection);
    (> $sys.configure_core() <);
};

public method .move_cmd() {
    arg cmd, cmdstr, args;
    var how;
    
    // Is this moving or a copy?
    how = match_begin(cmd, "@c") ? 'copy : 'move;
    if (how == 'move) {
        if ((((args[1])[1]) == 'object) && (((args[1])[2]).is($user)))
            (> .check_mojo('benice) <);
    }
    return (> pass(cmd, cmdstr, args) <);
};

public method .kick_cmd() {
    arg cmdstr, cmd, user;
    var x, u, uname;
    
    (> .check_mojo() <);
    catch ~namenf {
        u = $user_db.match(user);
        uname = u.name();
        u.tell((sender().name()) + " has kicked you from the system.");
        pause();
        for x in (u.connections())
            x.destroy();
        sender().tell(uname + " has been kicked from the system.");
    } with {
        sender().tell(("Usage: " + cmd) + " <player name>.");
    }
};

protected method .status_cmd() {
    arg cmdstr, com, @args;
    var opt, cache, x, y, width, depth, info, out, str, pre, dstr, dirty, c;
    
    (> .perms(caller(), 'command) <);
    opt = (> $parse_lib.opt(args.join(" "), "c?ache", "d?irtyonly") <);
    if ((x = "c?ache" in ((opt[2]).slice(1))))
        cache = 1;
    if (!cache)
        return pass(cmdstr, com, @args);
    [width, depth, info] = $sys.cache_info();
    out = [((((("Cache Size: " + width) + "x") + depth) + " (") + (width * depth)) + " total object capacity)"];
    info = map x in (info) to (strsub(x, "i", ".", "c"));
    if (width < 80) {
        if (width < 78) {
            pre = 1;
            str = " +";
        } else {
            pre = 0;
            str = "";
        }
        str = strfmt(str + "%*{-}c", width, " WIDTH ");
        out += ["Cache Map (Horizontal):", str];
        dstr = "DEPTH";
        for y in [1 .. depth] {
            if (pre) {
                if (y <= strlen(dstr))
                    str = (dstr[y]) + "|";
                else
                    str = " |";
            } else {
                str = "";
            }
            for x in [1 .. width] {
                refresh();
                if (strlen(info[x]) >= y) {
                    c = (info[x])[y];
                    str += (info[x])[y];
                } else {
                    str += " ";
                }
            }
            out += [str];
        }
        if (pre)
            out += [" +" + ("-" * width)];
        else
            out += ["-" * width];
    } else {
        str = strfmt(" +%*{-}c", depth, " DEPTH ");
        out += ["Cache Map (Vertical):", str] + (info.prefix(" |"));
    }
    return out + ["Object Legend: a=active, A=active+dirty, .=inactive, I=inactive+dirty"];
};

public method .scour_cmd() {
    arg cmdstr, cmd, line;
    var allopts, opts, parse, comp, neg, match, list, start, end, obj, pos, found, out, i, x, y;
    
    // command requires mojo for full search, so check it
    (> .check_mojo() <);
    
    // check to see if arguments have been provided
    if (!line)
        return .tell("Syntax: @scour <scope> [{comparison}] [range] [options]");
    
    // determine the scope of the search: method, variable, or setting
    if ((parse = line.regexp("\.([a-zA-Z0-9_]+)\((.*)\)")))
        parse = (| ['method, ".", (parse[1]).to_symbol(), fromliteral(("[" + (parse[2])) + "]")] |);
    else if ((parse = line.regexp(",([a-zA-Z0-9_]+)")))
        parse = (| ['variable, ",", (parse[1]).to_symbol()] |);
    else if ((parse = line.regexp(":([a-zA-Z0-9-]+)")))
        parse = (| ['setting, ":", parse[1]] |);
    else
        return .tell("Scope parse failed.");
    
    // if provided, find the basis of comparison
    refresh();
    comp = line.regexp("{(.+)}");
    if (comp) {
        comp = comp[1];
    
        //    if (line[line.index("{") - 1] == "!")
        if ((line[stridx(line, "{") - 1]) == "!")
            neg = 1;
    }
    
    // parse options and determine the objects to be scoured
    refresh();
    allopts = ["d?escend", "m?atch"];
    opts = ($parse_lib.opt(line, @allopts))[2];
    catch ~namenf {
        if ((pos = "d?escend" in (opts.slice(1)))) {
            start = $object_lib.to_dbref(((opts[pos])[4]).strip("'"));
            list = [start, @start.descendants()];
        } else if ((| ([start, end] = line.regexp("([^ .]+) ?\.\. ?([^ .]+)")) |)) {
            [start, end] = map i in ([start, end]) to ($object_lib.to_dbref(i));
            list = map i in [toint(start) .. toint(end)] to (refresh() && toobjnum(i));
            list = filter i in (list) where (refresh() && valid(i));
        } else {
            return .tell("You must specify a range of objects or an object from which to descend.");
        }
    } with {
        return .tell((traceback()[1])[2]);
    }
    if ((pos = "m?atch" in (opts.slice(1)))) {
        match = map i in ((allopts = ["r?egexp", "t?emplate", "e?quals"])) to (((opts[pos])[4]).match_template(i));
        if (match[1])
            match = 'regexp;
        else if (match[2])
            match = 'match_template;
        else if (match[3])
            match = 'equals;
        else
            return .tell((((opts[pos])[4]) + " is not a valid matching type: ") + (allopts.to_english()));
    }
    
    // defaults
    refresh();
    match ?= 'regexp;
    
    // scours the database and makes comparisons
    .tell(["Beginning analysis...", "".pad(79, "-")]);
    for obj in (list) {
        refresh();
        catch any {
            switch (parse[1]) {
                case 'method:
                    i = toliteral(obj.(parse[3])(@parse[4]));
                    if (comp) {
                        if (neg ? i.(match)(comp) : (!i.(match)(comp)))
                            continue;
                    }
                    found = 1;
                    .tell([tostr(obj), "  %20e  %55e".format((parse[2]) + tostr(parse[3]), i)]);
                case 'variable:
                    out = [];
                    for x in (obj.data()) {
                        refresh();
                        if (valid(x[1]) && ((parse[3]) in (((obj.data())[x[1]]).keys()))) {
                            i = toliteral(((obj.data())[x[1]])[parse[3]]);
                            if (comp) {
                                if (neg ? i.(match)(comp) : (!i.(match)(comp)))
                                    continue;
                            }
                            out += [("  <" + (x[1])) + ">", "    %20e  %50e".format((parse[2]) + tostr(parse[3]), i)];
                        }
                    }
                    if (!out)
                        continue;
                    found = 1;
                    .tell([tostr(obj), @out]);
                case 'setting:
                    if ((parse[3]) in ((pos = obj.all_defined_settings()).keys())) {
                        i = toliteral(obj.get_setting(parse[3], pos[parse[3]]));
                        if (comp) {
                            if (neg ? i.(match)(comp) : (!i.(match)(comp)))
                                continue;
                        }
                        found = 1;
                        .tell([tostr(obj), "  %20e  %55e".format((parse[2]) + (parse[3]), i)]);
                    }
                    continue;
            }
        } with {
            continue;
        }
    }
    if (!found)
        .tell("No matches found.");
    .tell(["".pad(79, "-"), "Finished."]);
    
    // $#Created: 22 Jul 98 20:09 $kirnamat
};

protected method .__cache_stats_display() {
    arg cache_stats_type;
    var cache_stats_data, headers, output, title;
    
    catch ~type {
        // If you are using Genesis 1.2, decomment this
        //      cache_stats_data = cache_stats(cache_stats_type);
        cache_stats_data = [];
    } with {
        return .tell(("Invalid cache type (" + toliteral(cache_stats_type)) + ") specified.");
    }
    if ((cache_stats_type == 'method_cache) || (cache_stats_type == 'ancestor_cache)) {
        if (cache_stats_type == 'method_cache)
            title = "Method Cache:";
        else
            title = "Ancestor Cache:";
        headers = [["Generation", "----------"], ["Hits", "----"], ["Misses", "------"], ["Partial Invalidations", "---------------------"]];
        cache_stats_data = cache_stats_data.transpose();
    } else if (cache_stats_type == 'name_cache) {
        title = "Name Cache:";
        headers = [["Hits", "----"], ["Misses", "------"]];
        cache_stats_data = [[cache_stats_data[1]], [cache_stats_data[2]]];
    }
    output = cache_stats_data.tabulate(headers);
    .tell(title);
    .tell(output);
};

protected method .cache_stats_cmd() {
    arg cmdline, cmd, @args;
    var opt, want_all, done;
    
    opt = (> $parse_lib.opt(args.join(" "), "m?ethods", "n?ame", "a?ncestor", "all") <);
    if ("all" in ((opt[2]).slice(1)))
        want_all = 1;
    if (want_all || ("m?ethods" in ((opt[2]).slice(1)))) {
        .__cache_stats_display('method_cache);
        done++;
    }
    if (want_all || ("n?ame" in ((opt[2]).slice(1)))) {
        if (done)
            .tell("");
        .__cache_stats_display('name_cache);
        done++;
    }
    if (want_all || ("a?ncestor" in ((opt[2]).slice(1)))) {
        if (done)
            .tell("");
        .__cache_stats_display('ancestor_cache);
        done++;
    }
    if (!done) {
        .tell("You can get driver cache statistics for:");
        .tell("  * Method cache (+m?ethods)");
        .tell("  * Name cache (+n?ame)");
        .tell("  * Ancestor cache (+a?ncestor)");
        .tell("  * All caches (+all)");
    }
    .tell("---");
};


new object $in_location: $located_location;

var $root manager = $in_location;
var $root created_on = 809991552;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core, 'fertile];
var $has_commands shortcuts = #[];
var $has_commands remote = #[["open", [["open", "*", "open <this>", 'open_cmd, #[[1, ['this, []]]]]]], ["close", [["close", "*", "close <this>", 'close_cmd, #[[1, ['this, []]]]]]]];
var $has_commands local = #[];
var $has_name name = ['prop, "in_location", "in_location"];
var $described prose = [];
var $location contents = [];
var $located location = $nowhere;
var $located obvious = 1;
var $root settings = #[["locked", 0], ["lockable", 0], ["closable", 0], ["closed", 0]];
var $command_cache modules = [];
var $command_cache commands = 0;
var $thing gender = $gender_neuter;
var $root defined_settings = #[["locked", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["lockable", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["closable", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["closed", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $command_cache shortcuts = 0;
var $foundation defined_msgs = #[["open", #[['branches, ["general", "actor", "inside"]]]], ["close", #[['branches, ["general", "actor", "inside"]]]]];
var $foundation msgs = #[["open", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " opens ", <$generator, ["this", [], [], 'gen_this]>, "."], #[]]>], ["inside", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " opens ", <$generator, ["this", [], [], 'gen_this]>, "."], #[]]>], ["actor", <$ctext_frob, [["You open ", <$generator, ["this", [], [], 'gen_this]>, "."], #[]]>]]], ["close", #[["inside", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " closes ", <$generator, ["this", [], [], 'gen_this]>, "."], #[]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " closes ", <$generator, ["this", [], [], 'gen_this]>, "."], #[]]>], ["actor", <$ctext_frob, [["You close ", <$generator, ["this", [], [], 'gen_this]>, "."], #[]]>]]]];
var $root managed = [$in_location];

public method .description() {
    arg flags;
    var line;
    
    if ((sender().location()) == this()) {
        return (> .inside_description(flags) <);
    } else {
        if (.get_setting("closed", $in_location))
            line = (((.gender()).pronoun('ps)).capitalize()) + " is closed.";
        else
            line = (("Inside " + (.name())) + " you see: ") + ((.contents()).map_to_english('name));
        return (> pass(flags) <) + [line];
    }
};

public method .open_cmd() {
    arg cmdstr, cmd, this;
    var vars, m;
    
    if (.get_setting("closable", $in_location)) {
        if (.get_setting("closed", $in_location)) {
            .set_setting("closed", $in_location, "no");
            vars = #[["$actor", sender()], ["actor", sender().name()], ["$this", this()], ["this", .name()], ["$inside", this()]];
            m = .eval_message("open", $in_location, vars);
            (.location()).announce(m, sender());
            .announce(m, sender());
            return m;
        } else {
            return ((.name()).capitalize()) + " is already opened.";
        }
    } else {
        return ((.name()).capitalize()) + " cannot be opened.";
    }
};

public method .close_cmd() {
    arg cmdstr, cmd, this;
    var vars, m;
    
    if (.get_setting("closable", $in_location)) {
        if (.get_setting("closed", $in_location)) {
            return ((.name()).capitalize()) + " is already closed.";
        } else {
            .set_setting("closed", $in_location, "yes");
            vars = #[["$actor", sender()], ["actor", sender().name()], ["$this", this()], ["this", .name()], ["$inside", this()]];
            m = .eval_message("close", $in_location, vars);
            (.location()).announce(m, sender());
            .announce(m, sender());
            return m;
        }
    } else {
        return ((.name()).capitalize()) + " cannot be closed.";
    }
};


new object $lost_and_found: $in_location;

var $root manager = $lost_and_found;
var $root created_on = 806811775;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $has_name name = ['prop, "Lost and Found box", "Lost and Found box"];
var $described prose = [];
var $location contents = [];
var $located location = $void;
var $located obvious = 1;
var $thing lock = <$object_lock_frob, [$void]>;
var $root managed = [$lost_and_found];
var $thing gender = $gender_neuter;
var $root settings = #[["home", $lost_and_found]];
var $command_cache commands = 0;


new object $introtut_mailbox: $in_location;

var $root manager = $introtut_mailbox;
var $thing lock = <$object_lock_frob, [$introtut_look]>;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874177644;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['normal, "small mailbox", "a small mailbox"];
var $described prose = <$ctext_frob, [["Just your standard mailbox, except that somone has built a wooden dairy cow around it. ", <$format, ["np", [], [], 'do_np]>, "This mailbox is a type of container; it can hold other objects. When you look at an open container, you also get a listing of its contents, if the container is closed it will simply tell you 'It is closed.' To open the mailbox, type:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["open the mailbox"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The mailbox may already be open; if so, you may want to try closing it and opening it again. Once the mailbox is open, you will see that it contains a leaflet. To read the leaflet, type:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["look at leaflet in mailbox"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>], #[]]>;
var $location contents = [$introtut_leaflet];
var $located location = $introtut_look;
var $located obvious = 1;
var $thing gender = $gender_neuter;
var $root inited = 1;
var $root settings = #[["closable", 1], ["closed", 1]];
var $command_cache shortcuts = 0;
var $has_name templates = ["box"];
var $root managed = [$introtut_mailbox];
var $command_cache modules = [];
var $command_cache commands = 0;


new object $trash: $located_location;

var $root manager = $trash;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 830126811;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['uniq, "System Trash Can", "the System Trash Can"];
var $described prose = <$ctext_frob, [["When you discard something, it goes here if you do not manage it."], #[]]>;
var $location contents = [];
var $located location = $void;
var $located obvious = 1;
var $root inited = 1;
var $command_cache shortcuts = 0;
var $trash items = #[];
var $root managed = [$trash];
var $command_cache modules = [];
var $thing gender = $gender_neuter;
var $event_handler hooks = #[];
var $command_cache commands = 0;

public method .did_leave() {
    arg mover, place;
    
    (> pass(mover, place) <);
    (| (items = items.del(sender())) |);
};

public method .did_arrive() {
    arg mover, place;
    var msg;
    
    (> pass(mover, place) <);
    (| (items = items.add(sender(), time())) |);
};

public method .del_sender_from_contents() {
    pass();
    items = dict_del(items, sender());
};


new object $on_location: $thing, $location;

var $root manager = $on_location;
var $root created_on = 809991549;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core, 'fertile];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "on_location", "on_location"];
var $described prose = [];
var $located location = $nowhere;
var $located obvious = 1;
var $root managed = [$on_location];
var $location contents = [];
var $thing gender = $gender_neuter;
var $command_cache commands = 0;
var $command_cache shortcuts = 0;

public method .description() {
    arg flags;
    var line;
    
    line = ((("You see " + ((.contents()).map_to_english('namef, 'name))) + " on ") + (.name())) + ".";
    return (> pass(flags) <) + [line];
};

public method .announce() {
    arg what, @except;
    var loc;
    
    pass(what, @except);
    loc = .location();
    loc.announce(what, @except, this());
    if (!(loc in except))
        (| loc.tell(what) |);
};


new object $realm_settings: $foundation;

var $root manager = $realm_settings;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854028767;
var $root inited = 1;
var $root defined_settings = #[["map-position", #[['get, ['get_realm_setting]], ['parse, ['parse_map_position]], ['format, ['format_map_position]]]], ["propagate", #[['get, ['get_realm_setting]], ['parse, ['is_propagator]], ['format, ['format_propagator]]]]];
var $root settings = #[["propagate", 0], ["map-position", 0]];
var $root managed = [$realm_settings];
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];

public method .get_realm_setting() {
    arg name, definer, @args;
    var v, t;
    
    t = this();
    if (.has_ancestor($place)) {
        if ((.settings()).contains(name))
            return .get_local_setting(name, definer);
        return (.realm()).get_realm_setting(name, definer, @args);
    } else if ((.settings()).contains(name)) {
        return .get_local_setting(name, definer);
    } else {
        return ((.parents())[1]).get_realm_setting(name, definer, @args);
    }
};

public method .will_propagate() {
    return .get_setting("propagate", definer());
};

public method .parse_map_position() {
    arg value;
    
    if (value in ["n", "no", "none", "0"])
        return 0;
    if (type(value) == 'list)
        value = value.join();
    value = (| (value.match_pattern("window *,* tag * on *")).mmap('trim) |);
    if (!value)
        throw(~parse, "Syntax: window <x>,<y> tag <tag> on <mapobject>");
    return (> [toint(value[1]), toint(value[2]), value[3], $object_lib.to_dbref(value[4])] <);
};

public method .format_map_position() {
    arg value;
    
    if (!value)
        return "none";
    return "window %l, %l tag %l on %l".format(@value);
};

root method .core_realm_settings() {
    .set_setting("map-position", definer(), "none");
    .set_setting("propagate", definer(), "none");
};


new object $place: $location, $realm_settings;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core, 'general_cache];
var $described prose = [];
var $has_name name = ['uniq, "place", "the place"];
var $place realm = $realm_of_creation;
var $place exits = [];
var $place darkness = 0;
var $location contents = [];
var $place entrances = 0;
var $command_cache modules = [];
var $root manager = $place;
var $has_commands local = #[];
var $foundation defined_msgs = #[["housekeeper", #[['branches, ["general"]]]], ["connect", #[['branches, ["general"]]]], ["disconnect", #[['branches, ["general"]]]]];
var $foundation msgs = #[["housekeeper", #[["general", <$ctext_frob, [["The housekeeper arrives and takes ", <$generator, ["actor", [], [], 'gen_actor]>, "'s body away."], #[]]>]]], ["connect", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " wakes up."], #[['this, $place]]]>]]], ["disconnect", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " falls asleep."], #[['this, $place]]]>]]]];
var $root defined_settings = #[["public-home", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["realm", #[['get, ['realm]], ['set, ['set_setting_realm]], ['parse, ['parse_realm_setting]], ['clear, ['clear_realm_setting]]]], ["darkness", #[['get, ['darkness]], ['set, ['set_darkness]], ['parse, ['is_type, 'integer]]]], ["restrict-entry", #[['get, ['get_restrict_entry]], ['set, ['set_restrict_entry]], ['parse, ['parse_restrict_entry]], ['format, ['format_restrict_entry]]]]];
var $root settings = #[["public-home", 0], ["map-position", 0], ["propagate", 0]];
var $root managed = [$place];
var $place restrict_entry = 0;
var $command_cache commands = 0;
var $command_cache shortcuts = 0;

root method .init_place() {
    exits = (entrances = []);
    .set_realm($realm_of_creation);
};

root method .uninit_place() {
    var x;
    
    for x in (exits + entrances)
        (| x.place_destroyed(this()) |);
    (| realm.place_destroyed(this()) |);
    (| $place_db.place_destroyed(this()) |);
};

public method .environment() {
    return pass() + exits;
};

public method .description() {
    arg f;
    var e;
    
    e = .visible_exits();
    return ((> pass(f) <) + [.format_contents(f)]) + (.format_exits(e, f));
};

public method .exits() {
    if (!(caller() in [$command_parser, $user]))
        (> .perms(sender()) <);
    return exits;
};

public method .did_connect() {
    (> .perms(caller(), $user) <);
    if ((.visibility()) >= 0)
        .announce(.eval_message("connect", $place, #[["$actor", sender()], ["actor", sender().name()], ["$here", this()], ["here", .name()]]), sender());
};

public method .did_disconnect() {
    (> .perms(caller(), $user) <);
    if ((.visibility()) >= 0)
        .announce(.eval_message("disconnect", $place, #[["$actor", sender()], ["actor", sender().name()], ["$here", this()], ["here", .name()]]), sender());
};

public method .realm() {
    arg @args;
    
    return realm;
};

public method .did_housekeep() {
    arg who;
    var m, v;
    
    (> .perms(sender(), $housekeeper) <);
    if (!(| (.realm()).get_setting("housekeeper-notify", $realm) |))
        return;
    .announce(.eval_message("housekeeper", $place, #[["$actor", who], ["actor", who.name()], ["$here", this()], ["here", .name()]]));
};

public method .set_name() {
    arg new_name, @args;
    var old_name;
    
    old_name = .name();
    (> pass(new_name, @args) <);
    (| $place_db.room_changed_name(old_name) |);
};

public method .set_realm() {
    arg value;
    
    (caller() == $realm) || ((sender() == this()) || (> .perms(sender()) <));
    realm = value.new();
};

public method .format_exits() {
    arg exits, flags;
    var output, e, exits, line, actor, how, exit;
    
    actor = flags['actor];
    how = (flags['actor]).get_setting("exit-style", $user);
    switch (how) {
        case 'none:
            return [];
        case 'brief:
            if (!exits)
                return [];
            return [$ctext_frob.new_with(["Visible Exits: ", $cml_lib.generate_english_tag(map exit in (exits) to ($cml_lib.format_obj_tag('look, exit, exit.path_name(this()), 'exit))), $cml_lib.format_br_tag()])];
        case 'templates:
            output = [];
            for e in (exits) {
                if (e.name_templates())
                    output += [$cml_lib.format_obj_tag('look, e, (((e.path_name(this())) + " (") + ((e.name_templates()).to_english())) + ")", 'exit)];
                else
                    output += [$cml_lib.format_obj_tag('look, e, e.path_name(this()), 'exit)];
            }
            return output ? [$ctext_frob.new_with(["Visible Exits: ", $cml_lib.generate_english_tag(output), $cml_lib.format_br_tag()])] : [];
        case 'long:
            output = [];
            for e in (exits)
                output += [(("  " + (e.path_name(this()))) + " to ") + ((e.dest(this())).name())];
            return output ? (["Visible Exits: "] + (output.lcolumnize(actor.linelen()))) : [];
        case 'verbose:
            output = [];
            for e in (exits) {
                if (e.name_templates())
                    line = (((e.path_name(this())) + " (") + ((e.name_templates()).to_english("no templates"))) + ")";
                else
                    line = e.path_name(this());
                output += [(("  " + line) + " to ") + ((e.dest(this())).name())];
            }
            return output ? ["Visible Exits: ", @output.lcolumnize(actor.linelen())] : [];
    }
    return [];
};

public method .format_contents() {
    arg flags;
    var users, br, exclude, actor, objects, output, obj, line, item, formatteduser, formattedobj;
    
    // called by .description
    users = [];
    objects = [];
    actor = flags['actor];
    exclude = (| flags['exclude] |) || [];
    for obj in (.contents()) {
        if ((!(obj in exclude)) && ((obj != actor) && (| obj.is_obvious_to(actor) |))) {
            if (obj.has_ancestor($body))
                users += [obj];
            else
                objects += [obj];
        }
    }
    output = $ctext_frob.new_with([]);
    br = $cml_lib.format_br_tag();
    if (users) {
        formatteduser = map item in (users) to ($cml_lib.format_obj_tag('look, item, item.namef('nactivity)));
        formatteduser = [$cml_lib.generate_english_tag(formatteduser), ((users.length()) > 1) ? " are here." : " is here.", br];
        line = $ctext_frob.new_with(formatteduser);
    
        //output += [br, line];
        output = output.append(line);
    }
    if (objects) {
        formattedobj = map item in (objects) to ($cml_lib.format_obj_tag('look, item, item.name()));
        formattedobj = ["You see ", $cml_lib.generate_english_tag(formattedobj), " here.", br];
        line = $ctext_frob.new_with(formattedobj);
    
        //output += [br, line];
        output = output.append(line);
    }
    return output;
};

public method .visible_exits() {
    var obv, exit;
    
    obv = [];
    for exit in (exits) {
        if ((exit.visibility()) >= (.visibility()))
            obv += [exit];
    }
    return obv;
};

public method .realm_name() {
    arg @ctype;
    
    [(ctype ?= "text/plain")] = ctype;
    switch (ctype) {
        case "text/html":
            return (((.hname()) + " (") + ((| (realm.realm_name()).to_html() |) || "&lt;unknown&gt;")) + ")";
        default:
            return (((.name()) + " (") + ((| realm.realm_name() |) || "<unknown>")) + ")";
    }
};

public method .will_attach() {
    arg type, @by_whom;
    
    [(by_whom ?= sender())] = by_whom;
    if ((.realm()).is_buildable_by(by_whom))
        return 1;
    if ((| .trusts(by_whom) |))
        return 1;
    if (.get_setting("public-home", $place))
        return 1;
    throw(~perm, "Place is not publicly extendable.");
};

public method .visible_exits_formatted() {
    arg actor, how;
    var output, ex, exits, line;
    
    exits = .visible_exits();
    switch (how) {
        case 'none:
            return [];
        case 'brief:
            if (!exits)
                return [];
            return ["Exits: " + ($list.to_english($list.mmap(exits, 'name), "none"))];
        case 'average:
            output = [];
            for ex in (exits) {
                line = (ex.name()) + " (";
                line += $list.to_english(ex.name_templates(), "no, templates");
                output += [line];
            }
            return output ? ["Exits: " + ($list.to_english(output))] : [];
        case 'long:
            output = [];
            for ex in (exits)
                output += [((("  " + (ex.name())) + " (to ") + ((ex.dest()).name())) + ")"];
            return output ? ["Exits: ", @$list.lcolumnize(output, actor.linelen())] : [];
        case 'verbose:
            output = [];
            for ex in (exits) {
                line = ex.prose();
                if (!line)
                    line = [ex.name()];
                output += [line[1]];
            }
            return output ? [output.join()] : [];
    }
};

public method .place_destroyed() {
    arg place;
    var e;
    
    (> .perms(caller(), $place, $realm) <);
    for e in (exits) {
        if ((e.dest()) == sender())
            e.destination_destroyed();
    }
};

public method .set_objname(): nooverride {
    arg new_objname;
    
    if ((caller() != $place) && (!(sender() in ($sys.system()))))
        throw(~perm, "Place objname can only be changed by $place.");
    (> pass(new_objname) <);
};

public method .attach_exit() {
    arg type, exit;
    
    if (!(caller().is($path)))
        throw(~perm, "Caller is not an exit.");
    if (type == 'source) {
        (| (.realm()).add_exit_to(exit.dest()) |);
        exits = setadd(exits, exit);
    } else {
        entrances = setadd(entrances, exit);
    }
};

public method .did_arrive() {
    arg mover, place;
    
    pass(mover, place);
    .cache_client_init();
};

public method .darkness() {
    arg @args;
    
    return darkness;
};

public method .set_setting_realm() {
    arg name, definer, value, @args;
    
    (> .perms(sender()) <);
    .set_realm(value);
};

public method .prose() {
    arg @no_default;
    var ret;
    
    ret = pass(@no_default);
    if (type(ret) == 'frob)
        (| (ret = ret.set_vars((.realm()).ctext_variables())) |);
    return ret;
};

public method .detach_exit() {
    arg type, exit;
    
    if (!(caller().is($path)))
        throw(~perm, "Caller is not an exit.");
    if (type == 'source)
        exits = setremove(exits, exit);
    else
        entrances = setremove(entrances, exit);
};

public method .entrances() {
    (| .perms(caller(), definer(), $command_parser) |) || (> .perms(sender()) <);
    return entrances;
};

root method .core_place(): nooverride {
    .set_realm($realm_of_creation);
};

public method .is_connected_to() {
    arg dest;
    var i;
    
    (> .perms(caller(), $realm) <);
    for i in (exits) {
        if ((| dest == (i.dest()) |))
            return 1;
    }
    return 0;
};

public method .parse_realm_setting() {
    arg value, @args;
    var realm;
    
    realm = $place_lib.match_realm(value);
    if (!realm)
        throw(~invrealm, ("Unable to find the realm " + value) + ".");
    else if (!(realm.is($realm)))
        throw(~invrealm, (realm.namef('ref)) + " is not a realm.");
    return realm;
};

public method .clear_realm_setting() {
    arg name;
    
    (> .perms(sender()) <);
    realm = $realm_of_creation;
};

public method .old_format_content() {
    arg flags;
    var users, br, exclude, actor, objects, output, obj, line;
    
    // called by .description
    users = [];
    objects = [];
    actor = flags['actor];
    exclude = (| flags['exclude] |) || [];
    for obj in (.contents()) {
        if ((!(obj in exclude)) && ((obj != actor) && (| obj.is_obvious_to(actor) |))) {
            if (obj.has_ancestor($body))
                users += [obj.namef('nactivity)];
            else
                objects += [obj.name()];
        }
    }
    output = [];
    br = (<$format, ["br", [], [], 'do_br]>);
    if (users) {
        line = ($list.to_english(users)) + " ";
        line = (line + (((users.length()) > 1) ? "are" : "is")) + " here.";
    
        //output += [br, line];
        output += [line];
    }
    if (objects) {
        line = "You see ";
        line = (line + ($list.to_english(objects))) + " here.";
    
        //output += [br, line];
        output += [line];
    }
    return output;
};

public method .set_darkness() {
    arg name, definer, value, @args;
    
    (> .perms(sender()) <);
    darkness = value;
};

public method .old_format_exits() {
    arg exits, flags;
    var output, e, exits, line, actor, how, exit;
    
    actor = flags['actor];
    how = (flags['actor]).get_setting("exit-style", $user);
    switch (how) {
        case 'none:
            return [];
        case 'brief:
            if (!exits)
                return [];
            return [$ctext_frob.new_with(["Visible Exits: ", $cml_lib.generate_english_tag(map exit in (exits) to ($cml_lib.format_obj_tag('look, exit, exit.name(), 'exit)))])];
        case 'templates:
            output = [];
            for e in (exits) {
                if (e.name_templates())
                    output += [$cml_lib.format_obj_tag('look, e, (((e.name()) + " (") + ((e.name_templates()).to_english())) + ")", 'exit)];
                else
                    output += [$cml_lib.format_obj_tag('look, e, e.name(), 'exit)];
            }
            return output ? [$ctext_frob.new_with(["Visible Exits: ", $cml_lib.generate_english_tag(output)])] : [];
        case 'long:
            output = [];
            for e in (exits)
                output += [(("  " + (e.name())) + " to ") + ((e.dest()).name())];
            return output ? (["Visible Exits: "] + (output.lcolumnize(actor.linelen()))) : [];
        case 'verbose:
            output = [];
            for e in (exits) {
                if (e.name_templates())
                    line = (((e.name()) + " (") + ((e.name_templates()).to_english("no templates"))) + ")";
                else
                    line = e.name();
                output += [(("  " + line) + " to ") + ((e.dest()).name())];
            }
            return output ? ["Visible Exits: ", @output.lcolumnize(actor.linelen())] : [];
    }
    return [];
};

public method .clear_entrances() {
    entrances = [];
};

public method .add_as_entrance() {
    arg path;
    
    entrances = setadd(entrances, path);
};

public method .parse_restrict_entry() {
    arg value;
    
    if (!value)
        throw(~invalid, "Restrict with 'by-entrances', 'none' or a lock frob");
    if (value == "by-entrances")
        value = "no";
    else if (value == "none")
        value = "yes";
    return (> $lock_frob.parse(value, user() || this()) <);
};

protected method .set_restrict_entry() {
    arg name, definer, value;
    
    if (class(value) == $true_lock_frob)
        (| clear_var('restrict_entry) |);
    else
        restrict_entry = value;
};

root method .format_restrict_entry() {
    arg value;
    var unparse;
    
    unparse = value.unparse();
    if (unparse == "yes")
        return "none";
    else if (unparse == "no")
        return "by-entrances";
    return unparse;
};

public method .get_restrict_entry() {
    arg name, definer;
    
    return restrict_entry || (<$true_lock_frob, []>);
};

public method .will_arrive() {
    arg mover, old_place;
    
    (> pass(mover, old_place) <);
    if (restrict_entry && ((!(mover.is($path))) && ((mover != $housekeeper) && ((!(.trusts(mover))) && ((| (mover.location()) != this() |) && (!(restrict_entry.try(mover))))))))
        throw(~restricted_entry, ((("Entry to " + (.name())) + " is restricted to ") + (restrict_entry.lock_name('place))) + ".");
};


new object $nowhere: $place;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $location contents = [$on_location, $in_location, $located, $robot, $character];
var $described prose = [];
var $has_name name = ['prop, "Nowhere", "Nowhere"];
var $place exits = [];
var $place realm = $realm_of_creation;
var $command_cache shortcuts = 0;
var $root manager = $nowhere;
var $root managed = [$nowhere];
var $place entrances = [];
var $event_handler hooks = #[];
var $command_cache modules = [];
var $root settings = #[["propagate", 0], ["public-home", 0], ["map-position", 0]];
var $command_cache commands = 0;
var $event_handler hooked = #[];

public method .description() {
    arg flags;
    
    return [];
};

public method .announce() {
    arg @args;
    
};


new object $body_cave: $place;

var $root manager = $body_cave;
var $root created_on = 808865147;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $has_name name = ['uniq, "Body Cave", "the Body Cave"];
var $described prose = [];
var $location contents = [$reaper, $builder, $guest, $no_one, $programmer, $admin, $player, $storyteller, $user];
var $place exits = [];
var $place realm = $realm_of_creation;
var $physical visibility = -100;
var $root managed = [$body_cave];
var $place entrances = [];
var $event_handler hooks = #[];
var $root settings = #[["public-home", 1], ["propagate", 0], ["map-position", 0]];
var $event_handler hooked = #[];
var $command_cache commands = 0;
var $place darkness = 10;

public method .announce() {
    arg @who_cares;
    
};

public method .will_attach() {
    arg type, @by_whom;
    
    throw(~perm, "Place is not publicly extendable.");
};


new object $void: $place;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $location contents = [$thing, $lost_and_found, $thing_frob, $trash, $located_location, $note, $slate, $generic_map, $plain_page, $nothing, $body, $wearable];
var $described prose = ["A place existing for the soul purpose of doing so, when it wishes be."];
var $has_name name = ['uniq, "Void", "the Void"];
var $place exits = [];
var $place realm = $realm_of_creation;
var $command_cache shortcuts = 0;
var $command_cache modules = [];
var $root manager = $void;
var $root managed = [$void];
var $place entrances = [];
var $root settings = #[["propagate", 0], ["map-position", 0]];
var $event_handler hooks = #[];
var $command_cache commands = 0;


new object $the_pit: $place;

var $root inited = 1;
var $root manager = $the_pit;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $location contents = [];
var $described prose = <$ctext_frob, [["A cozy atmosphere pervades this room, a small hideaway where people can come to relax and socialize. The cement walls are covered with various scribbles burn marks, and stains of unrecognizable origin."], #[]]>;
var $has_name name = ['prop, "The Pit", "The Pit"];
var $place exits = [];
var $place realm = $realm_of_creation;
var $command_cache commands = 0;
var $place entrances = [];
var $event_handler hooks = #[];
var $root settings = #[["public-home", 0], ["map-position", 0], ["propagate", 0]];
var $has_commands local = #[];
var $command_cache modules = [];
var $foundation msgs = #[["housekeeper", #[["general", <$ctext_frob, [["Dust bunnies rise from under the furniture to envelop ", <$generator, ["actor", [], [], 'gen_actor]>, "'s comatose form, leaving behind a small pile of musty lint."], #[]]>]]]];
var $event_handler hooked = #[];
var $command_cache shortcuts = 0;
var $place darkness = 0;
var $root managed = [$the_pit];

root method .core_the_pit() {
    .set_prose("A cozy atmosphere pervades this room, a small hideaway where people can come to relax and socialize. The cement walls are covered with various scribbles burn marks, and stains of unrecognizable origin.");
};


new object $tutorial: $place;

var $root manager = $tutorial;
var $root quota_exempt = 1;
var $root flags = ['variables, 'methods, 'code, 'core, 'general_cache];
var $root created_on = 874177642;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[["exit", [["exit", "", "exit", 'exit_cmd, #[]]]], ["n?ext|p?revious|m?ore|b?ack", [["n?ext|p?revious|m?ore|b?ack", "", "n?ext|p?revious|m?ore|b?ack", 'next_cmd, #[]]]]];
var $has_name name = ['prop, "Tutorial Room", "Tutorial Room"];
var $described prose = <$ctext_frob, [["This is the tutorial room. It's not part of any tutorial, and you probably shouldn't be here. Type", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["exit"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "now to get back to ", <$generator, ["servname", [], [], 'gen_servname]>, "."], #[]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $command_cache modules = [];
var $root defined_settings = #[["next-topic", #[['parse, ['parse_topic_object]]]], ["prev-topic", #[['parse, ['parse_topic_object]]]], ["class", #[['parse, ['parse_tutorial_class]]]], ["start-topic", #[['parse, ['parse_topic_object, 'start_topic]]]], ["back-topic", #[['parse, ['parse_topic_object]]]], ["more-topic", #[['parse, ['parse_topic_object]]]]];
var $event_handler hooks = #[];
var $root settings = #[["next-topic", ""], ["prev-topic", ""], ["class", ""], ["start-topic", ""], ["back-topic", ""], ["more-topic", ""], ["map-position", 0], ["propagate", 0]];
var $tutorial tracking = 0;
var $root managed = [$tutorial];

public method .announce() {
    arg str, @whonot;
    var p, msg;
    
    if ((!sender()) in (.contents()))
        return;
    if ((type(str) == 'frob) && ((class(str) == $message_frob) && (this() in (str.parts())))) {
        p = str.get_part(this());
        str = str.change_entry(this(), "general");
    }
    if ((!(sender() in whonot)) && (sender() in (.contents())))
        (| sender().tell(str, sender()) |);
    switch (type(str)) {
        case 'string:
            (| sender().tell(("[ Everyone else would see: " + str) + " ]") |);
        case 'frob:
            msg = ($parse_lib.filter_ctext(str, #[['formatter, $plain_format]])).to_strings();
            if (((msg.length()) == 2) && ((msg[2]) == `[])) {
                (| sender().tell(("[ Everyone else would see: " + (msg[1])) + " ]") |);
            } else {
                (| sender().tell("[-- Everyone else would see the following: --]") |);
                (| sender().tell(p) |);
                (| sender().tell("[-- End --]") |);
            }
    }
};

public method .parse_topic_object() {
    arg value, @args;
    var obj, class;
    
    if (args) {
        // for $tutorial:start-topic
        class = this();
    } else {
        // for $tutorial:(next|prev)-topic
        class = $tutorial;
    }
    if (!value)
        return "";
    obj = $object_lib.to_dbref(value);
    if (!(obj.is(class)))
        throw(~parse, "The topic must be a child of " + class);
    return obj;
};

public method .exit_cmd() {
    arg cmdstr, cmd, @who;
    var source, n;
    
    source = (| ((parents()[1]).tracking(sender()))[1] |) || ($world.starting_place());
    n = (((parents()[1]).name()).capitalize()) + " Tutorial.";
    sender().tell("You leave the " + n);
    (> sender().move_to(source) <);
    source.announce(((sender().name()) + " returns from the ") + n, sender());
};

public method .format_contents() {
    arg flags;
    var users, br, exclude, actor, objects, output, obj, line, item, formatteduser, formattedobj;
    
    // called by .description
    users = [];
    objects = [];
    actor = flags['actor];
    exclude = (| flags['exclude] |) || [];
    for obj in (.contents()) {
        if ((!(obj in exclude)) && ((obj != actor) && (| obj.is_obvious_to(actor) |))) {
            if (obj.has_ancestor($body))
                users += [obj];
            else
                objects += [obj];
        }
    }
    output = $ctext_frob.new_with([]);
    br = $cml_lib.format_br_tag();
    if (objects) {
        formattedobj = map item in (objects) to ($cml_lib.format_obj_tag('look, item, item.name()));
        formattedobj = ["You see ", $cml_lib.generate_english_tag(formattedobj), " here.", br];
        line = $ctext_frob.new_with(formattedobj);
    
        //output += [br, line];
        output = output.append(line);
    }
    return output;
};

public method .description() {
    arg @ignored;
    var exit, out, lines, more, back;
    
    out = (> pass(@ignored) <);
    lines = [];
    
    // back/more
    if ((exit = .get_setting("back-topic", $tutorial)))
        lines += [$cml_lib.format_obj_tag('look, exit, "Back: " + (exit.name()))];
    if ((exit = .get_setting("more-topic", $tutorial))) {
        if (lines)
            lines += [" || "];
        lines += [$cml_lib.format_obj_tag('look, exit, "More: " + (exit.name()))];
    }
    
    // reset
    if (lines) {
        out += [$ctext_frob.new_with(["<< ", @lines, " >>"])];
        lines = [];
    }
    
    // prev/next
    if ((exit = .get_setting("prev-topic", $tutorial)))
        lines += [$cml_lib.format_obj_tag('look, exit, "Previous: " + (exit.name()))];
    if ((exit = .get_setting("next-topic", $tutorial))) {
        if (lines)
            lines += [" || "];
        lines += [$cml_lib.format_obj_tag('look, exit, "Next: " + (exit.name()))];
    }
    if (lines)
        return out + [$ctext_frob.new_with(["<< ", @lines, " >>"])];
    else
        return out;
};

public method .next_cmd() {
    arg cmd, cmdstr, @args;
    var node, what;
    
    switch (cmd[1]) {
        case "n":
            what = "next";
        case "p":
            what = "prev";
        case "m":
            what = "more";
        case "b":
            what = "back";
        default:
            return "It seems this command is a little mis-configured.";
    }
    if (!(node = .get_setting(what + "-topic", $tutorial)))
        return ((("There is no \"" + what) + "\" topic.  Type \"exit\" to leave the ") + (((parents()[1]).name()).capitalize())) + " Tutorial.";
    sender().move_to(node);
};

public method .parse_tutorial_class() {
    arg value, @args;
    var obj;
    
    if (!value)
        return "";
    obj = $object_lib.to_dbref(value);
    if (!(obj.is($user)))
        throw(~perm, "the class must be a user class");
    return obj;
};

public method .minclass() {
    return (.get_setting("class", $tutorial)) || 0;
};

public method .will_arrive() {
    arg mover, old_place;
    
    pass(mover, old_place);
    if ((!((parents()[1]).is($tutorial))) || ((parents()[1]) == $tutorial))
        throw(~perm, "Something is wrong with that tutorial topic, you cannot go there.");
};

public method .did_arrive() {
    arg mover, old_place;
    
    pass(mover, old_place);
    (parents()[1]).track_user(sender(), old_place);
};

public method .track_user() {
    arg user, prev;
    var current;
    
    if (!tracking)
        tracking = #[];
    if (dict_contains(tracking, user))
        current = tracking[user];
    else
        current = [prev, 0];
    tracking = dict_add(tracking, user, replace(current, 2, sender()));
};

public method .did_leave() {
    arg mover, new_place;
    
    pass(mover, new_place);
    if (!(new_place.is(parents()[1])))
        (parents()[1]).user_left(sender());
};

public method .tracking() {
    arg user;
    
    return tracking[user];
};

public method .user_left() {
    arg user;
    
    if (dict_contains(tracking || #[], user))
        tracking = dict_del(tracking, user);
};

root method .core_tutorial() {
    if (tracking)
        tracking = 0;
};


new object $introductory_tutorial: $tutorial;

var $root manager = $introductory_tutorial;
var $root settings = #[["class", $user], ["start-topic", $introtut_start], ["map-position", 0], ["propagate", 0]];
var $root flags = ['variables, 'methods, 'code, 'core, 'general_cache];
var $root created_on = 874248718;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "introductory", "introductory"];
var $described prose = [];
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $command_cache modules = [];
var $tutorial tracking = 0;
var $root managed = [$introductory_tutorial];
var $command_cache commands = 0;
var $command_cache shortcuts = 0;


new object $introtut_speaking: $introductory_tutorial;

var $root manager = $introtut_speaking;
var $command_cache modules = [];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874177642;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Speaking", "Speaking"];
var $described prose = <$ctext_frob, [["One of the most used features of a Virtual Environment Server is communicating with other users online. There are several ways you can communicate with others, starting with the 'say' command. To experiment with speaking, enter the following:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["say Hello, I am new here."], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Not only will you (virtually) vocalize, but since you are currently in the tutorial you will also see what others will see. It should look like:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$generator, ["name", [], [<$generator, ["viewer", [], [], 'gen_viewer]>], 'gen_name]>, " says, \"Hello, I am new here.\"", <$format, ["br", [], [], 'do_br]>, "[ Everyone else would see: ", <$generator, ["name", [], [<$generator, ["viewer", [], [], 'gen_viewer]>], 'gen_name]>, " says, \"Hello, I am new here.\" ]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "For convenience, you can also abbreviate the say command to a single double-quote character (\"). This will provide the exact same result as the slightly longer command did before. You do not need to append another double-quote to your command since it is automatically provided. Try both forms, to see how they work."], #[]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root managed = [$introtut_speaking];
var $root settings = #[["prev-topic", $introtut_gender], ["next-topic", $introtut_nonverbal], ["map-position", 0], ["propagate", 0]];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_nonverbal: $introductory_tutorial;

var $root manager = $introtut_nonverbal;
var $command_cache modules = [];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874177643;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Non-verbal Communication", "Non-verbal Communication"];
var $described prose = <$ctext_frob, [["Another common form of communication is the \"emote\" command, or emotion command. It is used for situations where you would not normally vocalize. For instance, if you are feeling happy, it would seem unusual to say, \"I am happy\", when there are many ways you would normally express this in real life, such as smiling or laughing. This is what the emote command is used for. ", <$format, ["np", [], [], 'do_np]>, "The emote command simply displays your name followed by whatever you typed, to everybody in the room. The command to use is either 'emote', or like say, it can also be abbreviated for convenience--this time to a colon (:). To try emote enter the following:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["emote smiles happily."], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Keep in mind, an emote has no actual effect on your environment, so if you typed:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [":throws Neale out of the house."], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "People would see:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$generator, ["name", [], [<$generator, ["viewer", [], [], 'gen_viewer]>], 'gen_name]>, " throws Neale out of the house."], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "But Neale ", <$format, ["i", [], ["wouldn't"], 'do_i]>, " actually go anywhere. Nothing has happened in the Virtual Environment, except you might have made somebody angry. Emoting can be used to represent events that have not occurred, but this is generally not encouraged. A simple way of looking at it is you can emote anything about yourself, but if you intrusively involve others they may get annoyed."], #[]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root settings = #[["prev-topic", $introtut_speaking], ["next-topic", $introtut_remote], ["more-topic", $introtut_communication], ["map-position", 0], ["propagate", 0]];
var $root managed = [$introtut_nonverbal];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_remote: $introductory_tutorial;

var $root manager = $introtut_remote;
var $command_cache modules = [];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874177643;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Remote Communication", "Remote Communication"];
var $described prose = <$ctext_frob, [["When you would like to talk with someone who is logged into ", <$generator, ["servname", [], [], 'gen_servname]>, ", but isn't in your location, you can page them. The '@page' command will send your message only to the person (or people) you specify. You use this command by paging one or more people, with a message, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@page me ", <$format, ["i", [], ["with"], 'do_i]>, " This is my first page."], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["with"], 'do_i]>, " preposition is important, and is not a part of the message you are actually paging. This exists to help the server distinguish where the list of recipients ends, and your message begins. Since this page was directed only at you, it should have looked something like:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["[from Remote Communication] ", <$generator, ["name", [], [<$generator, ["viewer", [], [], 'gen_viewer]>], 'gen_name]>, " says, \"This is my first page.\"", <$format, ["br", [], [], 'do_br]>, "[to ", <$generator, ["name", [], [<$generator, ["viewer", [], [], 'gen_viewer]>], 'gen_name]>, "] ", <$generator, ["name", [], [<$generator, ["viewer", [], [], 'gen_viewer]>], 'gen_name]>, " says, \"This is my first page.\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "As you see, a page announces to its recipient who sent the message and where the sender is, and you also see a line showing what you sent. ", <$format, ["np", [], [], 'do_np]>, "For more information on the various features and shortcuts of paging, See ", <$format, ["link", [["node", "$help_cmd_page"]], ["@page"], 'do_link]>, "."], #[['links, #[["@page", "$help_cmd_page"]]]]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root settings = #[["next-topic", $introtut_who], ["prev-topic", $introtut_nonverbal], ["map-position", 0], ["propagate", 0]];
var $root managed = [$introtut_remote];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_who: $introductory_tutorial;

var $root manager = $introtut_who;
var $command_cache modules = [];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874177643;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Who's on-line?", "Who's on-line?"];
var $described prose = <$ctext_frob, [["It is possible to get a list of everybody who is using ", <$generator, ["servname", [], [], 'gen_servname]>, " at the same time you are. This information is useful for many things, from finding if friends are currently connected to finding somebody's location. ", <$format, ["np", [], [], 'do_np]>, "The command to list everybody connected is ", <$format, ["help", [["node", "$help_cmd_who"]], ["@who"], 'do_help]>, ". Type ", <$format, ["help", [["node", "$help_cmd_who"]], ["@who"], 'do_help]>, " now, to see who is online, how long they have been online, how long it has been since they have typed anything, and where they currently are located. Go ahead and try it now, see who is online. ", <$format, ["np", [], [], 'do_np]>, "You can also specify a specific person with @who. Doing this will only show you information on that specific person. Try this by using yourself as the person, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@who ", <$generator, ["name", [], [<$generator, ["viewer", [], [], 'gen_viewer]>], 'gen_name]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If you want to learn more information about a person, you may want to use the ", <$format, ["link", [["node", "$help_cmd_finger"]], ["@finger"], 'do_link]>, " command. For more information on either of these commands, read the help documents for them."], #[['links, #[["@finger", "$help_cmd_finger"]]]]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root settings = #[["prev-topic", $introtut_remote], ["next-topic", $introtut_end], ["map-position", 0], ["propagate", 0]];
var $root managed = [$introtut_who];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_look: $introductory_tutorial;

var $root manager = $introtut_look;
var $command_cache shortcuts = 0;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874177644;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Looking Around", "Looking Around"];
var $described prose = <$ctext_frob, [["All objects in ", <$generator, ["servname", [], [], 'gen_servname]>, " have a name and a description. Names are automatically displayed, but descriptions often are not. To see an object's description, you need to look at it with the 'look' command. ", <$format, ["np", [], [], 'do_np]>, "The look command can be used in two ways. If you specify something or somebody to look at, you will see that person or object's description. If you do not specify anything, you will see your current location's description (typing 'look here' is the same as simply typing 'look'). ", <$format, ["np", [], [], 'do_np]>, "If you type 'look' right now, you will see these instructions again, because they are the description of this room. The last line you see should be, \"You see a small mailbox here.\", because there is a mailbox in this room. Type 'look mailbox' now, and follow the instructions in its description."], #[]]>;
var $location contents = [$introtut_mailbox];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $root settings = #[["prev-topic", $introtut_names], ["next-topic", $introtut_moving], ["map-position", 0], ["propagate", 0]];
var $event_handler hooks = #[];
var $root managed = [$introtut_look];
var $command_cache modules = [];
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_desc: $introductory_tutorial;

var $root manager = $introtut_desc;
var $command_cache shortcuts = 0;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874177645;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Describing Yourself", "Describing Yourself"];
var $described prose = <$ctext_frob, [["As was just explained, all objects in your virtual environment have descriptions, including you. Most likely, you have the default description, which is 'You see nothing special'. It would be a good idea to change that description now, even if you're not sure what you want it to be. You can always change it again later. ", <$format, ["np", [], [], 'do_np]>, "Since you may not have looked at many other players, there are a few examples of users' descriptions here. Look at the graffiti to see them. ", <$format, ["np", [], [], 'do_np]>, "When you have decided on a description for yourself, you can set it with", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@describe me as \"Your Description Here\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>], #[]]>;
var $location contents = [$introtut_user_graffiti];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $root settings = #[["prev-topic", $introtut_moving], ["next-topic", $introtut_gender], ["map-position", 0], ["propagate", 0]];
var $event_handler hooks = #[];
var $root managed = [$introtut_desc];
var $command_cache modules = [];
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_gender: $introductory_tutorial;

var $root manager = $introtut_gender;
var $command_cache modules = [];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874177645;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Gender", "Gender"];
var $described prose = <$ctext_frob, [["You, as well as every other person in ", <$generator, ["servname", [], [], 'gen_servname]>, ", has a gender. If you look at yourself, you will see a phrase about being awake; the pronouns used are determined by your gender, which is most likely the default gender of 'neuter' (no gender). ", <$format, ["np", [], [], 'do_np]>, "To see a list of possible genders, type:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set gender"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "To set a gender from the list type:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set gender=GENDER"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "And then look at yourself (type 'look me'). ", <$format, ["np", [], [], 'do_np]>, "You can change your gender whenever you like; right now you should use @set gender to set yourself to the gender of your choice."], #[]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $root settings = #[["prev-topic", $introtut_desc], ["next-topic", $introtut_speaking], ["map-position", 0], ["propagate", 0]];
var $event_handler hooks = #[];
var $root managed = [$introtut_gender];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_start: $introductory_tutorial;

var $root manager = $introtut_start;
var $root managed = [$introtut_start];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874181387;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Welcome!", "Welcome!"];
var $described prose = <$ctext_frob, [["This is the beginner tutorial to ColdCore and ", <$generator, ["servname", [], [], 'gen_servname]>, ".", <$format, ["br", [], [], 'do_br]>, " It is designed to help introduce you to some of the common commands", <$format, ["br", [], [], 'do_br]>, " you will be using most often. Throughout this tutorial you may be asked", <$format, ["br", [], [], 'do_br]>, " to try a command. We encourage you to do so, and to experiment as much", <$format, ["br", [], [], 'do_br]>, " as you desire. If the command causes the topic's instructions to scroll", <$format, ["br", [], [], 'do_br]>, " off the screen, simply type '", <$format, ["tt", [], ["look"], 'do_tt]>, "' to see them again. ", <$format, ["np", [], [], 'do_np]>, "Each topic in the tutorial is given in a seperate step. You can move", <$format, ["br", [], [], 'do_br]>, " back and forth between steps with the commands '", <$format, ["tt", [], ["next"], 'do_tt]>, "' and '", <$format, ["tt", [], ["prev"], 'do_tt]>, "'.", <$format, ["br", [], [], 'do_br]>, " You can exit the tutorial at any time by typing the command '", <$format, ["tt", [], ["exit"], 'do_tt]>, "'."], #[]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root settings = #[["next-topic", $introtut_lines], ["map-position", 0], ["propagate", 0]];
var $command_cache commands = 0;
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $event_handler hooked = #[];


new object $introtut_help: $introductory_tutorial;

var $root manager = $introtut_help;
var $root managed = [$introtut_help];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874182968;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Using the Help System", "Using the Help System"];
var $described prose = <$ctext_frob, [["One of the most important things to learn is how to use the help system. If you are familiar with the World Wide Web, you may recognize a hyperlink. Within a topic, references to help documents will be highlighted in some manner--these are known as links, or hyperlinks. How the link is highlighted will vary depending upon how you are browsing this tutorial. If you are connected through a terminal the link may be surrounded by square brackets ([]). If you are using html, it should be highlighted just like any other link. The following is a link to the main help page:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["link", [["node", "$help_coldcore"]], ["@help"], 'do_link]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Remember how it looks. When you see something which looks like it, you can type: '", <$format, ["tt", [], ["@help WORD"], 'do_tt]>, "' where WORD is the text. ", <$format, ["np", [], [], 'do_np]>, "If you want to explore how to use the help system further, type 'more'. Or, for later reference, you can get more information on all of the features of the help system, as well as a list of the abbreviations useful for easy navigation by typing:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@help help"], 'do_dfn]>], #[['links, #[["@help", "$help_coldcore"]]]]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root settings = #[["prev-topic", $introtut_lines], ["next-topic", $introtut_objs], ["more-topic", $introtut_help_short], ["map-position", 0], ["propagate", 0]];
var $command_cache shortcuts = 0;
var $command_cache modules = [];
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_lines: $introductory_tutorial;

var $root manager = $introtut_lines;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874185080;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Line Wrapping", "Line Wrapping"];
var $described prose = <$ctext_frob, [["If text on your display is scrolling off the edge of the screen,", <$format, ["br", [], [], 'do_br]>, " you will need to find a means to wrap it. The preferred method is", <$format, ["br", [], [], 'do_br]>, " to use a special client designed for connecting to Virtual Community", <$format, ["br", [], [], 'do_br]>, " Servers. We suggest using Tinyfugue, or another similar client. More", <$format, ["br", [], [], 'do_br]>, " information on available clients can be found by typing:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@help clients"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Up to now in the tutorial, all lines have been pre-wrapped by the server.", <$format, ["br", [], [], 'do_br]>, " To determine if your text is wrapping or not, look at the following", <$format, ["br", [], [], 'do_br]>, " line which counts from one to fifty. ", <$format, ["np", [], [], 'do_np]>, "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 ", <$format, ["np", [], [], 'do_np]>, "If line wrapping is working for you, you should be able to see all", <$format, ["br", [], [], 'do_br]>, " numbers (although they will take two or more lines). If you only", <$format, ["br", [], [], 'do_br]>, " see one line, and it ends before 50, line wrapping is not working", <$format, ["br", [], [], 'do_br]>, " for you. If you cannot get a client to do line wrapping for you,", <$format, ["br", [], [], 'do_br]>, " you can set your content type as text/wrapped. This method is not", <$format, ["br", [], [], 'do_br]>, " suggested, as it is slower and you may have problems with some", <$format, ["br", [], [], 'do_br]>, " formatting. You can set your content type with the following command:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set content-type=text/wrapped"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "All further topics will assume your client can word-wrap properly,", <$format, ["br", [], [], 'do_br]>, " or that you are using text/wrapped."], #[]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root managed = [$introtut_lines];
var $root settings = #[["prev-topic", $introtut_start], ["next-topic", $introtut_help], ["map-position", 0], ["propagate", 0]];
var $command_cache commands = 0;
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $event_handler hooked = #[];


new object $introtut_end: $introductory_tutorial;

var $root manager = $introtut_end;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874251255;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Other Tutorials", "Other Tutorials"];
var $described prose = <$ctext_frob, [["This is the end of the Introductory Tutorial. More tutorials exist, which you may want to browse. To get a full list of tutorials type:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@tutorial ?"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "To enter another tutorial specify it after the ", <$format, ["tt", [], ["@tutorial"], 'do_tt]>, " command. You must exit this tutorial first, by typing 'exit'. ", <$format, ["np", [], [], 'do_np]>, "This tutorial and the core tutorial code were written by Brandon Gillespie and Neale Pickett. The tutorial was based on a concept in Jay's House MOO (JHM), as was some of the original tutorial text."], #[]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root managed = [$introtut_end];
var $root settings = #[["prev-topic", $introtut_who], ["next-topic", ""], ["map-position", 0], ["propagate", 0]];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_objs: $introductory_tutorial;

var $root manager = $introtut_objs;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874259889;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Objects", "Objects"];
var $described prose = <$ctext_frob, [["Everything in your Virtual Environment on ", <$generator, ["servname", [], [], 'gen_servname]>, " is an object. This includes people, items and locations. Every object has a unique name, which is used to refer to it. This name is often called a database reference (dbref for short) or object name. An object name begins with a dollar-sign (", <$format, ["tt", [], ["$"], 'do_tt]>, ") and is followed by one or more alphabetic or numeric characters, or the undescore. All of the following are object names:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["$root", <$format, ["br", [], [], 'do_br]>, "$thing_35", <$format, ["br", [], [], 'do_br]>, <$generator, ["viewer", [], [], 'gen_viewer]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Objects also have another type of dbref called an object number. You will not likely see too many object numbers, as all valid objects should have a name--which is easier to remember. An object number begins with a pound sign (", <$format, ["tt", [], ["#"], 'do_tt]>, ") followed by a number (positive or negative). If it is a negative number, it is referring to an object which either no longer exists, or has never existed."], #[]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root settings = #[["prev-topic", $introtut_help], ["next-topic", $introtut_names], ["map-position", 0], ["propagate", 0]];
var $root managed = [$introtut_objs];
var $command_cache shortcuts = 0;
var $command_cache modules = [];
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_env: $introductory_tutorial;

var $root manager = $introtut_env;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874260896;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Your Environment", "Your Environment"];
var $described prose = <$ctext_frob, [["Up to now you may have seen a few references to the Virtual Environment. This is a generic term applied to everything which exists in the same virtual location as you, including the location itself. When you want to look at something, it has to exist in your environment first (i.e. it has to be in the same place you are). ", <$format, ["np", [], [], 'do_np]>, "For instance, if you were in a place named The Courtyard, and in The Courtyard was a friend, a box and a bench--your environment would consist of The Courtyard, your friend, a box, a bench and yourself. ", <$format, ["np", [], [], 'do_np]>, "To learn more about your environment, type 'more'. Or, for later reference, you can get more information on your environment in the ", <$format, ["link", [["node", "$help_environment"]], ["Environment"], 'do_link]>, " help document."], #[['links, #[["Environment", "$help_environment"]]]]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root settings = #[["prev-topic", $introtut_names], ["next-topic", $introtut_look], ["more-topic", $introtut_objs_env], ["map-position", 0], ["propagate", 0]];
var $root managed = [$introtut_env];
var $command_cache shortcuts = 0;
var $command_cache modules = [];
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_moving: $introductory_tutorial;

var $root manager = $introtut_moving;
var $command_cache shortcuts = 0;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874264042;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Moving Around", "Moving Around"];
var $described prose = <$ctext_frob, [["Central to the concept of the Virtual Environment is your location. Generally, when you are in one place, you can only see and interact with things in that same location. Just like in real life, you cannot interact with people who are not nearby. ", <$format, ["np", [], [], 'do_np]>, "Exits are used to link locations together. You can move from place to place using exits. Most places on ", <$generator, ["servname", [], [], 'gen_servname]>, " will be connected in a consistent way, and the exits will usually be compass directions, as well as up and down. You can set how exits are listed in a room with:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set exit-style"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Even if you choose your exit-style to be 'none', you can always type '@ways' to see a list of visible exits. ", <$format, ["np", [], [], 'do_np]>, "Try going east now, by typing 'east' or just 'e'. ", <$format, ["!--", [["This", 1], [" ", 1], ["is", 1], ["a", 1], ["small,", 1], ["poshly-decorated", 1], ["room.", 1], ["The", 1], ["walls", 1], ["are", 1], ["decorated", 1], ["with", 1], ["lavish", 1], ["tapestries,", 1], ["and", 1], ["all", 1], ["around", 1], ["you", 1], ["expensive-looking", 1], ["furniture.", 1], ["So", 1], ["expensive,", 1], ["in", 1], ["fact,", 1], ["that", 1], ["afraid", 1], ["to", 1], ["sit", 1], ["down", 1], ["on", 1], ["it,", 1], ["indeed", 1], ["owner", 1], ["seems", 1], ["have", 1], ["exact", 1], ["same", 1], ["opinion,", 1], ["for", 1], ["cushions", 1], ["covered", 1], ["plastic.", 1], ["Perhaps", 1], ["had", 1], ["better", 1], ["just", 1], ["leave", 1], ["room,", 1], ["lest", 1], ["breathe", 1], ["something.", 1], ["--", 1]], [], 'do_]>], #[]]>;
var $location contents = [];
var $place entrances = [$introtut_path1];
var $place exits = [$introtut_path1];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $root managed = [$introtut_moving];
var $event_handler hooks = #[];
var $root settings = #[["prev-topic", $introtut_look], ["next-topic", $introtut_desc], ["map-position", 0], ["propagate", 0]];
var $command_cache modules = [];
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_help_short: $introductory_tutorial;

var $root manager = $introtut_help_short;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874289888;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Help Shortcut", "Help Shortcut"];
var $described prose = <$ctext_frob, [["For convenience, you can abbreviate the '@help' command to a single question mark, followed by the topic, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["?LINK"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Which would be equivalent to:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@help LINK"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "You can also use a single question mark (without any LINK name) to view the current help node again (incase it has scrolled off your terminal). ", <$format, ["np", [], [], 'do_np]>, "To learn about your help navigation history, and how to traverse it, type 'more', or type 'back' to go back."], #[]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root managed = [$introtut_help_short];
var $root settings = #[["next-topic", $introtut_objs], ["prev-topic", $introtut_lines], ["back-topic", $introtut_help], ["more-topic", $introtut_help_nav], ["map-position", 0], ["propagate", 0]];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_help_nav: $introductory_tutorial;

var $root manager = $introtut_help_nav;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874290428;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Help History", "Help History"];
var $described prose = <$ctext_frob, [["The server keeps track of what help nodes you have read, and you can go backwards and forwards in this history, using the less-than and greater-than signs in place of the link name, respectively. For instance, if you wanted to go back to the previous help node, you could simply type either of the following commands:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@help <", <$format, ["br", [], [], 'do_br]>, "?<"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "And to move forward again, you could type either of:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@help >", <$format, ["br", [], [], 'do_br]>, "?>"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "All of the other shortcuts and features are explained in detail, in the ", <$format, ["link", [["node", "$help_help"]], ["help options"], 'do_link]>, " documentation."], #[['links, #[["help options", "$help_help"]]]]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root managed = [$introtut_help_nav];
var $root settings = #[["next-topic", $introtut_objs], ["prev-topic", $introtut_lines], ["back-topic", $introtut_help_short], ["map-position", 0], ["propagate", 0]];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_objs_env: $introductory_tutorial;

var $root manager = $introtut_objs_env;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874293646;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Objects in your Environment", "Objects in your Environment"];
var $described prose = <$ctext_frob, [["When you use an object in your environment, either by picking it up, looking at it, talking to a friend or something similar (how to do each of these is explained later), ", <$generator, ["servname", [], [], 'gen_servname]>, " will remember the object in your Environment Context. This allows you to refer to previous things in a simple manner. For instance, if you were to use the command 'get' to pick up a bubbly bottle, you could drop the bubbly bottle by simply typing 'drop it', and the system would remember that 'it' refers to the 'bubbly bottle' because it was the last thing you were using. ", <$format, ["np", [], [], 'do_np]>, "In the case where multiple objects may match one name, you can use ordinal references. For instance, if there were five boxes in the same location as you, and each was named 'box', you could not simply pickup 'the box' because the server would not know which one you wanted. However, you could use an ordinal reference, such as 'the 3rd box'. ", <$format, ["np", [], [], 'do_np]>, "The server also has two known keywords which always act the same way. These are '", <$format, ["tt", [], ["me"], 'do_tt]>, "', which will always refer to you, and '", <$format, ["tt", [], ["here"], 'do_tt]>, "', which will always refer to your location. ", <$format, ["np", [], [], 'do_np]>, "More information on Objects in your Environment can be found in the help section ", <$format, ["link", [["node", "$help_environment"]], ["Environment"], 'do_link]>, "."], #[['links, #[["Environment", "$help_environment"]]]]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root managed = [$introtut_objs_env];
var $root settings = #[["next-topic", $introtut_look], ["prev-topic", $introtut_names], ["back-topic", $introtut_env], ["map-position", 0], ["propagate", 0]];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_names: $introductory_tutorial;

var $root manager = $introtut_names;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874465166;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Object Names", "Object Names"];
var $described prose = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Every object in your Virtual Environment has a name. When you see an object listed as the contents of a location, you are seeing its name. You can change the name of any object you manage with the command '", <$format, ["link", [["node", "$help_cmd_rename"]], ["@rename"], 'do_link]>, "'. ", <$format, ["np", [], [], 'do_np]>, "Names can include any number of words, such as 'a blue sock'. When you refer to an object with its name, you can use any or all of the words in the name to refer to the object. You should use as much of the name as you can, to make a correct match. You can always leave off the article--or use it, if it makes it easier. For instance, to look at the blue sock, you could type any of the following:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> look at sock", <$format, ["br", [], [], 'do_br]>, "> look at soc", <$format, ["br", [], [], 'do_br]>, "> look at blue sock", <$format, ["br", [], [], 'do_br]>, "> look at bl", <$format, ["br", [], [], 'do_br]>, "> look at the blue sock"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "More information is available on Names and Name Templates (aliases)."], #[['links, #[["@rename", "$help_cmd_rename"]]]]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root settings = #[["prev-topic", $introtut_objs], ["next-topic", $introtut_env], ["more-topic", $introtut_names_tmpl], ["map-position", 0], ["propagate", 0]];
var $root managed = [$introtut_names];
var $command_cache shortcuts = 0;
var $command_cache modules = [];
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_names_tmpl: $introductory_tutorial;

var $root manager = $introtut_names_tmpl;
var $root managed = [$introtut_names_tmpl];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874470121;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Name Templates", "Name Templates"];
var $described prose = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Sometimes, a few hints may be added to an object's name, in order to make it easier to refer to. These hints are called Name Templates, because they use a different sort of matching than Names. ", <$format, ["np", [], [], 'do_np]>, "When you see a name template, it may have a question mark in the word ('", <$format, ["tt", [], ["?"], 'do_tt]>, "'), and multiple words may be joined together with the pipe character ('", <$format, ["tt", [], ["|"], 'do_tt]>, "'). The question mark signifies that anything beyond that point in the word is optional. For instance, if the name template 'e?ast' were given, you could type 'e', 'ea', 'eas', and 'east'. ", <$format, ["np", [], [], 'do_np]>, "The pipe character is used to specify possible alternatives, and is equivalent to saying the template can match the first word, or the second word, or the third, and so on. For instance, the template 'east|out' would match both 'east' or 'out'. ", <$format, ["np", [], [], 'do_np]>, "More information is available on how User Names work."], #[]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root settings = #[["back-topic", $introtut_names], ["more-topic", $introtut_names_user], ["next-topic", $introtut_env], ["prev-topic", $introtut_objs], ["map-position", 0], ["propagate", 0]];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_names_user: $introductory_tutorial;

var $root manager = $introtut_names_user;
var $root managed = [$introtut_names_user];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874470130;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "User Names", "User Names"];
var $described prose = <$ctext_frob, [["In general, object names do not have to be unique. That is, multiple objects can have the exact same name. However, users must have unique names in respect to other users. To determine the unique aspect of a name, all characters which are not alphabetic or numeric are removed from the name, and then it is compared to other names which have been stripped in the same manner. Thus, if somebody were to have the name \"Joe\", somebody else could not have the name \"Joe!\", because after it is stripped it is equivalent. ", <$format, ["np", [], [], 'do_np]>, "If you want to have more than one name refer to yourself, you can register them, using the command '", <$format, ["tt", [], ["@register"], 'do_tt]>, "'."], #[]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root settings = #[["back-topic", $introtut_names_tmpl], ["next-topic", $introtut_env], ["prev-topic", $introtut_objs], ["map-position", 0], ["propagate", 0]];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;
var $event_handler hooked = #[];


new object $introtut_moving_1: $introductory_tutorial;

var $root manager = $introtut_moving_1;
var $command_cache shortcuts = 0;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874376521;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['uniq, "Top of the Stairs", "the Top of the Stairs"];
var $described prose = <$ctext_frob, [["Exits can have name templates, too. This place has an exit named 'stairs', with the name template 'd?own'. You can go down the stairs by typing 'stairs', 'sta', 'down', 'd', 'dow', or anything else that would match the object name or name template (see earlier in the tutorial for more information about these concepts). ", <$format, ["np", [], [], 'do_np]>, "You can get back to the tutorial by typing 'west', but try typing 'down' now."], #[]]>;
var $location contents = [];
var $place entrances = [$introtut_path1, $introtut_path2];
var $place exits = [$introtut_path1, $introtut_path2];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $event_handler hooks = #[];
var $root managed = [$introtut_moving_1];
var $command_cache modules = [];
var $command_cache commands = 0;
var $root settings = #[["map-position", 0], ["propagate", 0]];


new object $introtut_moving_2: $introductory_tutorial;

var $root manager = $introtut_moving_2;
var $command_cache shortcuts = 0;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874473713;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['uniq, "Cellar", "the Cellar"];
var $described prose = <$ctext_frob, [["You can also chain movement commands together, if you already know where it is you want to go and how to get there. To do this, use the 'go' command, with the path you would walk. To get back to the tutorial, try typing", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["go up west"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "then type 'next' to move to the next tutorial topic."], #[]]>;
var $location contents = [];
var $place entrances = [$introtut_path2];
var $place exits = [$introtut_path2];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $root managed = [$introtut_moving_2];
var $event_handler hooks = #[];
var $command_cache modules = [];
var $command_cache commands = 0;
var $root settings = #[["map-position", 0], ["propagate", 0]];


new object $introtut_communication: $introductory_tutorial;

var $root manager = $introtut_communication;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874519394;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "More Ways to Communicate", "More Ways to Communicate"];
var $described prose = <$ctext_frob, [["There are several ways of getting your message out, other than saying and emoting. This includes direct speech, thinking, and quoting. ", <$format, ["np", [], [], 'do_np]>, "To direct speech to another user in the same room, use \"to USER say TEXT\", or \"'user TEXT\". Like @page, you can direct speech to the last person you directed to or paged with two apostrophes (''). Try talking to yourself with", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["'", <$generator, ["name", [], [<$generator, ["viewer", [], [], 'gen_viewer]>], 'gen_name]>, " hello there."], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "You can also use 'think' or '%' to put something in thought bubbles, just like old Spider-Man comics. Try this:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["%Don't worry, nobody can read your mind."], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Sometimes it is useful to be able to quote something someone else said, or even paste a line of code from a program, without ambiguity introduced by quotation marks or people thinking you are emoting. To do this, use 'quote' or '|'. Often this is used when trying to explain to new users how to do something on ", <$generator, ["servname", [], [], 'gen_servname]>, ". As an example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["|\"Hello world, I can say things now!"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "For further information on other communication commands (yes, there are more!), see the section ", <$format, ["link", [["node", "$help_interaction"]], ["Interaction"], 'do_link]>, " Commands."], #[['links, #[["Interaction", "$help_interaction"]]]]]>;
var $location contents = [];
var $place entrances = [];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root inited = 1;
var $root settings = #[["prev-topic", $introtut_speaking], ["back-topic", $introtut_nonverbal], ["next-topic", $introtut_remote], ["map-position", 0], ["propagate", 0]];
var $root managed = [$introtut_communication];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;


new object $realm: $realm_settings, $event_handler, $has_name;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core, 'fertile];
var $has_name name = ['uniq, "Realm", "the Realm"];
var $realm local = [];
var $root manager = $realm;
var $root managed = [$realm];
var $realm links = #[];
var $root trusted_by = [$world];
var $root defined_settings = #[["weather-time", #[['get, ['get_realm_setting]], ['parse, ['parse_weather_time]], ['format, ['format_weather_time]]]], ["housekeeper-delay", #[['parse, ['parse_setting_delay]], ['format, ['format_setting_delay]]]], ["housekeeper-notify", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $root settings = #[["weather-time", [$weather_nice, "spring", $climate_creation, 0, $world_time, 0]], ["propagate", 0], ["housekeeper-delay", 300], ["housekeeper-notify", 1], ["map-position", 0]];
var $realm last_daytime = 0;
var $foundation defined_msgs = #[["night", #[['branches, ["general"]]]], ["predawn", #[['branches, ["general"]]]], ["dawn", #[['branches, ["general"]]]], ["morning", #[['branches, ["general"]]]], ["noon", #[['branches, ["general"]]]], ["afternoon", #[['branches, ["general"]]]], ["sunset", #[['branches, ["general"]]]], ["evening", #[['branches, ["general"]]]]];
var $foundation msgs = #[["afternoon", #[["general", <$ctext_frob, [["The sun descends toward the horizon."], #[]]>]]], ["dawn", #[["general", <$ctext_frob, [["The first rays of sun announce the new day."], #[]]>]]], ["evening", #[["general", <$ctext_frob, [["The sky darkens as sunlight fades."], #[]]>]]], ["morning", #[["general", <$ctext_frob, [["The temperature begins to rise as the morning sun lifts above the horizon."], #[]]>]]], ["night", #[["general", <$ctext_frob, [["The sky darkens to night."], #[]]>]]], ["noon", #[["general", <$ctext_frob, [["The sun peaks in the sky."], #[]]>]]], ["predawn", #[["general", <$ctext_frob, [["The sky to the east brightens."], #[]]>]]], ["sunset", #[["general", <$ctext_frob, [["The sun slowly dips beneath the horizon."], #[]]>]]]];
var $root help_node = $help_places_realms;
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];

public method .new() {
    var i;
    
    (sender().is($place)) || throw(~place, sender() + " is not a place.");
    local = local.setadd(sender());
    .cleanup_local();
    return this();
};

protected method .set_realm_local() {
    arg new;
    
    local = new;
};

root method .uninit_realms_frob() {
    var x;
    
    for x in (local)
        (| (x[1]).set_realm($realm_of_creation) |);
};

public method .place_destroyed() {
    arg @args;
    
    (sender() == (.manager())) || (> .perms(caller(), $place) <);
    (| (local = local.setremove(sender())) |);
};

public method .local() {
    return local;
};

frob method .name() {
    arg @args;
    
    return (> pass(@args) <);
};

public method .realm_name() {
    var realms;
    
    realms = .realms();
    if ((realms.length()) > 2)
        realms = [realms[1], realms.last()];
    return realms.join(", ");
};

public method .realms() {
    var r;
    
    if (definer() == this())
        return [];
    return [.name()] + (((.parents())[1]).realms());
};

public method .cleanup_local() {
    var i, t;
    
    t = this();
    local = filter i in (local) where ((| (i.realm()) == t |));
};

root method .uninit_realm() {
    var x;
    
    for x in (local)
        (| x.set_realm($realm_of_creation) |);
};

public method .init_realm() {
    local = [];
    links = #[];
};

public method .ctext_variables() {
    var climate, weather, season, depend, timeobj, timezone, ret;
    
    [weather, season, climate, depend, timeobj, timezone] = .get_setting("weather-time", $realm);
    ret = (| climate.ctext_variables(weather, season) |) || #[];
    ret = ret.add('daytime, timeobj.daytime(timezone, (| climate.daylength(season) |) || 0));
    ret = ret.add('evaluator, $realm_base_eval);
    return ret;
};

public method .add_exit_to() {
    arg dest;
    
    (> .perms(caller(), $place) <);
    if ((dest.realm()) != this()) {
        links = links || #[];
    
        // Do a quick sanity check before adding a new cross-realm exit
        ._check_links();
    
        // The format is: links, source, destination, path source->dest
        links = links.add_elem(dest.realm(), [this(), sender(), dest, []]);
    }
};

public method ._check_links() {
    arg @propagate_check;
    var i, j, k, d;
    
    (caller() == $realm_admin_ui) || (> .perms(caller(), $realm) <);
    d = #[];
    for i in (links || #[]) {
        for j in (i[2]) {
            // Run at low priority...
            refresh();
            if (!(j[4])) {
                if ((j[2]).is_connected_to(j[3]))
                    d = d.add_elem(i[1], j);
            } else if (((j[2]).is_connected_to((j[4])[1])) && ((!find k in [1 .. ((j[4]).length()) - 1] where (refresh() && (!(((j[4])[k]).is_connected_to((j[4])[k + 1]))))) && (((j[4]).last()).is_connected_to(j[3])))) {
                d = d.add_elem(i[1], j);
            }
        }
    }
    links = d;
    if (propagate_check)
        (| ((.parents())[1])._check_links(@propagate_check) |);
};

public method .advance_weather() {
    arg ticked;
    var d, new;
    
    (caller() == $world) || (> .perms(sender()) <);
    d = .get_setting("weather-time", $realm);
    if (ticked) {
        d = d.replace(2, (d[5]).current_season());
        new = (d[3]).advance(d[1], d[2], (d[4]) || []);
        if (new != (d[1])) {
            d = d.replace(1, new);
            .set_setting("weather-time", $realm, d);
            .realm_announce(new.eval_message("invoke", $weather, .ctext_variables()));
        }
    }
    new = ((d[5]).daytime(d[6], (d[3]).daylength(d[2])))[2];
    if (new != last_daytime) {
        last_daytime = new;
        .realm_announce(new);
    }
    d = d.replace(2, (d[5]).current_season());
};

public method .realm_announce() {
    arg message;
    
    (caller() == this()) || (> .perms(sender()) <);
    $world.send_event('realm_announce, message);
};

public method .parse_weather_time() {
    arg value;
    var m, climate, depend, i, obj, tmp, str;
    
    if (type(value) == 'list)
        return value;
    if ((!value) || (value == "none"))
        return 0;
    value = (| (value.regexp("^(.+) (.+) in (.+),([^+-]+)([+-] *[0-9]+)?$")).mmap('trim) |);
    if (!value)
        throw(~type, "Value is not parsable as weather/time data.");
    if ((value.length()) < 5)
        value += ["0"];
    if ((m = (value[3]).match_pattern("* influenced by *"))) {
        value = value.replace(3, (m[1]).trim());
        depend = [];
        for i in ((((m[2]).trim()).split(";")).mmap('trim)) {
            refresh();
            [tmp, (str ?= "=50%")] = (i.regexp("([^=]+)(= *[0-9]+%)?")).mmap('trim);
            str = toint(((str.match_pattern("=*%"))[1]).trim());
            if (!(obj = $place_lib.match_realm(tmp)))
                throw(~match, ("Can't find realm " + tmp) + ".");
            depend += [[obj, str]];
        }
        depend ?= 0;
    } else {
        depend = 0;
    }
    if ((m = (value[3]).match_pattern("*($*)")))
        value = value.replace(3, "$" + (m[2]));
    if ((m = (value[4]).match_pattern("*($*)")))
        value = value.replace(4, "$" + (m[2]));
    climate = (> $object_lib.to_dbref(value[3]) <);
    return (> [climate.match_weather(value[1]), value[2], climate, depend, $object_lib.to_dbref(value[4]), toint((value[5]).replace(" ", ""))] <);
};

public method .format_weather_time() {
    arg value;
    var out, i;
    
    if (!value)
        return "None";
    out = "%l %l in %l%l, %l".format((value[1]).name(), value[2], (value[3]).namef('ref), (value[4]) ? (" influenced by " + (map i in (value[4]) to (((i[1]).name()) + (((i[2]) == 50) ? "" : ((" = " + (i[2])) + "%"))).join("; "))) : "", (value[5]).namef('ref));
    if ((value[6]) > 0)
        out += "+";
    if ((value[6]) != 0)
        out += value[6];
    return out;
};

public method .get_msg() {
    arg name, definer;
    var get;
    
    // can only inherit if they use the default 'getter
    if ((get = (| definer.get_msg_attr(name, 'getter) |)))
        return .(get)(name, definer);
    return ._get_msg(name, definer);
};

public method .core_realm() {
    links = #[];
    local = [];
};

protected method ._get_msg() {
    arg name, definer;
    var msg;
    
    if ((msg = (| .get_local_msg(name) |)))
        return dict_union(definer.get_default_msg(name), msg);
    else if (this() == definer)
        return definer.get_default_msg(name);
    else
        return (parents()[1])._get_msg(name, definer);
};

public method .add_local() {
    arg new_dest;
    
    local = $list.setadd(.local(), new_dest);
};

public method .is_buildable_by() {
    arg whom;
    
    if (.trusts(whom))
        return 1;
    else if (this() == definer())
        return 0;
    else
        return (parents()[1]).is_buildable_by(whom);
};

protected method .parse_setting_delay() {
    arg value, @args;
    
    return (> $time.from_english(value) <);
};

protected method .format_setting_delay() {
    arg value;
    
    return $time.to_english(value);
};


new object $realm_of_creation: $realm;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "<Creation>", "<Creation>"];
var $realm local = [$the_pit];
var $root manager = $realm_of_creation;
var $root managed = [$realm_of_creation];
var $realm links = #[];
var $root settings = #[["propagate", 0], ["map-position", 0]];

root method .core_realm_of_creation() {
    .set_realm_local([$the_pit]);
};


new object $tutorial_realm: $realm;

var $root manager = $tutorial_realm;
var $root managed = [$tutorial_realm];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874178606;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Tutorial", "Tutorial"];
var $realm local = [];
var $realm links = #[];
var $root inited = 1;
var $root settings = #[["map-position", 0], ["propagate", 0]];


new object $mail_list_news: $mail_list;

var $root manager = $mail_list_news;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $has_name name = ['prop, "news", "news"];
var $mail_list mail = [];
var $mail_list senders = [];
var $mail_list readers = 1;
var $mail_list notify = [];
var $mail_list last_received_on = 0;
var $root managed = [$mail_list_news];


new object $mail_list_bugs: $mail_list;

var $root manager = $mail_list_bugs;
var $root created_on = 811630223;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "bugs", "bugs"];
var $mail_list mail = [];
var $mail_list senders = 1;
var $mail_list readers = 1;
var $mail_list notify = [];
var $mail_list last_received_on = 0;
var $root managed = [$mail_list_bugs];


new object $mail_postmaster: $mail_list;

var $root manager = $mail_postmaster;
var $root managed = [$mail_postmaster];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 869072520;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "postmaster", "postmaster"];
var $mail_list mail = [];
var $mail_list senders = 1;
var $mail_list readers = 0;
var $mail_list notify = [];
var $root inited = 1;
var $mail_list last_received_on = 0;


new object $mail_admin: $mail_list;

var $root manager = $mail_admin;
var $root managed = [$mail_admin];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 869072525;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "admin", "admin"];
var $mail_list mail = [];
var $mail_list senders = 1;
var $mail_list readers = 0;
var $mail_list notify = [];
var $root inited = 1;
var $mail_list last_received_on = 0;

public method .list_is_readable_by() {
    arg who;
    
    return (> pass(who) <) || ($sys.is_admin(who));
};


new object $mail_list_tracebacks: $mail_list;

var $root manager = $mail_list_tracebacks;
var $root managed = [$mail_list_tracebacks];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 904830832;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "tracebacks", "tracebacks"];
var $mail_list mail = [];
var $mail_list senders = [$no_one];
var $mail_list readers = 0;
var $mail_list notify = [];
var $root inited = 1;
var $mail_list last_received_on = 0;


new object $antisocial: $user_interfaces;

var $root manager = $antisocial;
var $root flags = ['variables, 'methods, 'code, 'fertile, 'core, 'general_cache];
var $root created_on = 838182893;
var $antisocial antisocial_msgs = #[["feh", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " kicks ", <$generator, ["who", [], [], 'gen_who]>, " rather firmly in the kiester."], #[['this, $antisocial]]]>]];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[["ice", [["ice", "*", "ice <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["eye", [["eye", "*", "eye <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["fart", [["fart", "*", "fart <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["kick", [["kick", "*", "kick <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["pat", [["pat", "*", "pat <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["pummel", [["pummel", "*", "pummel <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["poke", [["poke", "*", "poke <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["prod", [["prod", "*", "prod <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["bonk", [["bonk", "*", "bonk <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["hug", [["hug", "*", "hug <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["hit", [["hit", "*", "hit <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["peer", [["peer", "*", "peer <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["bite", [["bite", "*", "bite <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["nip", [["nip", "*", "nip <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["bounce", [["bounce", "*", "bounce <object>", 'anti_cmd, #[[1, ['object, []]]]]]]];
var $root inited = 1;
var $root managed = [$antisocial];
var $foundation defined_msgs = #[["ice", #[['branches, ["general", "actor", "who"]]]], ["eye", #[['branches, ["general", "actor", "who"]]]], ["pat", #[['branches, ["general", "actor", "who"]]]], ["pummel", #[['branches, ["general", "actor", "who"]]]], ["prod", #[['branches, ["general", "actor", "who"]]]], ["kick", #[['branches, ["general", "actor", "who"]]]], ["hug", #[['branches, ["general", "actor", "who"]]]], ["beat", #[['branches, ["general", "actor", "who"]]]], ["hit", #[['branches, ["general", "actor", "who"]]]], ["peer", #[['branches, ["general", "actor", "who"]]]], ["bite", #[['branches, ["general", "actor", "who"]]]], ["nip", #[['branches, ["general", "actor", "who"]]]], ["poke", #[['branches, ["general", "actor", "who"]]]], ["bonk", #[['branches, ["general", "actor", "who"]]]], ["fart", #[['branches, ["general", "actor", "who"]]]], ["bounce", #[['branches, ["general", "actor", "who"]]]]];
var $foundation msgs = #[["ice", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pours a bucket of ice water over ", <$generator, ["who", [], [], 'gen_who]>, "'s head."], #[]]>], ["actor", <$ctext_frob, [["You pour a bucket of ice water over ", <$generator, ["who", [], [], 'gen_who]>, "'s head."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pours a bucket of ice water over your head."], #[]]>]]], ["eye", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " eyes ", <$generator, ["who", [], [], 'gen_who]>, " warily."], #[]]>], ["actor", <$ctext_frob, [["You eye ", <$generator, ["who", [], [], 'gen_who]>, " warily."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " eyes you warily."], #[]]>]]], ["pat", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pats ", <$generator, ["who", [], [], 'gen_who]>, " onna head."], #[]]>], ["actor", <$ctext_frob, [["You pat ", <$generator, ["who", [], [], 'gen_who]>, " onna head."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pats you onna head."], #[]]>]]], ["pummel", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pummels ", <$generator, ["who", [], [], 'gen_who]>, " into a milky white substance."], #[]]>], ["actor", <$ctext_frob, [["You pummel ", <$generator, ["who", [], [], 'gen_who]>, " into a milky white substance."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pummels you into a milky white substance. ouch."], #[]]>]]], ["prod", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " prods ", <$generator, ["who", [], [], 'gen_who]>, " with a cowpoke."], #[]]>], ["actor", <$ctext_frob, [["You prod ", <$generator, ["who", [], [], 'gen_who]>, " with a cowpoke."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " prods you with a cowpoke. ouch."], #[]]>]]], ["kick", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " kicks ", <$generator, ["who", [], [], 'gen_who]>, " firmly in the kiester."], #[]]>], ["actor", <$ctext_frob, [["You kick ", <$generator, ["who", [], [], 'gen_who]>, " firmly in the kiester."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " kicks you firmly in the kiester."], #[]]>]]], ["hug", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " bear hugs ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["actor", <$ctext_frob, [["You bear hug ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " bear hugs you. oif."], #[]]>]]], ["beat", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pulls out a stick and beats the ", <$generator, ["who", [], [], 'gen_who]>, " repeatedly."], #[]]>], ["actor", <$ctext_frob, [["You pull out a stick and beat the ", <$generator, ["who", [], [], 'gen_who]>, " repeatedly."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pulls out a stick and beats you repeatedly."], #[]]>]]], ["hit", #[["general", <$ctext_frob, [["Boldly, ", <$generator, ["actor", [], [], 'gen_actor]>, " pulls out a stick and beats the ", <$generator, ["who", [], [], 'gen_who]>, " repeatedly."], #[]]>], ["actor", <$ctext_frob, [["Boldly, you pull out a stick and beat the ", <$generator, ["who", [], [], 'gen_who]>, " repeatedly."], #[]]>], ["who", <$ctext_frob, [["Boldly, ", <$generator, ["actor", [], [], 'gen_actor]>, " pulls out a stick and beats you repeatedly. oif."], #[]]>]]], ["peer", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " peers suspiciously at ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["actor", <$ctext_frob, [["You peer suspiciously at ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " peers suspiciously at you."], #[]]>]]], ["bite", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " BITES ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["actor", <$ctext_frob, [["You BITE ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " BITES you."], #[]]>]]], ["nip", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " nips at ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["actor", <$ctext_frob, [["You nip at ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " nips at you."], #[]]>]]], ["poke", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " firmly jabs ", <$generator, ["pro", [["actor", 1]], ["pp"], 'gen_pro]>, " index finger into ", <$generator, ["who", [], [], 'gen_who]>, "'s ribs."], #[]]>], ["actor", <$ctext_frob, [["You jab your index finger firmly into ", <$generator, ["who", [], [], 'gen_who]>, "'s ribs."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " firmly jabs ", <$generator, ["pro", [["actor", 1]], ["pp"], 'gen_pro]>, " index finger into your ribs. oif."], #[]]>]]], ["bonk", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " maliciously bonks ", <$generator, ["who", [], [], 'gen_who]>, " onna head."], #[]]>], ["actor", <$ctext_frob, [["You maliciously bonk ", <$generator, ["who", [], [], 'gen_who]>, " onna head."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " maliciously bonks you onna head. oif."], #[]]>]]], ["fart", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " farts in ", <$generator, ["who", [], [], 'gen_who]>, "'s general direction."], #[]]>], ["actor", <$ctext_frob, [["You fart in ", <$generator, ["who", [], [], 'gen_who]>, "'s general direction."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " farts in your general direction."], #[]]>]]], ["bounce", #[["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " bounces towards you obnoxiously!"], #[]]>], ["general", <$ctext_frob, [["You bounce obnoxiously towards ", <$generator, ["who", [], [], 'gen_who]>, "!"], #[]]>]]]];
var $command_cache modules = [];

public method .set_antisocial() {
    arg name, message;
    var mes, partial, compiler;
    
    (> .perms(sender(), 'writer) <);
    if (!antisocial_msgs)
        antisocial_msgs = #[];
    compiler = $compiler;
    message = compiler.compile_cml(message);
    antisocial_msgs = antisocial_msgs.add(name, message);
};

public method .antisocial_msgs() {
    return antisocial_msgs;
};

public method .test() {
    arg @who;
    var vars, m, message;
    
    if (who)
        who = .match_environment(who[1]);
    vars = #[["$actor", this()], ["actor", .name()], ["$who", who], ["who", who.name()]];
    message = (definer().antisocial_msgs())["feh"];
    m = message.set_vars(vars);
    .tell(m);
    .announce(m, this());
};

public method .anti_cmd() {
    arg cmdstr, cmd, @who;
    var message, vars, victim, m, s;
    
    (> .perms(caller(), 'command) <);
    s = sender();
    vars = #[["$actor", s], ["actor", s.name()]];
    if (who)
        vars = (vars.add("$who", who[1])).add("who", (who[1]).name());
    (s.location()).announce(s.eval_message(cmd, definer(), vars));
};


new object $social: $user_interfaces;

var $root manager = $social;
var $root flags = ['variables, 'methods, 'code, 'core, 'general_cache];
var $root created_on = 838260513;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[["bow", [["bow", "*", "bow <object>", 'social_cmd, #[[1, ['object, []]]]]]]];
var $root inited = 1;
var $root managed = [$social];
var $user_interfaces links = 2;
var $command_cache modules = [];
var $foundation defined_msgs = #[["bow", #[['branches, ["actor", "general", "victim"]]]]];
var $foundation msgs = #[["bow", #[["actor", <$ctext_frob, [["You bow to ", <$generator, ["victim", [], [], 'gen_victim]>, "."], #[]]>], ["victim", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " bows to you."], #[]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " bows to ", <$generator, ["victim", [], [], 'gen_victim]>, "."], #[]]>]]]];

public method .social_cmd() {
    arg cmdstr, cmd, @who;
    var vars, i, n, s;
    
    (> .perms(caller(), 'command) <);
    s = sender();
    vars = #[["$actor", s], ["actor", s.name()]];
    n = 0;
    for i in (who) {
        if ((| i.name() |)) {
            vars = (vars.add(n ? ("$victim_" + n) : "$victim", i)).add(n ? ("victim_" + n) : "victim", i.name());
            n++;
        }
    }
    (s.location()).announce(.eval_message(cmd, $social, vars));
};


new object $httpd_ui: $user_interfaces;

var $root manager = $httpd_ui;
var $command_cache modules = [];
var $root flags = ['variables, 'methods, 'code, 'core, 'general_cache];
var $root created_on = 887523264;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[["@list-entries", [["@list-entries", "on *", "@list-entries on <descendant of $directories>", 'list_entries_cmd, #[[2, ['descendant, [$directories]]]]]]], ["@add-entry", [["@add-entry", "* to *", "@add-entry <any:+t?arget> to <descendant of $directories>", 'add_entry_cmd, #[[1, ['any_opt, ["t?arget"]]], [3, ['descendant, [$directories]]]]]]], ["@del-entry", [["@del-entry", "* from *", "@del-entry <any> from <descendant of $directories>", 'del_entry_cmd, #[[1, ['any, []]], [3, ['descendant, [$directories]]]]]]]];
var $root inited = 1;
var $root managed = [$httpd_ui];
var $root credit = ["Bruce Mitchener, Jr <bruce@puremagic.com>"];

public method .list_entries_cmd() {
    arg cmd, cmdstr, prep, directory;
    var output, x;
    
    output = map x in (directory.entries()) to ($cml_lib.format_tr_tag($cml_lib.format_td_tag(x[1]), $cml_lib.format_td_tag(x[2])));
    return $ctext_frob.new_with([("Directory entries for " + directory) + ":", $cml_lib.format_table_tag("25%,75%", @output), $cml_lib.format_sep_tag()]);
};

public method .add_entry_cmd() {
    arg cmd, cmdstr, @args;
    var name, opt, prep, directory, target;
    
    [[[name], [opt]], prep, directory] = args;
    if ((opt.length()) != 4)
        return "You must specify the target object via +target.";
    target = opt[4];
    if (!(target = (| $object_lib.to_dbref(target) |)))
        return "The target must be a valid object.";
    if (!(target.is($page)))
        return "The target must be a descendant of $page.";
    directory.add_entry(name, target);
    return;
};

public method .del_entry_cmd() {
    arg cmd, cmdstr, @args;
    var name, prep, directory;
    
    [name, prep, directory] = args;
    catch ~keynf {
        directory.del_entry(name);
        sender().tell(((("Entry, '" + name) + "', removed from ") + directory) + ".");
    } with {
        sender().tell(((("Entry, '" + name) + "', was not an entry on ") + directory) + ".");
    }
    return;
};


new object $settings_ui: $user_interfaces;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_commands local = #[["@set?tings", [["@set?tings", "on|from *", "@set?tings on|from <object reference>", 'settings_on_cmd, #[[2, ['objref, []]]]]]], ["@set|@setting?s", [["@set|@setting?s", "*", "@set|@setting?s <any>", 'set_cmd, #[[1, ['any, []]]]]]]];
var $root manager = $settings_ui;
var $root managed = [$settings_ui];
var $command_cache modules = [];
var $command_cache shortcuts = 0;
var $command_cache commands = 0;

protected method .settings_cmd() {
    arg cmdstr, cmd, args;
    var flag, value, template, syn, bool, line;
    
    (> .perms(caller(), 'command) <);
    syn = cmd + " [+|-]<flag>[=<value>]";
    if (!args) {
        return .list_settings('local);
    } else if (args in ["-all", "-a"]) {
        return .list_settings('all);
    } else {
        bool = (args[1]) in ["-", "+"];
        if (bool)
            args = args.subrange(2);
        args = args.explode("=");
        flag = args[1];
        if ((args.length()) == 2)
            value = args[2];
        else
            value = "";
        template = .setting_template(flag);
        if (!template)
            return ("No setting available with the flag \"" + flag) + "\".";
        switch (template[2]) {
            case 'boolean:
                if (!bool)
                    return ("Value must be boolean (+|-" + flag) + ").";
                value = bool - 1;
            case 'integer:
                if (!($string.is_numeric(value)))
                    return ("Value must be an integer (" + flag) + "=<integer>).";
                value = toint(value);
            case 'string:
                if (!value)
                    return ("Value must be a string (" + flag) + "=<string>).";
        }
        .OLD_set_setting(flag, value);
        line = ("Setting " + flag) + " set to ";
        switch (template[2]) {
            case 'boolean:
                line += (value == 1) ? "+" : "-";
            default:
                line += toliteral(value);
        }
        .tell(line);
    }
};

protected method .settings_on_cmd() {
    arg cmdstr, cmd, prep, ref;
    
    (> .perms(caller(), 'command) <);
    
    // this is a hookneyed way to do it, and wont work out in the long run,
    // but until we get arguments in the parser this will work fine
    if ((ref[2]) == (ref[3]))
        return ._show_settings(ref[3]);
    else
        return ._show_settings_on(ref[3], ref[2]);
};

public method ._show_setting() {
    arg setting, definer, object;
    var line;
    
    line = ("  " + setting) + " = ";
    setting = (| object.display_setting(setting, definer) |);
    if (setting != ~setting)
        line += setting;
    return line;
};

public method ._show_settings_on() {
    arg definer, object;
    var settings, s, setting, line, out;
    
    if (!(object.trusts(this())))
        return [(definer.namef('xref)) + ":", "  ** Unable to see settings **"];
    settings = (| definer.OLD_defined_settings() |) || [];
    out = [];
    for s in (settings)
        out += [._show_setting(s, definer, object)];
    if (!out)
        out = ["  (none)"];
    return [(definer.namef('xref)) + ":"] + out;
};

protected method .set_cmd() {
    arg cmdstr, cmd, args;
    var opt, definer, t, p, name, value, object, reg, s;
    
    (> .perms(caller(), 'command) <);
    if (!args)
        return ._show_settings(this());
    if ((reg = regexp(args, "^ *(.*)<([^)]+)>(.*) *$"))) {
        definer = (> .match_env_nice(reg[2]) <);
        args = (((reg[1]).trim()) + " ") + ((reg[3]).trim());
    }
    if ((reg = regexp(args, "^ *([^:=]+): *(.*) *$"))) {
        object = (> .match_env_nice(reg[1]) <);
        args = reg[2];
    } else {
        object = this();
    }
    if ((reg = regexp(args, "^ *([a-z0-9_@-]+)[ =](.*)$"))) {
        name = (reg[1]).trim();
        args = (reg[2]).trim();
    } else {
        name = args;
        args = "";
    }
    if (!name)
        return [("-- Settings on " + (object.namef('ref))) + ":", ._show_settings(object), "--"];
    
    // this should fix the quotes
    value = args.unquote();
    
    // change it
    catch any {
        ._change_setting(name, value, definer, object);
        .tell(["-- Setting changed to:", ._show_setting(name, definer, object), "--"]);
    } with {
        return (traceback()[1])[2];
    }
};

public method ._show_settings() {
    arg object;
    var a, s, out;
    
    if (!(object.trusts(this())))
        return (((object.namef('ref)) + " does not trust you enough to show you ") + (((| object.gender() |) || $gender_neuter).pronoun('pp))) + " settings.";
    out = [];
    for a in (object.ancestors()) {
        if (a == $has_settings)
            break;
        s = (| a.OLD_defined_settings() |);
        if (s)
            out += [._show_settings_on(a, object)];
    }
    return out.reverse();
};

public method ._change_setting() {
    arg name, value, definer, object;
    var current, style, index, pos;
    
    (> .perms(sender(), 'writers) <);
    style = name.last();
    if (style in ["+", "-"]) {
        name = name.subrange(1, (name.length()) - 1);
        if (!definer)
            definer = object._find_setting_definer(name);
        current = (object.setting(name, definer)) || [];
        if (style == "+")
            value = [@current || [], value];
        else
            value = current.delete(toint(value));
    }
    catch ~check, ~set
        (> object.OLD_set_setting(definer, name, value) <);
    with
        throw(~stop, (traceback()[1])[2]);
};


new object $network: $core;

var $root manager = $network;
var $root created_on = 809051864;
var $root inited = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root managed = [$network];

protected method .ip(): native;

protected method .hostname(): native;


new object $connection: $network;

var $root manager = $connection;
var $root created_on = 809051864;
var $root inited = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $connection buffer = `[];
var $connection host = "";
var $connection daemon = 0;
var $connection active = 0;
var $connection line_buffer = 0;
var $connection interface = 0;
var $connection timeout = 0;
var $connection read_block = [];
var $connection started_at = 0;
var $connection port = 0;
var $connection foreign_addr = 0;
var $connection local_port = 0;
var $connection local_addr = 0;
var $connection remote_port = 0;
var $connection remote_addr = 0;
var $connection remote_name = 0;
var $root managed = [$connection];
var $connection tid = 0;
var $root defined_settings = #[["interface", #[['get, ['get_interface]], ['set, ['set_interface]], ['parse, ['parse_interface]]]]];
var $connection debugees = 0;

public method .daemon_shutdown() {
    var c;
    
    // called by $daemon.stop_listening()
    (> .perms(caller(), $daemon) <);
    for c in (.children())
        (> c.close() <);
    (> interface.daemon_shutdown() <);
};

root method .init_connection() {
    buffer = `[];
    local_addr = (remote_addr = "");
    line_buffer = [];
    timeout = 300;
    tid = -1;
    
    // remove all flags
    .set_flags([]);
};

root method .uninit_connection() {
    (| close_connection() |);
    active = 0;
    if (interface)
        (| interface.connection_going_away(remote_addr, remote_port) |);
    interface = 0;
    if (read_block) {
        read_block = read_block.add('lines, 'disconnected);
        .finish_reading_block();
    }
    if (tid != (-1))
        $scheduler.del_task(tid);
    tid = 0;
};

public method .timeout() {
    return timeout;
};

public method .address() {
    arg @nolookup;
    var name;
    
    (> .perms(sender()) <);
    return remote_addr;
    if (!remote_name) {
        name = (| $dns.hostname(remote_addr) |);
        if (name)
            remote_name = name;
        else
            remote_name = remote_addr;
    }
    return remote_name;
};

public method .set_timeout() {
    arg seconds;
    
    (> .perms(sender(), interface, this()) <);
    timeout = seconds;
    if (!timeout)
        (| clear_var('timeout) |);
};

public method .change_interface() {
    arg new;
    var old;
    
    (> .perms(sender()) <);
    (> .perms(caller(), $login_interface) <);
    if (interface) {
        old = interface;
        old.connection_going_away(.address(), remote_port);
    }
    interface = new;
    (.manager()).change_connection_interface(old, new);
    interface.connection_starting(.address(), remote_port);
};

public method .new_interface() {
    arg obj;
    
    (> .perms(sender()) <);
    interface = obj;
};

public method .set_daemon() {
    arg obj;
    
    (> .perms(sender()) <);
    daemon = obj;
};

public method .write() {
    arg what, @how;
    var elem, sep;
    
    (> .perms(sender()) <);
    sep = ('non_terminated in how) ? `[] : `[13, 10];
    switch (type(what)) {
        case 'string:
            what = strings_to_buf([what], sep);
        case 'list:
            what = strings_to_buf(what, sep);
        case 'buffer:
        default:
            throw(~type, "Write: strings, list of strings and buffers.");
    }
    cwrite(what);
};

driver method .parse() {
    arg incoming;
    var lines, line, index;
    
    lines = buf_to_strings(buffer + incoming);
    index = listlen(lines);
    buffer = lines[index];
    lines = delete(lines, index);
    line_buffer += lines;
    while (line_buffer) {
        line = line_buffer[1];
        line_buffer = delete(line_buffer, 1);
        (| .parse_line(line) |);
    }
};

protected method .parse_line() {
    arg line;
    
    if (read_block) {
        read_block = read_block.parse(line);
        line = .rehash_read_status();
        if ((!line) && (line != ""))
            return;
    }
    if ((interface.parse_line(line)) == 'disconnect)
        (> .close() <);
};

public method .cwritef() {
    arg fname;
    
    (> .perms(sender()) <);
    (> cwritef(fname) <);
};

public method .is_reading_block() {
    return read_block ? 1 : 0;
};

public method .finish_reading_block() {
    var task_id, lines;
    
    (> .perms(sender()) <);
    task_id = read_block.task_id();
    lines = read_block.lines();
    read_block = 0;
    $scheduler.resume(task_id, lines);
};

public method .abort_reading_block() {
    (> .perms(sender()) <);
    read_block = read_block.add('lines, 'aborted);
    .finish_reading_block();
};

public method .start_reading_block() {
    arg count;
    
    (> .perms(sender()) <);
    read_block = $read_parser.new_with(task_id(), count);
    (| .push_buffered() |);
    return (> $scheduler.suspend(this()) <);
};

protected method .rehash_read_status() {
    switch (read_block.status()) {
        case 'abort:
            .abort_reading_block();
        case 'not_done:
            // do nothing
        case 'done:
            .finish_reading_block();
        case 'pass_command:
            return read_block.command();
    }
    return 0;
};

protected method .do_timeout() {
    if (!timeout)
        return;
    .write(("Timeout (" + tostr(timeout)) + ")");
    .close();
};

public method .close() {
    (sender() != this()) && (> .perms(sender()) <);
    (> $sys.destroy_sender() <);
};

driver method .disconnect() {
    .close();
};

public method .set_remote_port() {
    arg port;
    
    (> .perms(sender()) <);
    remote_port = port;
};

public method .new_connection() {
    var new, i;
    
    (> .perms(caller(), $daemon) <);
    new = .spawn();
    i = interface.new(new);
    new.add_writer(sender());
    new.add_writer(interface);
    new.add_writer((| class(i) |) || i);
    new.add_writer(this());
    new.new_interface(i);
    return new;
};

public method .active() {
    return active;
};

public method .write_string() {
    arg string;
    
    if ((sender() != interface) && (sender() != (| class(interface) |)))
        throw(~perm, sender() + " cannot write this connection.");
    if (type(string) != 'string)
        throw(~type, "Argument must be a string.");
    cwrite($buffer.from_string(string));
};

public method .write_strings() {
    arg strings;
    
    if ((sender() != interface) && (sender() != (| class(interface) |)))
        throw(~perm, sender() + " cannot write this connection.");
    if (type(strings) != 'list)
        throw(~type, "Argument must be a list of strings.");
    cwrite($buffer.from_strings(string));
};

public method .write_buffer() {
    arg buffer;
    
    if ((sender() != interface) && (sender() != (| class(interface) |)))
        throw(~perm, sender() + " cannot write this connection.");
    if (type(buffer) != 'buffer)
        throw(~type, "Argument must be a buffer.");
    cwrite(buffer);
};

public method .active_since() {
    return active;
};

public method .start() {
    arg remote, local, rport, lport;
    
    // Make this method 'fork' from the regular thread stack
    (> .perms(caller(), $daemon) <);
    active = time();
    remote_addr = remote;
    remote_port = rport;
    local_addr = local;
    local_port = lport;
    
    //    if (timeout)
    //        $scheduler.add_task(timeout, 'do_timeout);
    interface.connection_starting(.address(), remote_port);
};

public method .interface() {
    (caller() == $daemon) || (> .perms(sender()) <);
    return interface;
};

public method .interface_going_away() {
    if ((sender() != interface) && (sender() != (| class(interface) |)))
        throw(~perm, sender() + " is not the interface.");
    interface = 0;
    (> $sys.destroy_sender() <);
};

protected method .open_connection() {
    arg host, port;
    
    (> open_connection(host, port) <);
};

protected method .set_active() {
    arg value;
    
    active = value;
};

public method .change_connection_interface() {
    arg old, new;
    var i;
    
    (> .perms(caller(), $connection) <);
    if (old)
        sender().del_writer((| class(old) |) || old);
    sender().add_writer((| class(new) |) || new);
};

private method .push_buffered(): forked {
    var line;
    
    // called when a read() suspends the connection--to finish unbuffering i/o
    while (line_buffer) {
        line = line_buffer[1];
        line_buffer = delete(line_buffer, 1);
        (| .parse_line(line) |);
    }
};

protected method .get_ident() {
    return $ident_connection.get(remote_addr, remote_port, local_port);
};

protected method .get_interface() {
    arg @args;
    
    return interface;
};

protected method .set_interface() {
    arg name, definer, value, @args;
    
    interface = value;
};

public method .parse_interface() {
    arg value, @args;
    var obj;
    
    obj = (> $object_lib.to_dbref(value) <);
    return obj;
};


new object $outbound_connection: $connection;

var $root manager = $outbound_connection;
var $root quota = 100000;
var $root inited = 1;
var $root created_on = 844616370;
var $root quota_exempt = -1;
var $connection buffer = `[];
var $connection remote_addr = "";
var $connection local_addr = "";
var $connection line_buffer = [];
var $connection timeout = 0;
var $connection host = "";
var $connection daemon = 0;
var $connection active = 0;
var $connection interface = 0;
var $connection read_block = 0;
var $connection started_at = 0;
var $root trusted = [$smtp, $dns];
var $root flags = ['core, 'methods, 'code, 'variables];
var $root managed = [$outbound_connection];

driver method .connect() {
    arg task_id;
    
    $scheduler.resume(task_id, 'success);
};

driver method .failed() {
    arg task_id, reason;
    
    $scheduler.resume(task_id, reason);
};

public method .open_connection() {
    arg host, port;
    var condition;
    
    (> .perms(sender()) <);
    (> pass(host, port) <);
    condition = $scheduler.suspend(this());
    if (condition != 'success)
        throw(condition, "Unable to open connection.");
    return condition;
};

public method .new() {
    var child, daemon, port, i;
    
    (| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
    child = .spawn();
    
    // do perms stuff
    child.add_writer(sender());
    child.add_writer(this());
    child.new_interface(sender());
    return child;
};

public method .new_with() {
    arg name;
    var child, daemon, port, i;
    
    (| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
    child = .spawn();
    catch any {
        (> child.set_objname(name) <);
    } with {
        (| child.destroy() |);
        rethrow(error());
    }
    
    // do perms stuff
    child.add_writer(sender());
    child.new_interface(sender());
    return child;
};


new object $ident_connection: $outbound_connection;

var $root manager = $ident_connection;
var $ident_connection task = 0;
var $root inited = 1;
var $root created_on = 859834690;
var $connection buffer = `[];
var $connection remote_addr = "";
var $connection local_addr = "";
var $connection line_buffer = [];
var $connection timeout = 300;
var $connection tid = -1;
var $root flags = ['core, 'methods, 'code, 'variables];
var $root quota_exempt = 1;
var $root managed = [$ident_connection];

public method .get_ident() {
    arg host, remote_port, local_port;
    var out;
    
    (> .perms(caller(), definer()) <);
    task = task_id();
    catch any
        .open_connection(host, 113);
    with
        return [];
    .write(((remote_port + ", ") + local_port) + "\n");
    out = $scheduler.suspend(this());
    .close();
    return out.explode(":");
};

protected method .parse_line() {
    arg line;
    
    return $scheduler.resume(task, line);
};

public method .get() {
    arg @args;
    var conn;
    
    (caller() != $connection) && (> .perms(sender()) <);
    conn = .spawn();
    conn.add_writer(sender());
    return conn.get_ident(@args);
};


new object $inbound_connection: $connection;

var $root manager = $inbound_connection;
var $root flags = ['core, 'methods, 'code, 'variables];
var $root inited = 1;
var $root created_on = 868487559;
var $dmi_data descriptions = #[];
var $connection buffer = `[];
var $connection remote_addr = "";
var $connection local_addr = "";
var $connection line_buffer = [];
var $connection timeout = 300;
var $connection tid = -1;
var $root managed = [$inbound_connection];


new object $http_connection: $inbound_connection;

var $root manager = $http_connection;
var $root created_on = 809075134;
var $root inited = 1;
var $root quota_exempt = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $connection buffer = `[27];
var $connection host = "";
var $connection daemon = 0;
var $connection active = 0;
var $connection line_buffer = [];
var $connection interface = $http_interface;
var $connection timeout = 0;
var $connection read_block = 0;
var $connection started_at = 0;
var $root managed = [$http_connection];
var $http_connection buffer = 0;
var $http_connection line_buffer = 0;
var $http_connection reading = 0;

root method .init_http_connection() {
    buffer = `[];
    line_buffer = [];
};

public method .start() {
    arg @args;
    
    .set_timeout(0);
    return (> pass(@args) <);
};

public method .handle_POST_input() {
    arg len;
    var body;
    
    if (buflen(buffer) < len) {
        reading = 300;
        while ((buflen(buffer) < len) && --reading) {
            $scheduler.sleep(1);
            refresh();
        }
        if (buflen(buffer) < len) {
            buffer = `[];
            status = 400;
            reading = 0;
            throw(~timeout, "Timeout on receiving POST request");
        }
    }
    body = buf_to_strings(subbuf(buffer, 1, len));
    buffer = subbuf(buffer, len + 1);
    if ((`[13, 10] in buffer) == 1)
        buffer = subbuf(buffer, 3);
    if ((body[listlen(body)]) == `[])
        body = delete(body, listlen(body));
    else
        body = replace(body, listlen(body), buf_to_str(body[listlen(body)]));
    reading = 0;
    return body;
};

driver method .parse() {
    arg incoming;
    var l, line, i, t, int, sub;
    
    catch any {
        buffer += incoming;
        int = .interface();
        while (!reading) {
            if (!(i = `[13, 10] in buffer))
                break;
            sub = subbuf(buffer, 1, i - 1);
            line = buf_to_str(sub);
            buffer = subbuf(buffer, i + 2);
            (> int.parse_line(line) <);
        }
    } with {
        int.set_status(500);
        int.respond($parse_lib.html_traceback(traceback(), 500));
    }
};


new object $smtp_connection: $inbound_connection;

var $root manager = $smtp_connection;
var $connection interface = $smtp_interface;
var $root inited = 1;
var $root created_on = 849170589;
var $connection buffer = `[];
var $connection remote_addr = "";
var $connection local_addr = "";
var $connection line_buffer = [];
var $connection timeout = 300;
var $root quota_exempt = 1;
var $root managed = [$smtp_connection];
var $root flags = ['core, 'variables, 'methods, 'code];


new object $login_connection: $inbound_connection;

var $root manager = $login_connection;
var $root created_on = 809051865;
var $root inited = 1;
var $root quota_exempt = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $connection interface = $login_interface;
var $connection active = 0;
var $connection buffer = `[];
var $connection host = "";
var $connection daemon = 0;
var $connection line_buffer = [];
var $connection timeout = 0;
var $connection read_block = 0;
var $connection started_at = 0;
var $root managed = [$login_connection];

public method .local_echo_off() {
    (sender() == (.interface())) || (> .perms(sender()) <);
    cwrite(`[255, 251, 1]);
};

public method .local_echo_on() {
    (sender() == (.interface())) || (> .perms(sender()) <);
    cwrite(`[255, 252, 1]);
};


new object $pop3_connection: $inbound_connection;

var $root manager = $pop3_connection;
var $connection interface = $pop3_interface;
var $root inited = 1;
var $root created_on = 872047000;
var $dmi_data descriptions = #[];
var $connection buffer = `[];
var $connection remote_addr = "";
var $connection local_addr = "";
var $connection line_buffer = [];
var $connection timeout = 300;
var $connection tid = -1;
var $root flags = ['core, 'methods, 'variables, 'code];
var $root managed = [$pop3_connection];
var $root quota_exempt = 1;


new object $smtp: $network;

var $root manager = $smtp;
var $smtp maildrop = "127.0.0.1";
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 845213524;
var $root managed = [$smtp];
var $root inited = 1;
var $smtp postmaster = 0;
var $smtp valid_email_regexp = "^[-a-z0-9_!.%+$'=]+[^.]$";
var $root trusted_by = [$outbound_connection];
var $root trusted = [$login_interface, $user_info, $mail_message];
var $smtp timeouts = #[];
var $smtp mail_aliases = #[["postmaster", $mail_postmaster], ["admin", $mail_admin], ["abuse", $mail_admin], ["MAILER-DAEMON", $mail_postmaster]];
var $smtp hosts = 0;
var $root defined_settings = #[["aliases", #[['get, ['get_aliases_setting]], ['set, ['set_aliases_setting]], ['parse, ['parse_itemlist, 'parse_alias_setting]], ['format, ['fmt_aliases_setting]]]], ["hosts", #[['get, ['get_hosts_setting]], ['set, ['set_hosts_setting]], ['parse, ['parse_itemlist, 'parse_host_setting]], ['format, ['format_itemlist]]]], ["maildrop", #[['get, ['get_maildrop_setting]], ['set, ['set_maildrop_setting]], ['parse, ['parse_maildrop_setting]], ['format, ['fmt_maildrop_setting]]]], ["cold-relay-recip", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $root settings = #[["cold-relay-recip", 0]];

protected method .get_response() {
    arg c;
    var line, code, m, more, out;
    
    if (c.is_reading_block())
        throw(~engaged, "Connection is already reading.");
    more = 1;
    out = [];
    while (more) {
        line = c.start_reading_block('one);
        if (line == 'disconnected)
            throw(~aborted, "Connection read aborted.");
        line = line[1];
        if (line == 'aborted)
            throw(~aborted, "Connection read aborted.");
        m = regexp(line, "^([0-9]+)([- ])(.*)$");
        if (listlen(m) != 3)
            throw(~invalid, "Unexpected response from server: " + line);
        more = (m[2]) == "-";
        out += [[toint(m[1]), m[3]]];
    }
    return out;
};

public method .sendmail() {
    arg from, recip, subj, body;
    var mailagent, header, c;
    
    if ((!(.trusts(caller()))) && (!(.trusts(sender()))))
        throw(~perm, ("Permission Denied: " + sender()) + " is not trusted.");
    mailagent = ((((($motd.server_name()) + " (") + ((| (.get_hosts_setting())[1] |) || "")) + ":") + ($login_daemon.current_port())) + ")";
    (> .parse_email_address(recip) <);
    if (!from)
        from = 'postmaster;
    if (type(from) == 'symbol)
        from = .get_email_address(from);
    header = ["Date: " + ($time.format("%a, %d %b %Y %H:%M:%S %Z")), "From: " + from, "To: " + recip, "Subject: " + subj, "Errors-to: " + (.get_email_address('postmaster)), "X-Mail-Agent: " + mailagent];
    
    // connect to maildrop
    c = (> .connect_to_smtp_host(maildrop) <);
    
    // send it off
    catch any {
        (> .MAIL_FROM(c, from) <);
        (> .RCPT_TO(c, recip) <);
        (> .DATA(c, (header + [""]) + body) <);
        (> .QUIT(c) <);
        .close_session(c);
    } with {
        .close_session(c);
        rethrow(error());
    }
};

protected method .set_timeout() {
    arg c, timeout;
    var task;
    
    task = (| timeouts[task_id()] |);
    if (task)
        (| $scheduler.del_task(task) |);
    if (timeout) {
        task = $scheduler.add_task(timeout, 'timeout, [c]);
        timeouts = dict_add(timeouts || #[], task_id(), task);
    } else if (dict_contains(timeouts || #[], task_id())) {
        timeouts = dict_del(timeouts, task_id());
    }
};

public method .parse_email_address() {
    arg address, @lookup;
    var name, host, ip, h;
    
    if (!address)
        throw(~invemail, "No email address supplied.");
    address = explode(address, "@");
    if (listlen(address) != 2)
        throw(~invemail, ("\"" + (address.join("@"))) + "\" is not a valid email address.");
    [name, host] = address;
    if (!match_regexp(name, valid_email_regexp))
        throw(~invemail, ("'" + name) + "' is not a valid Internet mail username");
    if (lookup) {
        ip = $dns.ip(host);
        if ((!ip) || (ip == "-1"))
            throw(~invemail, ("'" + host) + "' does not resolv to an IP address");
        h = $dns.hostname(ip);
        if (!($dns.valid_hostname(h)))
            throw(~invemail, (("Invalid DNS entry for: " + host) + "/") + ip);
        host = h;
    } else if (!($dns.valid_hostname(host))) {
        throw(~invemail, ("Invalid hostname \"" + host) + "\"");
    }
    return [name, host, ip];
};

public method .parse_maildrop_setting() {
    arg value, @args;
    var name, ip;
    
    [(name ?= ""), (ip ?= "")] = explode(value, "/");
    if (!ip) {
        if (!name)
            name = "localhost";
        ip = (> $dns.ip(name) <);
    } else {
        (> $dns.hostname(ip) <);
    }
    return ip;
};

public method .parse_host_setting() {
    arg value, action, @args;
    
    if (action == 'del) {
        if (!(value in hosts))
            throw(~failed, ("The host '" + value) + "' is not set, and thus cannot be removed");
        return value;
    } else {
        (> $dns.ip(value) <);
        return lowercase(value);
    }
};

protected method .set_maildrop_setting() {
    arg name, definer, value;
    
    maildrop = value;
};

public method .get_maildrop_setting() {
    arg @args;
    
    return maildrop;
};

public method .connection_starting() {
    arg addr, port;
    
};

public method .connection_going_away() {
    arg addr, port;
    
};

protected method .RSET() {
    arg c;
    var lines, code, line, i;
    
    .set_timeout(c, 120);
    c.write("RSET");
    
    // get it, but ignore it
    lines = (> .get_response(c) <);
};

protected method .timeout() {
    arg conn;
    
    (| conn.close() |);
};

root method .core_smtp(): nooverride {
    maildrop = "127.0.0.1";
    hosts = 0;
    .set_setting("cold-relay-recip", $smtp, "no");
};

protected method .close_session() {
    arg c;
    
    (| c.close() |);
    .set_timeout(c, 0);
};

protected method .connect_to_smtp_host() {
    arg ip, @host;
    var line, c;
    
    if (host)
        host = host[1];
    else
        host = ip;
    c = $outbound_connection.new();
    catch any {
        c.open_connection(ip, 25);
        (> .negotiate_connect(c) <);
    } with {
        (| c.close() |);
        if (error() == ~refused)
            throw(~refused, "Unable to open SMTP connection to " + host);
        else
            rethrow(error());
    }
    return c;
};

protected method .negotiate_connect() {
    arg c;
    var lines, code, line;
    
    .set_timeout(c, 120);
    lines = (> .get_response(c) <);
    [code, line] = lines[1];
    if (code == 421)
        throw(~notavail, (lines.slice(2)).join());
    if (code != 220)
        throw(~invalid, (("Unknown response from server: " + code) + " ") + line);
    .set_timeout(c, 120);
    c.write("HELO " + ($sys.server_info('server_hostname)));
    lines = (> .get_response(c) <);
    [code, line] = lines[1];
    if (code == 250)
        return;
    if ((code % 500) < 100)
        throw(~syntax, "I'm doing something wrong: " + line);
    if (code == 421)
        throw(~notavail, (lines.slice(2)).join());
    throw(~invalid, (("Unknown response from server: " + code) + " ") + line);
};

protected method .RCPT_TO() {
    arg c, address;
    var lines, code, line;
    
    .set_timeout(c, 120);
    c.write(("RCPT TO: <" + address) + ">");
    lines = (> .get_response(c) <);
    [code, line] = lines[1];
    if ((code < 300) && (code >= 200))
        return [code, lines.slice(2)];
    throw(~error, (lines.slice(2)).join(), code);
};

protected method .MAIL_FROM() {
    arg c, address;
    var lines, code, line;
    
    .set_timeout(c, 120);
    c.write(("MAIL FROM: <" + address) + ">");
    lines = (> .get_response(c) <);
    [code, line] = lines[1];
    if (code == 250)
        return lines.slice(2);
    throw(~error, (("ERROR FROM " + maildrop) + ": ") + ((lines.slice(2)).join()), code);
};

protected method .VRFY() {
    arg c, address;
    var lines, code, line;
    
    .set_timeout(c, 120);
    c.write("VRFY " + address);
    lines = (> .get_response(c) <);
    [code, line] = lines[1];
    if ((code < 300) && (code >= 200))
        return [code, lines.slice(2)];
    throw(~error, (lines.slice(2)).join(), code);
};

protected method .DATA() {
    arg c, body;
    var lines, code, line, i;
    
    .set_timeout(c, 120);
    c.write("DATA");
    lines = (> .get_response(c) <);
    [code, line] = lines[1];
    if (code != 354)
        throw(~error, (lines.slice(2)).join(), code);
    
    // escape period DATA termination
    while ((i = find i in (body) where (i == ".")))
        body = replace(body, i, "..");
    
    // send it
    c.write(body + ["."]);
    lines = (> .get_response(c) <);
    [code, line] = lines[1];
    if (code != 250)
        throw(~error, (lines.slice(2)).join(), code);
};

public method .verify_email_address() {
    arg address;
    var c, lines, code, email, name, m;
    
    if (!(| .perms(caller(), 'trusts) |))
        (> .perms(sender(), 'trusts) <);
    
    // connect
    address = (> .parse_email_address(address, 'resolv_host) <);
    c = (> .connect_to_smtp_host(address[3], address[2]) <);
    
    // VRFY enabled?
    catch ~error {
        [code, lines] = (> .VRFY(c, address[1]) <);
        if (code == 250) {
            .QUIT(c);
            .close_session(c);
    
            // munch on it a little
            if ((m = regexp(lines[1], "^([^<]+)<([^>]+)>"))) {
                [name, email] = m;
            } else if ((m = regexp(lines[1], "<([^>]+)>"))) {
                email = m[1];
                name = strsed(lines[1], " *<[^>]+> *", "");
            } else {
                [email, (name ?= "")] = lines;
            }
            return [email.trim(), name.trim()];
        }
    }
    
    // nope, try RCPT..
    catch any {
        (> .MAIL_FROM(c, $smtp.get_email_address('postmaster)) <);
        [code, lines] = (> .RCPT_TO(c, address[1]) <);
        .QUIT(c);
        .close_session(c);
        if ((m = regexp(lines[1], "<([^>]+)>")))
            email = m[1];
        else
            email = lines[1];
        return [email.trim()];
    } with {
        .QUIT(c);
        .close_session(c);
        rethrow(error());
    }
};

protected method .QUIT() {
    arg c;
    var lines, code, line, i;
    
    .set_timeout(c, 120);
    c.write("QUIT");
    
    // get it, but ignore it
    lines = (> .get_response(c) <);
};

public method .mail_aliases() {
    return mail_aliases;
};

public method .lookup_alias() {
    arg name;
    
    return (> mail_aliases[name] <);
};

public method .remove_aliases() {
    var x;
    
    (> .perms(caller(), $mail_list) <);
    for x in (mail_aliases) {
        if ((x[2]) == sender())
            mail_aliases = dict_del(mail_aliases, x[1]);
    }
};

public method .add_mail_alias() {
    arg alias, recip;
    var name;
    
    if (type(alias) != 'string)
        throw(~type, "First argument must be a string name for the alias");
    if ((type(recip) != 'objnum) || (!(recip.is($mail_list))))
        throw(~type, "Second argument is not a valid $mail_list");
    name = alias;
    name = strsed(alias, "[^a-z0-9\.-]+", "", "g");
    if (name != alias)
        throw(~type, "Alias may only be alphanumeric characters, or a period or dash");
    mail_aliases = dict_add(mail_aliases, alias, recip);
};

public method .del_mail_alias() {
    arg alias;
    
    return dict_del(mail_aliases, alias);
};

public method .parse_alias() {
    arg alias;
    var tmp, obj, o;
    
    tmp = explode(alias, ":");
    if (listlen(tmp) != 2)
        throw(~type, ("Invalid alias pair '" + alias) + "', should be ALIAS:OBJ");
    [alias, obj] = tmp;
    tmp = strsed(alias, "[^a-z0-9\.-]+", "", "g");
    if (tmp != alias)
        throw(~type, "Alias must be composed of a-z, 0-9, a period or a dash");
    if (obj && ((obj[1]) == "$")) {
        if (!(o = (| $object_lib.to_dbref(obj) |)))
            throw(~type, "Invalid object: " + obj);
    } else if (!(o = (| $mail_lib.match_mail_recipient(obj) |))) {
        throw(~type, "Invalid mail recipient: " + obj);
    }
    if (!(o.is($mail_list)))
        throw(~type, ("Object " + o) + " is not a valid mail recipient.");
    return [alias, o];
};

protected method .set_aliases_setting() {
    arg name, definer, value;
    
    switch (value[1]) {
        case 'set:
            mail_aliases = value[2];
        case 'add:
            mail_aliases = dict_add(mail_aliases, @value[2]);
        case 'del:
            mail_aliases = dict_del(mail_aliases, value[2]);
        default:
            throw(~type, "Unknown action: " + (value[1]));
    }
};

protected method .get_aliases_setting() {
    arg @args;
    
    return mail_aliases;
};

public method .fmt_aliases_setting() {
    arg data;
    var a;
    
    return map a in (data) to (((a[1]) + ":") + ((a[2]).mail_name())).join(", ");
};

protected method .set_hosts_setting() {
    arg name, definer, value;
    
    switch (value[1]) {
        case 'set:
            hosts = value[2];
        case 'add:
            hosts = setadd(hosts, value[2]);
        case 'del:
            hosts = setremove(hosts, value[2]);
        default:
            throw(~type, "Unknown action: " + (value[1]));
    }
};

public method .get_hosts_setting() {
    arg @args;
    
    return hosts || [$dns.hostname("")];
};

public method .format_email_address() {
    arg recip, @notfull;
    var host, mailname;
    
    host = (| (.get_hosts_setting())[1] |);
    mailname = recip.mail_name();
    if ((| .lookup_alias((recip.name()).replace(" ", "-")) |)) {
        mailname = strsed(mailname, "^[*~]", "");
    } else {
        mailname = strsub(recip.mail_name(), "*", "list-");
        if (.get_setting("cold-relay-recip", $smtp))
            mailname = strsub(mailname, "~", "user-");
        else
            mailname = strsub(mailname, "~", "");
    }
    if (host) {
        if (notfull)
            return (mailname + "@") + host;
        return ((((((recip.name()).capitalize()) + " <") + mailname) + "@") + host) + ">";
    } else {
        if (notfull)
            return mailname;
        return ((((recip.name()).capitalize()) + " <") + mailname) + ">";
    }
};

public method .allowed() {
    arg cmd;
    
    return 1;
};

public method .parse_recipient() {
    arg user;
    var x, host;
    
    if (mail_aliases.contains(user))
        return mail_aliases[user];
    if (((user[1]) == "<") && ((user[user.length()]) == ">"))
        user = user.subrange(2, (user.length()) - 2);
    if ("@" in user) {
        [user, host] = explode(user, "@");
        if (!(host in ($smtp.get_hosts_setting())))
            throw(~perm, "Unwilling to accept or relay mail for: " + host, 571);
    }
    user = user.trim();
    user = strsed(user, "^list-", "*");
    user = strsed(user, "^user-", "~");
    return (| $smtp.lookup_alias(user) |) || (> $mail_lib.match_mail_recipient(user) <);
};

public method .get_system_email() {
    arg type;
    var email, r, host;
    
    if (type(type) != 'string)
        type = tostr(type);
    
    // format aliases here, so .format_email_address() doesn't confuse them
    if ((r = (| .lookup_alias(type) |))) {
        if ((host = (| (.get_hosts_setting())[1] |)))
            return (type + "@") + host;
        return type;
    }
    if ((r = (| .parse_recipient(type) |)))
        return .format_email_address(r, 'notfull);
    r = $mail_admin;
    if ((host = (| (.get_hosts_setting())[1] |)))
        return "admin@" + host;
    return "admin";
};

public method .get_email_address() {
    arg type;
    var email, r, host;
    
    if (type(type) == 'objnum)
        (| (type = type.name()) |);
    if (type(type) != 'string)
        type = tostr(type);
    return .format_email_address((| .parse_recipient(type) |) || $mail_admin);
};

public method .fmt_maildrop_setting() {
    arg data;
    
    return (| (($dns.hostname(data)) + "/") + data |) || data;
};

public method .parse_alias_setting() {
    arg value, action, @args;
    var a;
    
    if (action == 'del) {
        value = explode(value, ":")[1];
        a = strsed(value, "[^a-z0-9\.-]+", "", "g");
        if (a != value)
            throw(~type, "Alias must be composed of a-z, 0-9, a period or a dash");
        if (!dict_contains(mail_aliases, value))
            throw(~failed, ("The alias '" + value) + "' is not set, and thus cannot be removed");
        return value;
    } else {
        return (> .parse_alias(value) <);
    }
};


new object $daemon: $network;

var $root manager = $daemon;
var $root created_on = 809051864;
var $root inited = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $daemon connection = 0;
var $daemon next_connection = 0;
var $daemon current_port = 0;
var $root managed = [$daemon];
var $root defined_settings = #[["connection", #[['get, ['get_connection]], ['set, ['set_connection]], ['parse, ['parse_connection_setting]]]], ["listen", #[['get, ['get_listen]], ['set, ['set_listen]], ['parse, ['parse_listen]], ['format, ['format_listen]]]]];
var $daemon listen = 0;
var $daemon current_ports = 0;

public method .current_ports() {
    return current_ports;
};

protected method .set_connection() {
    arg name, definer, value, @args;
    
    connection = value;
};

public method .stop_listening() {
    var p;
    
    (> .perms(sender()) <);
    if (valid(connection))
        (> connection.daemon_shutdown() <);
    (| clear_var('next_connection) |);
    for p in (current_ports || [])
        (| unbind_port(p[1]) |);
    (| clear_var('current_ports) |);
};

public method .start_listening() {
    arg @ports;
    var p, last, l;
    
    (> .perms(sender()) <);
    (| .stop_listening() |);
    ports ?= listen;
    current_ports = [];
    for p in (ports) {
        catch any {
            last = p;
            bind_port(@p);
            current_ports += [p];
            $sys.slog((("** Starting " + this()) + " on ") + (.format_listen([p], 1)));
        } with {
            p = (p.reverse()).join(":");
            $sys.slog((("** Unable to bind " + this()) + " to ") + p);
            if (error() != ~bind)
                $sys.log_traceback(traceback(), (("LISTEN: " + this()) + " ") + p);
        }
    }
    if (!current_ports)
        throw(~daemon, ("** " + this()) + " NOT LISTENING **");
    next_connection = connection.new_connection();
};

public method .startup(): forked {
    arg @args;
    var match, port, rx, str, o, ports, msg;
    
    (> .perms(caller(), 'system) <);
    rx = tostr(.objname());
    rx = ("-(p)" + substr(rx, 1, ("_" in rx) - 1)) + "=(.*)";
    if (find str in (args) where ((match = regexp(str, rx)))) {
        [o, ports] = match;
        ports = .parse_port(ports);
        if (strcmp(o, "p") == 0)
            ports = listen + [ports];
    } else {
        ports = listen;
    }
    (> .start_listening(@ports) <);
};

public method .current_port() {
    return (current_ports[1])[1];
};

public method .shutdown() {
    arg @args;
    
    (> .perms(caller(), $sys) <);
    (> .stop_listening() <);
};

driver method .connect() {
    arg remote, local, socket;
    var conn;
    
    if ($sys.host_denied(remote)) {
        close_connection();
        return;
    }
    if (!valid(next_connection))
        next_connection = connection.new_connection();
    conn = next_connection;
    reassign_connection(conn);
    next_connection = connection.new_connection();
    conn.start(remote, local, socket, (current_ports[1])[1]);
};

protected method .get_connection() {
    arg @args;
    
    return connection;
};

public method .parse_connection_setting() {
    arg value, @args;
    var obj;
    
    obj = (> $object_lib.to_dbref(value) <);
    if (!(obj.is($connection)))
        throw(~perm, "Connection object must be descended from $connection.");
    return obj;
};

root method .core_daemon() {
    .stop_listening();
    if (this() != definer())
        .set_setting("listen", $daemon, tostr(((.get_setting("listen", $daemon))[1])[1]));
};

public method .get_listen() {
    arg @args;
    
    return listen || [];
};

protected method .set_listen() {
    arg name, definer, value;
    
    listen = value;
};

public method .parse_port() {
    arg str;
    var m, host, port, ip;
    
    if ((m = str.regexp("^([^:]+):(.*)$"))) {
        [host, port] = m;
        host = host.trim();
        port = port.trim();
        if (host) {
            ip = $dns.ip(host);
            if (ip == "-1")
                throw(~parse, "Unable to resolv hostname: " + host);
            host = ip;
        }
    } else {
        port = str;
        host = "";
    }
    if (!(port.is_numeric()))
        throw(~parse, "Invalid port: " + port);
    port = toint(port);
    if ((port <= 0) || (port > 65535))
        throw(~parse, ("Invalid port " + port) + " (out of range, must be 0 .. 65535)");
    if (host)
        return [port, host];
    else
        return [port];
};

public method .parse_listen() {
    arg value, @args;
    var out, p, m, port, ip;
    
    if (!value)
        throw(~parse, "Invalid listen setting, must be a list of ports or host:ports.");
    out = map p in (value.explode_english_list()) to ((> .parse_port(p) <));
    if (!out)
        throw(~parse, "Invalid listen setting, must be a list of ports or host:ports.");
    return out;
};

public method .format_listen() {
    arg value, @noresolv;
    var p, out;
    
    out = [];
    for p in (value) {
        if (listlen(p) > 1)
            out += [((noresolv ? (p[2]) : ($dns.hostname(p[2]))) + ":") + (p[1])];
        else
            out += [p[1]];
    }
    return out.join(", ");
};


new object $login_daemon: $daemon;

var $root manager = $login_daemon;
var $root created_on = 809051992;
var $root inited = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $daemon connection = $login_connection;
var $daemon current_port = 1138;
var $root managed = [$login_daemon];
var $root defined_settings = #[["creation-disabled-msg", #[]], ["creation-allowed", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["guests-allowed", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["guests-disabled-msg", #[]]];
var $root settings = #[["creation-disabled-msg", "Sorry, character creation is disabled."], ["creation-allowed", 1], ["guests-allowed", 1], ["guests-disabled-msg", "Sorry, guests are disabled."]];
var $daemon listen = [[1138]];

root method .core_login_daemon() {
    .set_setting("creation-allowed", $login_daemon, "yes");
};


new object $smtp_daemon: $daemon;

var $root manager = $smtp_daemon;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 849170427;
var $root inited = 1;
var $daemon connection = $smtp_connection;
var $daemon current_port = 1125;
var $root managed = [$smtp_daemon];
var $smtp_daemon msg_id = 411;
var $daemon listen = [[1125]];

public method .get_msg_id() {
    msg_id++;
    return msg_id;
};


new object $http_daemon: $daemon;

var $root manager = $http_daemon;
var $root managed = [$http_daemon];
var $root flags = ['methods, 'code, 'variables, 'core];
var $root created_on = 809075222;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $daemon connection = $http_connection;
var $daemon current_port = 1180;
var $root quota = 1;
var $root quota_exempt = 1;
var $daemon listen = [[1180]];
var $http_daemon site_url = "";

public method .site_url() {
    return site_url;
};

protected method .figure_site_url() {
    var host, curr, h, port;
    
    curr = .current_ports();
    if ((h = find h in (curr) where (listlen(h) == 2))) {
        [port, host] = curr[h];
        host = $dns.hostname(host);
    } else {
        host = $dns.hostname("");
        port = (curr[1])[1];
    }
    if (port != 80)
        site_url = (host + ":") + port;
    else
        site_url = host;
    return site_url;
};

public method .stop_listening() {
    site_url = "";
    (> pass() <);
};

public method .start_listening() {
    arg @args;
    
    (> pass(@args) <);
    .figure_site_url();
};


new object $pop3_daemon: $daemon;

var $root manager = $pop3_daemon;
var $daemon connection = $pop3_connection;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 872047000;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $daemon listen = [[1210]];
var $root managed = [$pop3_daemon];


new object $dns: $network;

var $root manager = $dns;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 867779129;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $dns dnshost = ["127.0.0.1", 1153];
var $dns connection = 0;
var $root trusted_by = [$outbound_connection];
var $dns starting = 0;
var $dns async = 0;
var $dns started = 0;
var $dns valid_host_regexp = "^([-a-z0-9]+\.)+(gov|edu|com|org|int|mil|net|nato|arpa|[a-z][a-z])$";
var $dns valid_ip_regexp = "([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)";
var $root managed = [$dns];

public method .ip() {
    arg hostname;
    var c, line, result;
    
    if (!hostname)
        return pass();
    if ((hostname != "localhost") && (!match_regexp(hostname, valid_host_regexp)))
        throw(~address, ("Invalid Internet Address: \"" + hostname) + "\"");
    if (!async)
        return pass(hostname);
    if (!valid(connection)) {
        if (!(.restart()))
            return pass(hostname);
    }
    connection = connection.write((task_id() + ":R:") + hostname);
    result = $scheduler.suspend(this());
    if ((type(result) != 'list) || (listlen(result) != 2))
        return "";
    switch (result[1]) {
        case "N":
            throw(~address, result[2]);
        case "F":
            throw(~failed, result[2]);
        case "G":
            return result[2];
        default:
            $sys.log("DNS ERROR: Invalid result: " + (result.join(":")));
    }
};

public method .hostname() {
    arg ip;
    var c, line, result;
    
    if (!ip)
        return pass();
    if (!match_regexp(ip, valid_ip_regexp))
        throw(~invip, "Invalid IP Address: " + ip);
    if (!async)
        return pass(ip);
    if (!valid(connection)) {
        if (!(.restart()))
            return pass(ip);
    }
    connection = connection.write((task_id() + ":N:") + ip);
    result = $scheduler.suspend(this());
    if ((type(result) != 'list) || (listlen(result) != 2))
        return "";
    switch (result[1]) {
        case "N":
            throw(~address, result[2]);
        case "F":
            throw(~failed, result[2]);
        case "G":
            return result[2];
        default:
            $sys.log("DNS ERROR: Invalid result: " + (result.join(":")));
    }
};

protected method .startup_dns() {
    var id, tmp, x;
    
    if (starting)
        return;
    started = 0;
    starting = 1;
    if (connection)
        (| connection.close() |);
    id = tosym("dns_connection");
    while ((| lookup(id) |))
        id = tosym("dns_connection_" + ++x);
    connection = $outbound_connection.new_with(id);
    if ((| connection.open_connection(@dnshost) |)) {
        starting = 0;
        started = 1;
        return;
    }
    
    // try to exec() it, then startup again
    (| $sys.startup_dnsserv() |);
    $scheduler.sleep(1);
    catch any {
        connection.open_connection(@dnshost);
        starting = 0;
    } with {
        (| connection.close() |);
        connection = 0;
        starting = 0;
        if (error() == ~refused)
            throw(~refused, "Unable to open connection to " + (dnshost.join(":")));
        else
            rethrow(error());
    }
    started = 1;
};

public method .connection_starting() {
    arg host, port;
    
};

public method .connection_going_away() {
    arg host, port;
    
    if (sender() != connection)
        return;
    started = 0;
    if (!starting)
        .restart();
};

public method .parse_line() {
    arg line;
    var m, task, code, info;
    
    (> .perms(caller(), $connection) <);
    if ((m = regexp(line, "^([0-9]+):([a-z]):(.*)$"))) {
        [task, code, info] = m;
        task = toint(task);
        catch any {
            $scheduler.resume(task, [code, info]);
        } with {
            $sys.log("DNS ERROR: ");
            $sys.log($parse_lib.traceback(traceback()));
        }
    } else {
        $sys.log("DNS ERROR: Invalid Result from server: " + line);
    }
};

public method .shutdown() {
    arg @args;
    var c;
    
    (sender() != this()) && (> .perms(caller(), 'system) <);
    c = connection;
    connection = 0;
    (| c.close() |);
    started = 0;
};

public method .startup(): forked {
    arg @args;
    
    (> .perms(sender(), 'system) <);
    .shutdown();
    if (!async)
        return;
    catch any {
        (> .startup_dns() <);
        $sys.log("** Starting async DNS lookups at " + (dnshost.join(":")));
    } with {
        $sys.log("** Unable to startup async DNS lookups because:");
        $sys.log("** => " + ((traceback()[1])[2]));
    }
};

public method .restart() {
    if (starting || (!started))
        return 0;
    connection = 0;
    catch any {
        (> .startup_dns() <);
        $sys.log("** Restarting async DNS lookups at " + (dnshost.join(":")));
    } with {
        $sys.log("** Unable to restart async DNS lookups because:");
        $sys.log("** => " + ((traceback()[1])[2]));
    }
    return valid(connection);
};

public method .valid_hostname() {
    arg host;
    
    return match_regexp(host, valid_host_regexp) ? 1 : 0;
};

public method .valid_ip() {
    arg ip;
    
    return match_regexp(ip, valid_ip_regexp) ? 1 : 0;
};

public method .valid_host_regexp() {
    return valid_host_regexp;
};

public method .valid_ip_regexp() {
    return valid_ip_regexp;
};

public method .core_dns() {
    async = 0;
    connection = 0;
    starting = 0;
    started = 0;
};


new object $connection_interface: $network, $command_cache;

var $root manager = $connection_interface;
var $root created_on = 809051864;
var $root inited = 1;
var $root quota_exempt = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $connection_interface connection = 0;
var $root managed = [$connection_interface];

public method .parse_line() {
    arg line;
    var cmd, c, match, parsed, i, m, a, u;
    
    catch any {
        line = line.trim();
        if (!line) {
            return .null_cmd(line);
        } else {
            cmd = line.explode();
            cmd = [line, cmd[1], ((cmd.subrange(2)).join()) || ""];
            c = (| .match_in_local_cache(@cmd) |);
            if (c && ((c[1]) == 'local)) {
                // screw duplicates, take the first match
                match = (c[2])[1];
                m = match[2];
                i = match[5];
                parsed = i.keys();
                for a in [1 .. m.length()] {
                    if (a in parsed)
                        m = m.replace(a + 2, (> $command_lib.convert_arg((i[a])[1], m[a + 2], $no_one, ((i[a])[2]) ? (((i[a])[2])[1]) : $no_one, $no_one) <));
                }
                return (> .(match[4])(@m) <);
            }
            return (> .invalid_cmd(line) <);
        }
    } with {
        if (((traceback()[1])[3]) != 'no_traceback) {
            (this['connection]).write($parse_lib.traceback(traceback()));
            return 'disconnect;
        }
    }
};

public method .connection_going_away() {
    arg @args;
    
    (> .close() <);
};

public method .linelen() {
    arg @args;
    
    return 79;
};

public method .send() {
    arg @args;
    
    return (> .write(@args) <);
};

public method .write() {
    arg what;
    
    return connection.write(what);
};

public method .null_cmd() {
    arg @args;
    
    return 'disconnect;
};

public method .invalid_cmd() {
    arg @args;
    
    return 'disconnect;
};

public method .connection() {
    return connection;
};

public method .tell() {
    arg @args;
    
    (> .write(@args) <);
};

public method .new() {
    arg c;
    var i;
    
    (> .perms(caller(), $connection) <);
    i = .spawn();
    i.set_connection(c);
    return i;
};

public method .new_connection() {
    arg this, host, port;
    
};

public method .set_connection() {
    arg c;
    
    if (caller() != definer())
        (> .perms(sender()) <);
    connection = c;
};

public method .daemon_shutdown() {
    var i;
    
    (> .perms(caller(), $connection) <);
    for i in (.children())
        (> i.close() <);
};

public method .close() {
    (> .perms(sender()) <);
    (> $sys.destroy_sender() <);
};

public method .connection_starting() {
    arg addr, port;
    
};

public method .log_traceback() {
    arg @args;
    
    return $sys.log_traceback(@args);
};


new object $login_interface: $connection_interface;

var $root manager = $login_interface;
var $root created_on = 809051864;
var $root inited = 1;
var $root quota_exempt = 1;
var $root flags = ['methods, 'code, 'core, 'variables, 'command_cache];
var $has_commands local = #[["@who", [["@who", "", "@who", 'who_cmd, #[]]]], ["m?otd", [["m?otd", "", "m?otd", 'motd_cmd, #[]]]], ["h?elp", [["h?elp", "", "h?elp", 'help_cmd, #[]]]], ["guest|connect-guest", [["guest|connect-guest", "*", "guest|connect-guest <any>", 'connect_guest_cmd, #[[1, ['any, []]]]]]], ["c?onnect", [["c?onnect", "*", "c?onnect <any>", 'connect_cmd, #[[1, ['any, []]]]]]], ["@quit|QUIT", [["@quit|QUIT", "", "@quit|QUIT", 'quit_cmd, #[]]]], ["cr?eate", [["cr?eate", "*", "cr?eate <any>", 'create_cmd, #[[1, ['any, []]]]]]]];
var $root managed = [$login_interface];
var $root trusted_by = [$smtp];
var $command_cache shortcuts = 0;
var $command_cache modules = [];
var $command_cache commands = 0;

protected method .connect_cmd() {
    arg cmdstr, cmd, args;
    var syn, stderr, passwd, name, user;
    
    syn = cmd + " <name> <password>";
    stderr = "Either that user does not exist or has a different password.";
    args = args.explode();
    if ((args.length()) < 2)
        (> .tell_error("Last word is taken as the password.", syn) <);
    passwd = args[args.length()];
    name = (args.subrange(1, (args.length()) - 1)).join();
    user = (| $user_db.search(name) |) || (> .tell_error(syn, stderr) <);
    if (!($security_lib.check_password(user, passwd, (.connection()).address())))
        (> .tell_error(syn, stderr) <);
    if ($sys.user_denied(user)) {
        .print(("Access to user " + (user.namef('ref))) + " is currently denied.");
        .print(("Contact " + ($smtp.get_email_address('admin))) + " for more information.");
    } else {
        (.connection()).change_interface(user);
    }
};

protected method .create_cmd() {
    arg cmdstr, cmd, args;
    var syn, msg, user, semail, len, name, pwd, email, result;
    
    if (!($login_daemon.get_setting("creation-allowed", $login_daemon)))
        return (> .tell_error("", $login_daemon.get_setting("creation-disabled-msg", $login_daemon)) <);
    syn = cmd + " <name> <password> <email@host>";
    semail = $smtp.get_email_address('login);
    args = args.explode_quoted();
    if ((args.length()) < 3)
        (> .tell_error(syn) <);
    if ((args.length()) > 3) {
        len = listlen(args);
        args = [sublist(args, 1, len - 2).join(), args[len - 1], args[len]];
    }
    [name, pwd, email] = args;
    if ((| $user_db.search(name) |))
        (> .tell_error(syn, ("The name '" + name) + "' is already taken.") <);
    if ($sys.validate_email_addresses()) {
        catch any {
            .print("Verifying Email Address..");
            msg = $smtp.verify_email_address(email);
            .print("SMTP Response: " + (msg.join(" ")));
        } with {
            .print("Aborting: " + ((traceback()[1])[2]));
            return;
        }
    }
    catch any {
        user = $sys.create_user(name, pwd, email);
    } with {
        if (user)
            (| user.destroy() |);
        .log_traceback(traceback(), "LOGIN: " + cmdstr);
        msg = ["There was a problem creating you:"];
    
        //// Too verbose.
        // msg += $parse_lib.traceback(traceback());
        // msg += ["If there is a problem contact: " + semail];
        (> .tell_error(syn, (msg + ["  " + ((traceback()[1])[2])]).prefix("!  ")) <);
        return;
    }
    (.connection()).change_interface(user);
};

protected method .quit_cmd() {
    arg cmdstr, cmd;
    
    .print("Goodbye.");
    return 'disconnect;
};

protected method .connect_guest_cmd() {
    arg cmdstr, cmd, args;
    var syn, msg, c, email, name, result, semail, user;
    
    if (!($login_daemon.get_setting("guests-allowed", $login_daemon)))
        return (> .tell_error("", $login_daemon.get_setting("guests-disabled-msg", $login_daemon)) <);
    syn = cmd + " <your name> <your email>";
    semail = $smtp.get_email_address('login);
    args = args.explode();
    c = .connection();
    if ((args.length()) < 2)
        (> .tell_error(syn) <);
    name = (args.subrange(1, (args.length()) - 1)).join();
    email = args[args.length()];
    if ($sys.validate_email_addresses()) {
        catch any {
            .print("Verifying Email Address..");
            msg = $smtp.verify_email_address(email);
            .print("SMTP Response: " + (msg.join(" ")));
        } with {
            .print("Aborting: " + ((traceback()[1])[2]));
            return;
        }
    }
    catch any
        user = (> $sys.create_user(name, 0, email, 'anonymous_user_class) <);
    with
        (> .tell_error(syn, (traceback()[1])[2], "If there is a problem contact: " + semail) <);
    c.change_interface(user);
};

protected method .who_cmd() {
    arg cmdstr, cmd;
    
    .print($code_lib.generate_listing($user_db.connected()));
};

protected method .help_cmd() {
    arg cmdstr, cmd;
    
    .print($motd.connect_help());
    if (!($login_daemon.get_setting("creation-allowed", $login_daemon)))
        .print(["", "NOTE: User creation is disabled, connect as a guest first."]);
};

protected method .null_cmd() {
    arg @args;
    
    return (> .invalid_cmd(@args) <);
};

protected method .invalid_cmd() {
    arg @args;
    var line;
    
    line = (((($login_interface.command_cache()).values()).slice(1)).slice(1)).compress();
    if (!($login_daemon.get_setting("creation-allowed", $login_daemon)))
        line = line.del("cr?eate");
    .print("Try: " + (line.to_english("", " or ")));
};

protected method .print() {
    arg what;
    
    (.connection()).write(what);
};

protected method .motd() {
    var out;
    
    // out = $motd.build('default) + ["", " ** Use 'H?elp' for a list of commands **".center(79), ""];
    out = $motd.build(@$motd.get_setting("login-sequence", $motd));
    return out;
};

protected method .motd_cmd() {
    arg cmdstr, cmd;
    
    .print(.motd());
};

protected method .tell_error() {
    arg syntax, @problem;
    var problem, line, sprefix, prefix, length;
    
    length = 79;
    if (syntax)
        .print(("=> Syntax: `" + syntax) + "`");
    if (problem) {
        for line in (problem) {
            if (type(line) == 'string)
                line = line.wrap_lines(length, "!  ", 1);
            .print(line);
        }
    }
    throw(~stop, "!  ** use h?elp for a list of commands and their usages **");
};

public method .connection_starting() {
    arg host, port;
    
    (> .perms(caller(), $connection) <);
    .cache_client_init();
    .print(.motd());
};

public method .parse_line() {
    arg line;
    var cmd, c, match, parsed, i, m, a, u;
    
    catch any {
        while (line && ((line[1]) == " "))
            line = line.subrange(2);
        if (!line) {
            return .null_cmd(line);
        } else {
            cmd = line.explode();
            cmd = [line, cmd[1], ((cmd.subrange(2)).join()) || ""];
            c = (| $login_interface.match_command(@cmd) |);
            if (c && ((c[1]) == 'command)) {
                // screw duplicates, take the first match
                match = (c[2])[1];
                m = match[2];
                i = match[6];
                parsed = i.keys();
                for a in [1 .. m.length()] {
                    if (a in parsed)
                        m = m.replace(a + 2, (> $command_parser.convert_arg(cmd[2], (i[a])[1], m[a + 2], $no_one, ((i[a])[2]) ? (((i[a])[2])[1]) : $no_one, $no_one) <));
                }
                return (> .(match[5])(@m) <);
            }
            return (> .invalid_cmd(line) <);
        }
    } with {
        if (error() == ~stop) {
            if ((traceback()[1])[2])
                .print((traceback()[1])[2]);
        } else {
            .print($parse_lib.traceback(traceback()));
            return 'disconnect;
        }
    }
};


new object $http_interface: $connection_interface;

var $root manager = $http_interface;
var $http_interface keep_alive = 0;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863766118;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $root inited = 1;
var $http_interface cache = [];
var $http_interface method = "GET";
var $http_interface http = "HTTP/1.0";
var $http_interface bytes = 205;
var $http_interface ctype = 0;
var $http_interface info = #[['generate, 'change], ['script_name, "/aredit/change"], ['path_info, "/"], ['directory_object, $directories], ['lock_object, 0]];
var $http_interface sent = 0;
var $http_interface args = #[];
var $root quota_exempt = 1;
var $command_cache commands = 0;
var $root managed = [$http_interface];
var $http_interface status = 404;
var $http_interface full = 0;
var $http_interface header = 0;
var $command_cache shortcuts = 0;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];

private method ._respond() {
    arg input, user;
    var output, t;
    
    switch (type(input)) {
        case 'list:
            output = `[];
            for t in (input)
                output += ._respond(t, user);
        case 'string:
            output = str_to_buf(input) + `[10];
        case 'buffer:
            output = input;
        case 'frob:
            output = $parse_lib.filter_ctext(input, #[['formatter, $html_format], ["viewer", user]]);
        default:
            output = str_to_buf((("Error, unable to send output type: " + type(input)) + " -- ") + input);
    }
    return output;
};

protected method .close_interface() {
    arg @args;
    var c;
    
    if ((!args) && keep_alive) {
        .reset_variables();
        return;
    }
    (.connection()).close();
};

protected method .send_header() {
    arg @lines;
    var code_str, content_len;
    
    if (!full)
        return;
    if (!(| (code_str = $http_lib.get_code(status)) |))
        code_str = "Unknown Code";
    if (bytes)
        content_len = ["Content-length: " + bytes];
    else
        content_len = [];
    (.connection()).write([(((http + " ") + status) + " ") + code_str, "Server: ColdWeb/2.1 (Virtual Environment)", "Connection: " + (keep_alive ? "Keep-Alive" : "close"), "Content-type: " + ctype, @content_len, @lines, ""]);
};

public method .respond() {
    arg body, @rest;
    var host, out, user;
    
    if (!(sender().is($page)))
        (> .perms(sender(), 'writer) <);
    if (!(user = (| info['run_as] |)))
        user = $no_one;
    if (status >= 400)
        keep_alive = 0;
    out = ._respond(body, user);
    bytes = buflen(out);
    .send_header(@rest);
    (.connection()).write(out);
    host = (.connection()).address();
    .log_request(host);
    .close_interface();
    sent = 1;
};

protected method .http_method_POST() {
    var len, body, part;
    
    len = (| header["Content-Length"] |);
    if ((len == ~keynf) || (!len))
        (> .respond(.response(400, "No Content-Length.")) <);
    body = (.connection()).handle_POST_input(toint(len[1]));
    
    // handle this differently in normal situations
    for part in (body)
        args = dict_union(args, $http_lib.explode_http_encoding(part));
    .http_method_GET();
};

public method .connection_going_away() {
    arg @args;
    
    (> .close() <);
};

public method .parse_line() {
    arg line;
    var match, URI;
    
    if (!method) {
        if (!line)
            return;
        line = explode(line);
        if (listlen(line) != 3) {
            (.connection()).write(.response(400, "HTTP/0.9 not supported."));
            (.connection()).close();
            return;
        }
        if ((match = regexp(line[1], "^(GET|HEAD|POST)$"))) {
            info = #[['URI, line[2]]];
            method = match[1];
        } else {
            info = #[['URI, line[2]]];
            .respond(.response(405, ("Method: \"" + (line[1])) + "\"."));
            (.connection()).close();
            return;
        }
        http = line[3];
    } else if (line) {
        if ((match = regexp(line, "^([^:]+): *(.+)$"))) {
            if (((match[1]) == "Connection") && ((match[2]) == "Keep-Alive"))
                keep_alive = 1;
            else if ((match[1]) == "Authorization")
                .process_auth_info(match[2]);
            else
                header = header.add_elem(@match);
        }
    } else {
        // parse the URI
        match = $http_lib.explode_url(info['URI]);
        info = dict_union(info, match[1]);
        args = match[2];
        catch any {
            (> .(tosym("http_method_" + method))() <);
        } with {
            if (error() != ~stop)
                .respond($parse_lib.html_traceback(traceback(), (status = 500)));
        }
    }
};

protected method .log_request() {
    arg host;
    var line;
    
    line = (((((((((host + " - - \"") + method) + " ") + (info['URI])) + " ") + http) + "\" ") + tostr(status)) + " ") + tostr(bytes);
    if ((| header["User-Agent"] |))
        line = (line + ";; ") + ((header["User-Agent"]).join());
    $sys.log(line);
};

protected method .reset_variables() {
    method = "";
    http = "HTTP/1.0";
    status = 200;
    bytes = 0;
    ctype = $http_lib.html_version();
    full = 1;
    header = #[['interface, sender()]];
    info = #[];
    args = #[];
};

public method .set_status() {
    arg s;
    
    (> .perms(caller(), $http_connection) <);
    status = s;
};

public method .http_method_GET() {
    arg @nopage;
    var page, r, desc, processed_args, final_args, item, lock;
    
    status = 200;
    page = $directories.find_page(info['path], this());
    if (page == 'pagenf) {
        .respond(.response(404, "Page not found"));
        return;
    } else if ((type(page) == 'list) && ((page[1]) == 'redirect)) {
        r = .expand_url(page[2]);
        .respond(.response(302, "Relocated at: " + r), "Location: " + r);
        return;
    }
    
    // get a lock, if necessary
    if (info['lock_object]) {
        if (!(.handle_lock_object()))
            return;
    }
    
    // process args
    catch any {
        desc = (| $interface_registry.describe(page, info['generate]) |) || ((| page.describe_method(info['generate]) |) || #[]);
        if ((| desc['args] |))
            processed_args = $adapter.process_args(args, desc['args]);
        else
            processed_args = args;
    } with {
        switch (error()) {
            case ~objnf:
                .respond(.response(500, "Object not found"));
                return;
            case ~missingarg:
                .respond(.response(500, "Missing Argument"));
                return;
            default:
                status = 500;
                .respond($parse_lib.html_traceback(traceback(), status));
                $sys.log($parse_lib.traceback(traceback()));
                return;
        }
    }
    
    // process Authentication, always auth user unless otherwise specified
    if (!(.handle_authorization(desc, page)))
        return;
    
    // generate the page
    catch any {
        if (page.is($page))
            final_args = [header, info, processed_args];
        else if ((| desc['arg_order] |))
            final_args = map item in (desc['arg_order]) to (processed_args[item]);
        else
            final_args = [];
        if ((| info['run_as] |))
            r = (info['run_as]).as_this_run(page, info['generate], final_args);
        else
            r = page.(info['generate])(@final_args);
        if (type(r) == 'list) {
            switch (r[1]) {
                case 'redirect:
                    page = .expand_url(r[2]);
                    .respond(.response(302, "Relocated at: " + page), "Location:  " + page);
                    return;
                case 'auth:
                    // do auth;
                    .respond(.response(401, "Authorization Required"), ((("WWW-Authenticate: " + ((r[2])[1])) + " realm=\"") + ((r[2])[2])) + "\" domain=\"/\"");
                    return;
                default:
                    if (type(r[1]) != 'list)
                        r = [r];
            }
        } else {
            r = [r];
        }
        if (r != [0])
            .respond(@r);
    } with {
        switch (error()) {
            case ~methodnf:
                .respond(.response(500, "Method not found: " + (info['generate])));
            default:
                status = 500;
                .respond($parse_lib.html_traceback(traceback(), status));
                $sys.log($parse_lib.traceback(traceback()));
        }
    }
    if (!sent)
        .respond(.response(500, "It should have generated a page by now"));
};

public method .header() {
    arg field;
    
    return (> header[field] <);
};

public method .get_info() {
    arg key;
    
    return (> info[key] <);
};

public method .expand_url() {
    arg partial_url;
    var base;
    
    base = "http://" + ($http_daemon.site_url());
    switch (partial_url[1]) {
        case "?":
            return ((base + (info['script_name])) + (info['path_info])) + partial_url;
        case "/":
            return base + partial_url;
        default:
            return partial_url;
    }
};

public method .set_info() {
    arg key, data;
    
    // Security: Only $directories and $http_interface can set info
    // if you must extend, set the defining object in this list
    (> .perms(caller(), $directories, $http_interface, $security_lib) <);
    info = info.add(key, data);
};

public method .response() {
    arg code, message;
    var name, x, page, title;
    
    status = code;
    if (!(name = (| $http_lib.get_code(code) |)))
        return .response(500, "We had a booboo!  Invalid code: " + code);
    if (type(message) == 'string)
        message = [("<p align=center>" + message) + "</p>"];
    title = (code + " ") + name;
    page = $directories.build_header(#[], #[], #[], #[['title, title]]);
    page += [("<h1 align=center>" + title) + "</h1>", "<hr size=1 noshade>"];
    page += message;
    page += $directories.build_footer(#[], #[], #[]);
    return page;
};

public method .process_auth_info() {
    arg str;
    var user, pwd;
    
    str = str.explode();
    switch (str[1]) {
        case "Basic":
            [(user ?= ""), (pwd ?= "")] = ((str[2]).decode64()).explode(":");
            .set_info('browser_auth, ['basic, [user, pwd]]);
    
            // no MD5, no Digest support, blah
        default:
            $sys.log("$security_db: Unknown authorization type '" + (str[1]));
            .set_info('browser_auth, ['unknown, str]);
    }
};

root method .init_http_interface() {
    .reset_variables();
};

public method .respond_with_file() {
    arg fstat, filename;
    var host, tzadjust, datestr, retry, havefile, c, filetb;
    
    if (!(sender().is($page)))
        (> .perms(sender(), 'writer) <);
    bytes = fstat[2];
    catch ~range {
        tzadjust = localtime()[12];
        datestr = "%a, %d %b %Y %H:%M:%S GMT";
        .send_header($time.format("Date: " + datestr, time() + tzadjust), $time.format("Last-modified: " + datestr, (fstat[4]) + tzadjust));
    } with {
        .send_header();
    }
    
    // OIF, bizarreness with cwritef skipping the first chunk of the
    // file, lets workaround it for now.
    // .connection().cwritef(filename);
    retry = 30;
    
    // lets wait up to 30 seconds or so, gah
    // later, setup a multi-file scheme where more than one is open
    // involve $cached_file...
    while (!havefile) {
        catch any {
            havefile = $web_file.fopen(filename, "-");
        } with {
            filetb = traceback();
            break;
        }
        retry--;
        if (retry < 0)
            break;
        else if (retry < 5)
            $scheduler.sleep(1);
        else
            pause();
    }
    if (havefile) {
        c = .connection();
        catch any {
            while (1) {
                pause();
                c.write_buffer((> $web_file.fread(1024) <));
            }
        }
        $web_file.fclose();
    } else {
        (.connection()).write("ERROR: unable to open file.");
        if (filetb)
            $sys.broadcast(("$web_file Error! (" + ((filetb[1])[2])) + ")");
        else
            $sys.broadcast("$web_file Bottleneck! ($web_file.close()?)");
    }
    host = (.connection()).address();
    .log_request(host);
    .close_interface();
    sent = 1;
};

public method .set_ctype() {
    arg ct;
    
    ctype = ct;
};

public method .http_method_HEAD() {
    var page, r, description, processed_args, final_args, item, lock;
    
    status = 200;
    page = $directories.find_page(info['path], this());
    if (page == 'pagenf) {
        status = 404;
        .respond([]);
        return;
    } else if ((type(page) == 'list) && ((page[1]) == 'redirect)) {
        r = .expand_url(page[2]);
        status = 302;
        .respond([], "Location: " + r);
        return;
    }
    if (info['lock_object]) {
        lock = (info['lock_object]).get_lock();
        r = (lock[1]).(lock[2])(this(), @lock[3]);
        if (r) {
            switch (type(r)) {
                case 'list:
                    if ((r[1]) == 'redirect) {
                        r = .expand_url(page[2]);
                        status = 302;
                        .respond([], "Location: " + r);
                        return;
                    } else {
                        status = 401;
                        .respond([], ((("WWW-Authenticate: " + (r[1])) + " realm=\"") + (r[2])) + "\"");
                        return;
                    }
                case 'symbol:
                    status = 403;
                    .respond([]);
                    return;
            }
        }
    }
    catch any {
        description = (| $interface_registry.describe(page, info['generate]) |) || ((| page.describe_method(info['generate]) |) || #[]);
        if ((| description['args] |))
            processed_args = $adapter.process_args(args, description['args]);
        else
            processed_args = #[];
    } with {
        status = 500;
        switch (error()) {
            case ~objnf:
                .respond([]);
                return;
            case ~missingarg:
                .respond([]);
                return;
            default:
                status = 500;
                .respond([]);
                $sys.log($parse_lib.traceback(traceback()));
                return;
        }
    }
    if ((| description['auth] |)) {
        if ((description['auth]) != 'none) {
            r = ((description['auth])[1]).((description['auth])[2])(this(), @(description['auth])[3]);
            if (r) {
                switch (type(r)) {
                    case 'list:
                        if ((r[1]) == 'redirect) {
                            r = .expand_url(page[2]);
                            status = 302.0.respond([], "Location: " + r);
                            return;
                        } else {
                            status = 401;
                            .respond([], ((("WWW-Authenticate: " + (r[1])) + " realm=\"") + (r[2])) + "\"");
                            return;
                        }
                    case 'symbol:
                        status = 403;
                        .respond([]);
                        return;
                }
            }
        }
    } else if (!(page.is($page))) {
        status = 500;
        .respond([]);
        return;
    }
    .respond([]);
};

public method .info() {
    return info;
};

private method .handle_lock_object() {
    var r, lock;
    
    lock = (info['lock_object]).get_lock();
    r = (lock[1]).(lock[2])(this(), @lock[3]);
    if (r) {
        switch (type(r)) {
            case 'list:
                if ((r[1]) == 'redirect) {
                    r = .expand_url(r[2]);
                    .respond(.response(302, "Relocated at: " + r), "Location: " + r);
                    return 0;
                } else {
                    status = 401;
                    .respond(.response(401, "Authorization Required"), ((("WWW-Authenticate: " + (r[1])) + " realm=\"") + (r[2])) + "\"");
    
                    //           .respond(["<HEAD><TITLE>Authorization Required</TITLE></HEAD>", "<BODY>", "<H1>Authorization Required</H1>", "Browser not authentication-capable or authentication failed.", "</BODY>"], "WWW-Authenticate: " + r[1] + " realm=\"" + r[2] + "\"");
                    return 0;
                }
            case 'symbol:
                .respond(.response(403, "Access forbidden"));
                return 0;
        }
    }
    return 1;
};

private method .handle_authorization() {
    arg desc, page;
    var r, auth, page;
    
    if ((| info['browser_auth] |) || (| desc['auth] |)) {
        r = 'forbidden;
        if ((auth = (| desc['auth] |)) && (auth != 'none))
            r = ((desc['auth])[1]).((desc['auth])[2])(this(), @(desc['auth])[3]);
        else
            r = $security_lib.check_userdb_with_password(this());
        if (r) {
            switch (type(r)) {
                case 'list:
                    if ((r[1]) == 'redirect) {
                        r = .expand_url(r[2]);
                        .respond(.response(302, "Relocated at: " + r), "Location: " + r);
                        return 0;
                    } else {
                        .respond(.response(401, "Authorization Required"), ((("WWW-Authenticate: " + (r[1])) + " realm=\"") + (r[2])) + "\"");
                        return 0;
                    }
                case 'symbol:
                    .respond(.response(403, "Access forbidden"));
                    return 0;
            }
        }
    } else if (!(page.is($page))) {
        .respond(.response(500, ("Authorization info missing (" + page) + " is not a $page)"));
        return 0;
    }
    return 1;
};


new object $pop3_interface: $connection_interface;

var $root manager = $pop3_interface;
var $root quota_exempt = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 871668198;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $root inited = 1;
var $pop3_interface mail_objects = [];
var $pop3_interface deleted = [];
var $pop3_interface state = 0;
var $pop3_interface maildrop = 0;
var $root managed = [$pop3_interface];
var $pop3_interface commands = #[["QUIT", 'quit_cmd], ["STAT", 'stat_cmd], ["LIST", 'list_cmd], ["RETR", 'retr_cmd], ["DELE", 'dele_cmd], ["NOOP", 'noop_cmd], ["RSET", 'rset_cmd], ["TOP", 'top_cmd], ["UIDL", 'uidl_cmd], ["USER", 'user_cmd], ["PASS", 'pass_cmd], ["APOP", 'apop_cmd]];
var $command_cache commands = 0;
var $command_cache shortcuts = 0;

public method .connection_starting() {
    arg host, port;
    
    (> .perms(caller(), $connection) <);
    state = 'authorization;
    deleted = [];
    .print("+OK Cold POP3 Server ready");
};

protected method .print() {
    arg @args;
    
    (.connection()).write(@args);
};

protected method .quit_cmd() {
    arg argstr;
    var errors, x;
    
    if (state != 'transaction) {
        .print("+OK Cold POP3 server signing off.");
    } else {
        for x in (deleted) {
            catch any
                maildrop.del_mail(mail_objects[x]);
            with
                errors++;
        }
        if (errors)
            .print("-ERR some messages could not be deleted");
        else
            .print(("+OK Cold POP3 server signing off (" + ((maildrop.mail()) ? (((maildrop.mail()).length()) + " messages left") : "maildrop empty")) + ")");
    }
    return 'disconnect;
};

protected method .stat_cmd() {
    arg argstr;
    var x, m;
    
    (> .check_state("STAT", 'transaction) <);
    .print((("+OK " + ((m = .live_messages()).length())) + " ") + (.mailbox_size()));
};

protected method .list_cmd() {
    arg argstr;
    var x, m;
    
    (> .check_state("LIST", 'transaction) <);
    if (argstr) {
        (> .check_valid_message((x = toint(argstr))) <);
        .print("+OK " + ((mail_objects[x]).rfc822_size()));
    } else {
        .print(((("+OK " + ((m = .live_messages()).length())) + " messages (") + (.mailbox_size())) + " octets)");
        for x in [1 .. mail_objects.length()] {
            if (!(x in deleted))
                .print((x + " ") + ((mail_objects[x]).rfc822_size()));
        }
        .print(".");
    }
};

protected method .live_messages() {
    var x, r;
    
    r = [];
    for x in [1 .. mail_objects.length()] {
        if (!(x in deleted))
            r += [mail_objects[x]];
    }
    return r;
};

protected method .retr_cmd() {
    arg argstr;
    var msgnum, x;
    
    (> .check_state("RETR", 'transaction) <);
    (> .check_valid_message((msgnum = toint(argstr))) <);
    .print(("+OK " + ((mail_objects[msgnum]).rfc822_size())) + " octets");
    for x in ((mail_objects[msgnum]).format_rfc822()) {
        refresh();
        if (!x)
            .print(x);
        else
            .print(((x[1]) == ".") ? ("." + x) : x);
    }
    .print(".");
};

protected method .check_state() {
    arg command, st;
    
    if (state != st)
        throw(~stop, ((("-ERR " + command) + " command only valid in ") + st) + " state");
};

protected method .check_valid_message() {
    arg num;
    
    if ((num < 1) || (num > (mail_objects.length())))
        throw(~stop, ("-ERR no such message, only " + (mail_objects.length())) + " messages in maildrop");
    else if (num in deleted)
        throw(~stop, "-ERR ", x, " refers to a deleted message");
};

protected method .dele_cmd() {
    arg argstr;
    var msgnum;
    
    (> .check_state("DELE", 'transaction) <);
    (> .check_valid_message((msgnum = toint(argstr))) <);
    deleted += [msgnum];
    .print("+OK message deleted");
};

protected method .noop_cmd() {
    arg argstr;
    
    (> .check_state("NOOP", 'transaction) <);
    .print("+OK");
};

protected method .rset_cmd() {
    arg argstr;
    
    (> .check_state("RSET", 'transaction) <);
    deleted = [];
    .print(((("+OK maildrop has " + (mail_objects.length())) + " messages (") + (.mailbox_size())) + " octets)");
};

protected method .top_cmd() {
    arg argstr;
    var args, m, n, x, b;
    
    (> .check_state("TOP", 'transaction) <);
    if (((args = argstr.explode()).length()) != 2)
        throw(~stop, "-ERR command needs two arguments");
    if ((n = toint(args[2])) < 0)
        throw(~stop, "-ERR second argument must be a non-negative integer");
    (> .check_valid_message((m = toint(args[1]))) <);
    .print("+OK");
    for x in ((mail_objects[m]).format_rfc822()) {
        if (x)
            .print(((x[1]) == ".") ? ("." + x) : x);
        else
            .print(x);
        if (b) {
            if (--n <= 0)
                break;
        } else if (!x) {
            b++;
        }
    }
    .print(".");
};

protected method .mailbox_size() {
    var x;
    
    return map x in (mail_objects) to (x.rfc822_size()).sum();
};

protected method .uidl_cmd() {
    arg argstr;
    var x;
    
    (> .check_state("UIDL", 'transaction) <);
    if (argstr) {
        (> .check_valid_message((x = toint(argstr))) <);
        .print((("+OK " + x) + " ") + ((mail_objects[x]).unique_id()));
    } else {
        .print("+OK");
        for x in [1 .. mail_objects.length()] {
            if (!(x in deleted))
                .print((x + " ") + ((mail_objects[x]).unique_id()));
        }
        .print(".");
    }
};

protected method .user_cmd() {
    arg argstr;
    
    (> .check_state("USER", 'authorization) <);
    catch any
        maildrop = $user_db.exact_match(argstr);
    with
        throw(~stop, "-ERR unknown user");
    .print("+OK " + (maildrop.namef('ref)));
};

protected method .pass_cmd() {
    arg argstr;
    var x;
    
    (> .check_state("USER", 'authorization) <);
    if (!maildrop)
        throw(~stop, "-ERR issue USER command first");
    if ($security_lib.check_password(maildrop, argstr)) {
        catch any
            mail_objects = maildrop.mail();
        with
            throw(~stop, "-ERR could not open maildrop");
        state = 'transaction;
        .print(((((("+OK " + (maildrop.namef('ref))) + " has ") + (mail_objects.length())) + " messages (") + (.mailbox_size())) + " octets)");
    } else {
        throw(~stop, "-ERR authentication failed");
    }
};

protected method .null_cmd() {
    arg line;
    
    return .invalid_cmd(line);
};

protected method .invalid_cmd() {
    arg line;
    
    .print("-ERR unimplemented or unrecognized command");
};

public method .parse_line() {
    arg line;
    var cmd, argstr, meth;
    
    (> .perms(caller(), $connection) <);
    cmd = line.word(1);
    argstr = (" " in line) ? (line.subrange((" " in line) + 1)) : "";
    if (!cmd)
        meth = 'null_cmd;
    else
        meth = (| default_var('commands)[cmd] |) || 'invalid_cmd;
    catch any {
        return .(meth)(argstr);
    } with {
        if (error() == ~stop) {
            .print((traceback()[1])[2]);
        } else {
            .print("-ERR Unrecoverable internal error");
            return 'disconnect;
        }
    }
};


new object $smtp_interface: $connection_interface, $has_name;

var $root manager = $smtp_interface;
var $root quota_exempt = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 849172060;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $root inited = 1;
var $root managed = [$smtp_interface];
var $smtp_interface mail_from = "";
var $smtp_interface cmds = #[["HELP", 'help_cmd], ["QUIT", 'quit_cmd], ["VRFY", 'verify_cmd], ["EXPN", 'verify_cmd], ["HELO", 'hello_cmd], ["MAIL", 'mail_from_cmd], ["NOOP", 'noop_cmd], ["RCPT", 'recipient_cmd], ["DATA", 'data_cmd]];
var $smtp_interface cmd_help = #[["HELP", ["HELP [<topic>]", "    For more help on any command type 'help <cmd>'"]], ["QUIT", ["QUIT", "    Ends your mail session"]], ["EXPN", ["EXPN <recipient>", "   Expand an address."]], ["VRFY", ["VRFY <recipient>", "   Verify an address."]], ["HELO", ["HELO <hostname>", "   Introduce yourself."]], ["MAIL", ["MAIL FROM: <sender>", "   Specify sender/return path."]], ["NOOP", ["NOOP", "   Do nothing"]], ["RCPT", ["RCPT TO:<recipient>", "   Specifies the recipient.  Can be used any number of times."]], ["DATA", ["DATA", "   Following data is collected as the message", "   End with a single dot"]]];
var $smtp_interface given_hostname = "";
var $smtp_interface mail_to = [];
var $smtp_interface mail_body = [];
var $smtp_interface mail_status = 'idle;
var $has_name name = ['prop, "smtp_interface", "smtp_interface"];
var $command_cache commands = 0;
var $smtp_interface read_header = 0;
var $smtp_interface header = [];
var $command_cache shortcuts = 0;
var $root trusted_by = [$no_one];

public method .parse_line() {
    arg line;
    var method, cmd, args, name, rest, m, last;
    
    if (mail_status == 'read_body) {
        if (line == ".") {
            .send_mail();
            mail_status = 'idle;
            return;
        } else {
            if (read_header) {
                mail_body += [line];
            } else if (!line) {
                read_header = 1;
            } else if ((m = regexp(line, "^([^ ][^:]+) *: *(.*)$"))) {
                header += [m];
            } else if (header) {
                last = header[listlen(header)];
                header = sublist(header, 1, listlen(header));
                last = replace(last, 2, (last[2]) + line);
                header += [last];
            }
            return;
        }
    }
    cmd = line.word(1);
    if ((line.length()) >= ((cmd.length()) + 2))
        args = line.subrange((cmd.length()) + 2);
    else
        args = "";
    catch ~keynf {
        method = definer().get_cmd(cmd);
    } with {
        (.connection()).write("500 unrecognized command");
        return 'disconenct;
    }
    return .(method)(args);
};

public method .connection_starting() {
    arg addr, port;
    
    (.connection()).write((("220 " + ($sys.server_info('server_hostname))) + " SMTP ColdMail 1.0/1.0; ") + ($time.format("%a, %d %b %Y %H:%M:%S %Z")));
};

public method .help_cmd() {
    arg rest;
    var i, conn;
    
    conn = .connection();
    if ((rest.length()) == 0) {
        conn.write(["214-This is ColdMail 0.01.", "214-Valid Commands:"]);
        for i in (definer().get_cmds())
            conn.write("214-  " + i);
        conn.write("214 End of Help");
    } else {
        catch ~keynf {
            rest = definer().get_cmd_help(rest);
            for i in (rest)
                conn.write("214-" + i);
            conn.write("214 End of Help");
        } with {
            conn.write(("504 HELP topic '" + rest) + "' not found.");
        }
    }
};

public method .quit_cmd() {
    arg rest;
    
    (.connection()).write(("221 " + ($sys.server_info('server_hostname))) + " closing connection");
    return 'disconnect;
};

public method .get_cmd() {
    arg cmd;
    
    return (> cmds[cmd] <);
};

public method .get_cmd_help() {
    arg help;
    
    return (> cmd_help[help] <);
};

public method .get_cmds() {
    return cmds.keys();
};

public method .verify_cmd() {
    arg rest;
    var conn, user, i, out;
    
    conn = .connection();
    if ((rest.length()) == 0) {
        conn.write("501 Argument required");
    } else {
        if (!($smtp.allowed('VRFY))) {
            conn.write("252 VRFY not allowed");
            return;
        }
        out = [];
        for i in (rest.explode()) {
            catch any {
                out = setadd(out, $smtp.parse_recipient(i));
            } with {
                switch (error()) {
                    case ~ambig:
                        conn.write("553 Ambiguous Recipient");
                    default:
                        conn.write(((((traceback()[1])[3]) || 550) + " ") + ((traceback()[1])[2]));
                        return;
                }
            }
        }
        for i in [1 .. (out.length()) - 1]
            conn.write("250-" + ($smtp.format_email_address(out[i])));
        if (out)
            conn.write("250 " + ($smtp.format_email_address(out.last())));
    }
};

public method .hello_cmd() {
    arg rest;
    var conn;
    
    conn = .connection();
    if ((rest.length()) == 0) {
        conn.write("501 HELO requires domain address");
    } else if (given_hostname == 0) {
        conn.write(((("250 " + ($sys.server_info('server_hostname))) + " Hello ") + (conn.address())) + ", pleased to meet you");
        given_hostname = rest;
    } else {
        conn.write("503 portland.puremagic.com Duplicate HELO");
    }
};

public method .mail_from_cmd() {
    arg rest;
    var conn, i;
    
    conn = .connection();
    if (((rest.length()) <= 5) || (((i = ":" in rest) != 5) || ((| rest.subrange(1, 5) |) != "from:"))) {
        conn.write(("501 Syntax error in \"" + (rest.subrange(1, (i == 0) ? (rest.length()) : (i - 1)))) + "\"");
    } else if (mail_from != "") {
        conn.write("503 Sender already specified");
    } else {
        .reset_interface();
        mail_from = (rest.subrange(6)).trim();
        header = [["MAIL FROM", mail_from]];
        conn.write(("250 " + mail_from) + "... sender ok");
    }
};

public method .init_smtp_interface() {
    .reset_interface();
    mail_status = 'idle;
};

public method .uninit_smtp_interface() {
    header = 0;
    read_header = 0;
    mail_from = 0;
    mail_to = 0;
    mail_body = 0;
    mail_status = 0;
};

public method .noop_cmd() {
    arg rest;
    
    (.connection()).write("250 Ok");
};

public method .recipient_cmd() {
    arg rest;
    var conn, i, user;
    
    conn = .connection();
    if (mail_from == "") {
        conn.write("503 Need MAIL before RCPT");
    } else if (((rest.length()) <= 3) || (((i = ":" in rest) != 3) || ((| rest.subrange(1, 3) |) != "to:"))) {
        conn.write(("501 Syntax error in \"" + (rest.subrange(1, (i == 0) ? (rest.length()) : (i - 1)))) + "\"");
    } else {
        catch any {
            user = $smtp.parse_recipient(rest.subrange(4));
            mail_to += [user];
            conn.write(("250 " + user) + "... recipient ok");
        } with {
            if (error() == ~ambig)
                conn.write("553 Ambiguous Recipient");
            else
                conn.write(((((traceback()[1])[3]) || 550) + " ") + ((traceback()[1])[2]));
        }
    }
};

public method .reset_interface() {
    header = [];
    read_header = 0;
    mail_from = "";
    mail_to = [];
    mail_body = [];
};

public method .data_cmd() {
    arg rest;
    var conn;
    
    conn = .connection();
    if (mail_from == "") {
        conn.write("503 Need MAIL command");
    } else if (mail_to == []) {
        conn.write("503 Need RCPT command");
    } else {
        conn.write("354 Enter mail, end with \".\" on a line by itself");
        mail_status = 'read_body;
    }
};

public method .send_mail() {
    var l, subj, from;
    
    .set_name(mail_from, 'prop);
    subj = "<NO SUBJECT>";
    for l in (header) {
        if ((l[1]) == "Subject")
            subj = l[2];
        if ((l[1]) == "From")
            from = l[2];
    }
    from ?= mail_from;
    catch any {
        $no_one.mail_as(from, header, subj, mail_body, @mail_to);
        (.connection()).write(("250 " + ($smtp_daemon.get_msg_id())) + " Message accepted for delivery");
    } with {
        .log_traceback(traceback(), "SMTP: DATA");
        (.connection()).write("550 Requested action not taken: Error delivering mail");
    }
    .reset_interface();
};


new object $has_text: $foundation;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $has_text text = 0;
var $root manager = $has_text;
var $root managed = [$has_text];
var $root defined_settings = #[["plaintext", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $root settings = #[["plaintext", 1]];
var $root help_node = $help_obj_has_text;

root method .init_has_text() {
    text = [];
};

root method .uninit_has_text() {
    text = [];
};

public method .text() {
    // returns text
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    return text;
};

public method .set_text() {
    arg txt;
    
    // resets ,text to the list sent
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    if (.get_setting("plaintext", $has_text)) {
        if (type(txt) == 'string)
            text = [txt];
        else
            text = txt;
    } else {
        text = $compiler.compile_cml(txt);
    }
};

public method .ins_line() {
    arg txt, @loc;
    var t;
    
    // inserts txt at loc (where loc is an integer)
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    [(loc ?= 0)] = loc;
    t = .get_raw_text();
    if (!loc)
        t += [txt];
    else
        t = (> t.insert(loc, txt) <);
    .set_text(t);
};

public method .del_text() {
    // deletes all text
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    text = [];
};

public method .del_line() {
    arg linestr;
    var t;
    
    // deletes "line" where line is the actual line to delete
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    t = .get_raw_text();
    t = t.setremove(linestr);
    .set_text(t);
};

public method .del_nline() {
    arg nline;
    var t;
    
    // deletes nline where nline is an integer reference to a list location
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    t = .get_raw_text();
    t = (> t.delete(nline) <);
    .set_text(t);
};

public method .ins_lines() {
    arg lines, loc;
    var line, t;
    
    // inserts txt at loc (where loc is an integer)
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    t = .get_raw_text();
    if (type(lines) != 'list)
        throw(~type, "Lines should be passed as a list of strings.");
    for line in (lines) {
        t = (> t.insert(loc, line) <);
        ++loc;
    }
    .set_text(t);
};

public method .edit_text() {
    var p;
    
    (> .perms(sender()) <);
    p = .get_raw_text();
    (> sender().invoke_editor(this(), '_edit_text_callback, p, []) <);
};

public method ._edit_text_callback() {
    arg t, client_data;
    
    (> .perms(caller(), $editor_reference) <);
    .set_text(t);
    return ['success, ["Text set."]];
};

public method .lines() {
    return listlen((.get_raw_text()) || []);
};

public method .get_raw_text() {
    // returns text
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    if (.get_setting("plaintext", $has_text))
        return text;
    else if (type(text) == 'frob)
        return text.uncompile();
    else
        return text;
};


new object $mail_message: $has_text, $mail_root;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root quota_exempt = 1;
var $mail_message readers = [];
var $mail_message header = #[];
var $mail_message delivered = 0;
var $root manager = $mail_message;
var $root managed = [$mail_message];
var $mail_message creator = 0;
var $mail_message meta = 0;
var $root trusted_by = [$smtp];
var $mail_message rfc822_size = 0;
var $mail_message frominet = 0;

public method .del_recipient(): nooverride {
    arg whom;
    var rcpts;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    rcpts = (header['rcpt]).setremove(whom);
    if (!rcpts)
        .destroy();
    else
        header = header.add('rcpt, rcpts);
};

public method .add_recipient(): nooverride {
    arg whom;
    var current;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    current = (| header['rcpt] |) || [];
    if ((| whom in current |))
        throw(~type, "Recipient is already in the list of recipients");
    header = dict_add(header, 'rcpt, setadd(current, whom));
};

public method .body() {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    return .text();
};

public method .readers(): nooverride {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    return readers;
};

public method .did_read(): nooverride {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    if ($guest in (sender().parents()))
        return;
    readers = setadd(readers, sender());
};

public method .set_time(): nooverride {
    arg time;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    header = header.add('time, time);
};

public method .set_recipients(): nooverride {
    arg whom;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    header = header.add('rcpt, whom);
};

public method .set_subject(): nooverride {
    arg what;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    header = header.add('subj, what);
};

public method .set_from(): nooverride {
    arg whom;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    header = header.add('from, whom);
};

public method .add_reader(): nooverride {
    arg who;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    readers = setadd(readers, who);
};

public method .recipients(): nooverride {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    return (| header['rcpt] |) || [$no_one];
};

public method .from(): nooverride {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    return (| header['from] |) || $no_one;
};

public method .subject(): nooverride {
    return (| header['subj] |) || "<none>";
};

public method .time(): nooverride {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    return (| header['time] |) || 0;
};

public method .format(): nooverride {
    arg @metainfo;
    var output, o, h, line, br, sep, i;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    h = .header();
    o = [];
    br = $cml_lib.format_br_tag();
    sep = $cml_lib.format_sep_tag();
    if (metainfo) {
        for i in (meta || [])
            o += [$cml_lib.format_tr_tag($cml_lib.format_td_tag(("I-" + (i[1])) + ":"), $cml_lib.format_td_tag(i[2]))];
    }
    o += [$cml_lib.format_tr_tag($cml_lib.format_td_tag("From:"), $cml_lib.format_td_tag($object_lib.get_name(h['from], 'mail_name)))];
    o += [$cml_lib.format_tr_tag($cml_lib.format_td_tag("To:"), $cml_lib.format_td_tag(((h['rcpt]).omap($mail_lib, 'mail_name)).to_english()))];
    o += [$cml_lib.format_tr_tag($cml_lib.format_td_tag("When:"), $cml_lib.format_td_tag($time.format("%I:%M %p %d-%b-%Y", h['time])))];
    o += [$cml_lib.format_tr_tag($cml_lib.format_td_tag("Subject:"), $cml_lib.format_td_tag(h['subj]))];
    output = [$cml_lib.format_table_tag("18%,82%", @o), sep, map line in (.text()) to ([line, br]), sep];
    return $ctext_frob.new_with(output);
};

public method .header(): nooverride {
    var h, d;
    
    (> .perms(sender()) <);
    h = #[['from, $no_one], ['rcpt, [$no_one]], ['subj, "<none>"], ['time, 0]];
    for d in (header)
        h = h.add(@d);
    return h;
};

root method .uninit_mail_message() {
    var r;
    
    for r in (.recipients())
        (| r.del_mail(this(), 'mail_destroyed) |);
    header = #[];
    readers = [];
};

root method .init_mail_message() {
    header = #[];
    readers = [];
    .set_flags([]);
};

public method .has_read(): nooverride {
    arg who;
    
    return who in readers;
};

protected method .text() {
    return (> pass() <) || ["", "(no message)", ""];
};

public method .send() {
    arg @recips;
    var r, valid, invalid, from;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    if (delivered)
        throw(~delivered, "This mail has already been delivered.");
    if (!recips)
        recips = .recipients();
    if (((recips.length()) == 1) && ((recips[1]) == $no_one))
        throw(~norcpt, "No recipients specified.");
    
    // Cache RFC822 size
    .rfc822_size();
    valid = [];
    invalid = [];
    for r in (recips) {
        if (r.has_ancestor($mail_list))
            valid += [r];
        else
            invalid += [r];
    }
    if (invalid)
        throw(~invrcpt, "Invalid mail recipients: " + (invalid.mmap('name)), invalid);
    recips = valid;
    invalid = [];
    
    // ok, now that we have that cleared up, lets set pertinent info...
    .set_time(time());
    if ((!(.from())) || (sender() != $no_one))
        .set_from(sender());
    
    // and now to finalize the recipients
    for r in (recips) {
        if ((r.list_is_inet()) && (!frominet)) {
            from = (sender().user_info("name")) || (sender().name());
            from += (" <" + (sender().user_info("email"))) + ">";
            r = r.get_setting("inet-list", $mail_list);
            $smtp.sendmail(from, r, header['subj], .body());
            delivered++;
        } else if (r.list_is_sendable_by(sender())) {
            r.add_mail();
            .add_recipient(r);
            delivered++;
        } else {
            invalid += [r];
        }
    }
    if (!delivered)
        throw(~delivered, "Unable to deliver message.");
    return invalid;
};

public method .new_mail(): nooverride {
    var new, suffix;
    
    // if (!$mail_lib.has_mail_perms(caller()))
    //     (> .perms(sender()) <);
    if (definer() != this())
        throw(~perm, "Only spawn mail from $mail_message.");
    suffix = tosym("mail_" + (.get_obj_suffix()));
    new = (> $sys.spawn_selfmanager(suffix, sender()) <);
    
    // since anybody can create mail, do some tracking..
    new.set_creator(user());
    return new;
};

public method .creator() {
    return creator;
};

private method .set_creator() {
    arg who;
    
    creator = who;
};

public method .set_meta(): nooverride {
    arg new_meta;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    meta = new_meta;
};

public method .meta(): nooverride {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    return meta || [];
};

public method .format_rfc822() {
    var out, x, line;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    if (.meta()) {
        out = [];
        for x in (.meta())
            out += [((x[1]) + ": ") + (x[2])];
    } else {
        out = ["Date: " + ($time.format("%a, %e %b %Y %H:%M:%S %Z", .time()))];
        out += ["From: " + ($smtp.get_email_address(.from()))];
        out += ["To: " + (((.recipients()).omap($smtp, 'get_email_address)).join(", "))];
        out += [((("Message-ID: <" + (.unique_id())) + "@") + ($sys.server_info('server_hostname))) + ">"];
        out += ["Subject: " + (.subject())];
        out += ["X-UIDL: " + (.unique_id())];
    }
    out += [""];
    for line in (.body()) {
        refresh();
        if ((line.length()) > 79)
            out += line.wrap_lines(75);
        else
            out += [line];
    }
    return out;
};

public method .rfc822_size() {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    if (!rfc822_size)
        rfc822_size = ((.format_rfc822()).to_buffer()).length();
    return rfc822_size;
};

public method .is_frominet() {
    if (sender() == $no_one)
        frominet = 1;
};

public method .unique_id() {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    if (!(header.contains('uidl)))
        header = header.add('uidl, $mail_lib.generate_unique_id(this()));
    return header['uidl];
};


new object $itext: $has_text;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $has_text text = ["hello", "this", "world"];
var $itext all_text = #[["foo", [["hello", "world"], ""]], ["bar", [["hello", "this", "world"], ""]]];
var $itext current = "foo";
var $root manager = $itext;
var $root managed = [$itext];

public method .current() {
    return current;
};

public method .topics() {
    return all_text.keys();
};

public method .set_desc() {
    arg desc, @topic;
    
    // set the description for a topic
    // The description is a short text string meant for use in an index
    // if <topic> is not given assume current
    [(topic ?= current)] = topic;
    if (topic in (all_text.keys()))
        all_text = all_text.add(topic, (all_text[topic]).replace(2, short_desc));
    else
        throw(~topicnf, ("Topic " + topic) + " not found.");
};

public method .store() {
    arg @topic;
    
    [(topic ?= current)] = topic;
    if (!(topic in (all_text.keys())))
        all_text = all_text.add(topic, [.text(), ""]);
    all_text = all_text.add(topic, (all_text[topic]).replace(1, .text()));
};

public method .set_current() {
    arg topic;
    
    current = topic;
    if (topic in (all_text.keys()))
        .set_text((all_text[topic])[1]);
    else
        .set_text([]);
};

public method .get_topic() {
    arg topic, @who;
    
    if (topic in (all_text.keys()))
        return (all_text[topic])[1];
    else
        throw(~topicnf, ("Topic " + topic) + " not found.");
};

root method .init_itext() {
    current = "";
    all_text = #[];
};

public method .get_desc() {
    arg topic, @who;
    
    if (topic in (all_text.keys()))
        return (all_text[topic])[2];
    else
        throw(~topicnf, ("Topic " + topic) + " not found.");
};


new object $note: $thing, $has_text;

var $root inited = 1;
var $root created_on = 796268969;
var $has_text text = [];
var $located location = $void;
var $located obvious = 1;
var $described prose = [];
var $has_name name = ['uniq, "Generic Note", "the Generic Note"];
var $note seperator = 0;
var $foundation edit_types = ["text"];
var $has_commands remote = #[["erase", [["erase", "*", "erase <this>", 'erase_cmd, #[[1, ['this, []]]]], ["erase", "* on|from *", "erase <string> on|from <this>", 'erase_on_cmd, #[[1, ['any, []]], [3, ['this, []]]]]]], ["read|nread", [["read|nread", "*", "read|nread <this>", 'read_cmd, #[[1, ['this, []]]]]]], ["write", [["write", "on *", "write on <this>", 'write_cmd, #[[2, ['this, []]]]], ["write", "at * on *", "write at <string> on <this>", 'write_at_cmd, #[[2, ['any, []]], [4, ['this, []]]]]]], ["copy", [["copy", "from * to *", "copy from <this> to <any>", 'copy_cmd, #[[2, ['this, []]], [4, ['any, []]]]]]]];
var $root manager = $note;
var $root defined_settings = #[["private", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $thing gender = $gender_neuter;
var $root settings = #[["private", 0]];
var $dmi_data descriptions = #[['read, #[['arg_order, ["who", "numbered"]], ['args, #[["who", [[$no_one], []]], ["numbered", [[0], [$converters, 'to_num, []]]]]], ['auth, 'none]]]];
var $root managed = [$note];
var $root flags = ['core, 'fertile, 'code, 'methods, 'variables];

protected method .add_text() {
    arg ntext, who, @args;
    
    // if at they should be an int defining where to insert.
    if (ntext) {
        if (ntext == 'aborted)
            return;
        if (args) {
            if (!(| .ins_lines(ntext, args[1]) |))
                who.tell(("There are not that many lines in " + (.name())) + ".");
        } else {
            .set_text((.get_raw_text()) + ntext);
        }
        who.tell(((("Line" + (((ntext.length()) == 1) ? "" : "s")) + " added to ") + (.name())) + ".");
    } else {
        who.tell("Text not added.");
    }
};

public method .seperator() {
    return $cml_lib.format_sep_tag();
    return (type(seperator) == 'string) ? seperator : "---";
};

root method .init_note() {
    .del_flag('variables);
};

public method .set_seperator() {
    arg newsep;
    
    .perms(sender(), 'manager);
    seperator = newsep;
};

public method .read_cmd() {
    arg cmdstr, cmd, @args;
    var who, numbered;
    
    numbered = (cmd == "nread") ? 1 : 0;
    return (.read(sender(), numbered)).append(["You finish reading " + (.name())]);
};

public method .write_cmd() {
    arg cmdstr, cmd, @args;
    var who, line;
    
    if (!(.is_writable_by(sender())))
        return ("You do not have permission to write on " + (.name())) + ".";
    who = sender();
    line = "Now writing on " + (.name());
    line += ", enter \".\" to finish and \"@abort\" to abort.";
    .add_text(who.read(line), who);
};

public method .erase_on_cmd() {
    arg cmdstr, cmd, str, prep, this;
    var line, nline, who, len, oldline;
    
    (> .perms(sender()) <);
    who = sender();
    if (!str)
        return who.tell("You must erase either a line, line number, or all");
    catch any {
        if ($string.match_begin("all", str)) {
            .del_text();
    
            // if cmd is null, this method was called by an editor
            if (cmd)
                who.tell(("All text cleared from " + (.name())) + ".");
        } else {
            if (((str.explode()).length()) > 1)
                nline = toint((str.explode())[2]);
            else
                nline = toint(str);
            oldline = (.get_raw_text())[nline];
            .del_nline(nline);
            line = ("Line " + tostr(nline)) + " (\"";
            len = (who.linelen()) - (25 + ((.name()).length()));
            line += $string.chop(oldline, len);
            line = (line + "\") erased from ") + (.name());
            who.tell(line);
        }
    } with {
        switch (error()) {
            case ~range:
                who.tell("There are not that many lines in the text.");
            default:
                who.tell("Oops: " + ((traceback()[1])[2]));
        }
    }
};

public method .erase_cmd() {
    arg cmdstr, cmd, this;
    var line, nline, len;
    
    (> .perms(sender()) <);
    .del_text();
    
    // if cmd is null, this method was called by an editor originally.
    if (cmd)
        sender().tell(("All text cleared from " + (.name())) + ".");
};

public method .write_str_cmd() {
    arg cmdstr, cmd, str, prep, this;
    
    (> .perms(sender()) <);
    if (!str)
        return ("Nothing to write on " + (.name())) + "!";
    .add_text([str], sender());
};

public method .write_at_cmd() {
    arg cmdstr, cmd, at, str, prep, this;
    var who, line, lines, syn;
    
    (> .perms(sender()) <);
    who = sender();
    syn = ((("`" + cmd) + " at [line] <line number> on ") + this) + "`";
    str = str.explode();
    if ((str[1]) == "line")
        str = str.delete(1);
    line = $string.is_numeric(str[1]);
    if (!at)
        $parse_lib.tell_error(("Unknown line \"" + (str[1])) + "\".", syn, who);
    lines = .lines();
    if (line > (lines + 1))
        $parse_lib.tell_error(("There are only " + tostr(lines)) + " lines!", syn, who);
    .add_text(who.read(), who, line);
};

public method .copy_cmd() {
    arg cmdstr, cmd, from, this, prep, dest;
    var obj, what;
    
    // this method is outdated, needs to be rewritten.
    // it probably doesn't even work.
    if (!(.trusts(sender())))
        return sender().tell(("You cannot read the text on " + (.namef('ref))) + ".");
    dest = $parse_lib.ref(dest);
    obj = dest[3];
    if (!(obj.is_writable_by(sender())))
        return .tell(("!  " + (obj.namef('ref))) + " is not writable by you.");
    if ((obj.has_ancestor($note)) && (!(dest[4])))
        obj.add_text(text, sender());
    if ((dest[1]) == 'method) {
        catch any {
            dest = (> tosym(dest[4]) <);
            if (what) {
                obj.(dest)(text, sender());
                sender().tell(((("Text copied to " + obj) + ".") + dest) + "().");
            } else {
                if (!((| tosym(dest) |) in (obj.variables())))
                    return .tell(("!  variable '" + dest) + " not found");
                obj.eval([(dest + " = ") + (.text())]);
            }
        } with {
            sender().tell_error((traceback()[1])[2]);
        }
    }
    sender().tell("Text copied from " + (.name()));
};

public method .description() {
    arg flags;
    
    if (dict_contains(flags, 'nonote))
        return (> pass(flags) <);
    return (> pass(flags) <) + [$ctext_frob.new_with(["You see some writing on the note, and may be able to ", $cml_lib.format_invoke_tag(tostr(this()), "read", "read"), " it..."])];
};

public method .read() {
    arg who, numbered;
    var text, prose, output, br;
    
    output = $ctext_frob.new_with([]);
    br = $cml_lib.format_br_tag();
    if ((.get_setting("private", $note)) && (!(.trusts(who))))
        return [("You cannot read " + (.name())) + "."];
    output = output.append([$cml_lib.format_subj_tag(.name(), 2), br]);
    output = output.append([.prose(), br]);
    output = output.append([.seperator()]);
    text = .text();
    if ((!(.get_setting("plaintext", $has_text))) && (type(text) == 'frob)) {
        output = output.append(text.append(br));
    } else {
        if (numbered && text)
            text = $list.numbered_text(text);
        text = text ? text : ["", "(nothing)", ""];
        output = output.append([$cml_lib.format_pre_tag($cml_lib.generate_join_tag(text, br)), br]);
    }
    output = output.append([.seperator()]);
    return output;
};


new object $generic_map: $note;

var $root manager = $generic_map;
var $located obvious = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 840768594;
var $located location = $void;
var $has_text text = [];
var $root inited = 1;
var $described prose = <$ctext_frob, [["This is generic map object - it's generic holder for area maps."], #[['this, $generic_map]]]>;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['uniq, "Generic Map", "the Generic Map"];
var $root managed = [$generic_map];
var $thing gender = $gender_neuter;
var $root help_node = $help_obj_generic_map;

public method .view() {
    arg x, y, code, height, width;
    var text, i, out, pos, line;
    
    text = .text();
    pos = 0;
    out = [];
    for i in [y .. y + height] {
        line = (| ((text[i]).subrange(x + 1)).pad(width) |) || "";
        pos = pos || (code in line);
        out += [((line.left(width)).replace(code, "[]")).sed("[0-9]", " ", "g")];
    }
    return [@out, pos ? "Your position is '[]'." : "Your position is not shown on this map."];
};


new object $page: $core;

var $root manager = $page;
var $dmi_data descriptions = #[];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863765169;
var $root inited = 1;
var $page lock = 0;
var $root managed = [$page];
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];

public method .generate() {
    arg headers, info, args;
    
    return [["<html><head><title>Error</title></head><body>Error</body></html>"]];
};

public method .get_lock() {
    return lock;
};

public method .build_header() {
    arg headers, info, args, @rest;
    
    return (> (info['directory_object]).build_header(headers, info, args, @rest) <);
};

public method .build_footer() {
    arg headers, info, args;
    
    return (> (info['directory_object]).build_footer(headers, info, args) <);
};

public method .get_realm() {
    return (> (info['directory_object]).get_realm() <);
};


new object $page_home_index: $page;

var $root manager = $page_home_index;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863765377;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $root managed = [$page_home_index];
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];

public method .generate() {
    arg header, info, args;
    var user, page;
    
    user = (| $user_db.search(substr(info['path_info], 2)) |);
    if (user) {
        catch ~private {
            page = user.get_setting("rl-home-page", $user_info);
            if ((page[1]) && (page[2])) {
                if (substr(page[2], 1, 7) != "http://")
                    page = page.replace(2, "http://" + (page[2]));
                return ['redirect, page[2]];
            }
        } with {
            return [(header['interface]).response(404, "User's homepage is private")];
        }
    } else {
        return [(header['interface]).response(404, "User not found")];
    }
};


new object $page_bin_index: $page;

var $root manager = $page_bin_index;
var $page_bin_index gateways = ["describe", "who", "display", "help", "object", "method"];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863765399;
var $dmi_data descriptions = #[['help, #[['args, #[["node", [[$help_coldcore], [$converters, 'to_help_node, []]]]]]]], ['who, #[['args, #[]]]], ['display, #[['args, #[["target", [[$root], [$converters, 'to_object, []]]], ["methods", [[0], []]], ["vars", [[0], []]], ["helpctext", [[0], []]], ["desc", [[0], []]]]]]], ['object, #[['args, #[["target", [[$root], [$converters, 'to_object, []]]]]]]], ['method, #[['args, #[["target", [[['method, $user, $user, "say_cmd", 0]], [$converters, 'parse_ref, [$foundation, ['method]]]]], ["linenumbers", [[0], [$converters, 'to_boolean, []]]]]]]], ['describe, #[['args, #[["detail", [[""], []]], ["target", [[$world], [$converters, 'to_object, []]]]]]]]];
var $root inited = 1;
var $root managed = [$page_bin_index];
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];

public method .generate() {
    arg header, info, args;
    var gate;
    
    return [(header['interface]).response(300, ["Multiple Choices: "] + (._list_gateways()))];
};

public method .who() {
    arg headers, info, args;
    var who, namel, names, times, idle, realm, x, cols, out, output, line;
    
    out = (.build_header(headers, info, args, #[['title, "Connected Users"]])) + [("<center><h2>Connected users to <i>" + ($motd.server_name())) + "</i></h2></center></head><body><pre>"];
    who = $user_db.connected();
    names = who.mmap('hname);
    namel = [];
    for x in (who.mmap('name))
        namel += [x.length()];
    cols = (namel.max()) + 1;
    if (cols < 5)
        cols = 5;
    times = who.mmap('connected_time);
    cols = [cols, (times.element_maxlength()) + 1];
    if ((cols[2]) < 7)
        cols = [cols[1], 7];
    idle = who.mmap('idle_time);
    cols += [(idle.element_maxlength()) + 1];
    if ((cols[3]) < 5)
        cols = cols.replace(3, 5);
    realm = who.mmap('realm_name, "text/html");
    out += [((((("<hr size=1 noshade><b>" + ("Name".pad(cols[1]))) + " ") + ("On for".pad(cols[2]))) + " ") + ("Idle".pad(cols[3]))) + " Location", ((((("----".pad(cols[1])) + " ") + ("------".pad(cols[2]))) + " ") + ("----".pad(cols[3]))) + " --------</b>"];
    for x in [1 .. who.length()] {
        line = ((("<b>" + (names[x])) + "</b>") + ("".pad((cols[1]) - (namel[x])))) + " ";
        line = (((line + "<i>") + (times[x])) + ("".pad((cols[2]) - ((times[x]).length())))) + " ";
        line = (((line + (idle[x])) + "</i>") + ("".pad((cols[3]) - ((idle[x]).length())))) + " ";
        line += realm[x];
        out += [line];
    }
    out += ["</pre>"];
    return [out + (.build_footer(headers, info, args))];
};

public method .describe() {
    arg header, info, args;
    var obj, desc, flags, detail, page, body, name, user;
    
    if ($security_lib.check_userdb_with_optional(header['interface]))
        user = (header['interface]).get_info('run_as);
    else
        user = $no_one;
    obj = (| args["target"] |);
    
    // because lame DMI
    if (obj == $world)
        obj = $world.get_setting("starting-place", $world);
    detail = (| args["detail"] |);
    if (detail) {
        detail = $http.decode(detail);
        name = ((obj.name()) + ": ") + detail;
        catch any
            body = (<$ctext_frob, [[(<$format, ["subj", [["level", "2"]], [detail.capitalize()], 'do_subj]>)], #[['this, obj]]]>).append(obj.get_detail(detail));
        with
            body = (header['interface]).response(404, ("No such detail '" + detail) + "'");
    } else {
        name = obj.name();
        body = obj.get_description(#[['actor, user]]);
    }
    return [[@.build_header(header, info, args, #[['title, obj.namef('ref)]]), body, @.build_footer(header, info, args)]];
};

public method .help() {
    arg header, info, args;
    var node, head, body, tail, tmp, n, name;
    
    node = (| args["node"] |);
    head = (.build_header(header, info, args, #[['title, "Help: " + (node.node_name())]])) + [("<h2 align=center>" + (node.html_node_name('top))) + "</h2><hr size=1 noshade>"];
    body = node.body();
    if (node.group()) {
        tail = "<p><hr size=1 noshade><p align=center>";
        tmp = "";
        for n in (((node.parents())[1]).children()) {
            if (n.nolist())
                continue;
            name = (n.name()).word(1, "|");
            if (n == node)
                tmp += ((tmp ? "| " : "") + name) + " ";
            else if (n.holder())
                tmp += (((tmp ? "| " : "") + "<i>") + name) + "</i> ";
            else
                tmp += (((((tmp ? "| " : "") + "<a href=\"/bin/help?node=") + n) + "\">") + name) + "</a> ";
        }
        if (tmp)
            tail += tmp + "<p>";
    } else {
        tail = "<p>";
    }
    return [[@head, body, tail, @.build_footer(header, info, args)]];
};

public method .object() {
    arg header, info, args;
    var out, obj, o, line, objs, m;
    
    obj = (| args["target"] |);
    out = (.build_header(header, info, args, #[['title, obj.namef('xref)]])) + [("<h1 align=center>" + (._make_display_href(obj, "&methods=1"))) + "</h1>"];
    line = "<p align=center><b>Parent(s)</b>: " + ((| ._make_object_href((obj.parents())[1]) |) || "(none)");
    for o in ((| (obj.parents()).subrange(2) |) || [])
        line += ", " + (._make_object_href(o));
    out += [line + "</p>", "<table>"];
    objs = obj.children();
    if (obj) {
        out += ["<p align=center><b>Children:</b></p>", "<center><table  cellspacing=0 cellpadding=0>", "<tr><td width=25%><b>Name</b></td><td width=25%><b>Perms</b></td><td width=25%><b>Size</b></td><td width=25%><b>Manager</b></td></tr>"];
        for o in (objs) {
            refresh();
            m = o.manager();
            if (!valid(o))
                m = toliteral(m);
            else
                m = ._make_object_href(m);
            out += [((((((("<tr><td>" + (._make_object_href(o))) + "</td><td>") + ($object_lib.see_perms(o, ["", ""]))) + "</td><td>") + ((o.size()).to_english())) + "</td><td>") + m) + "</td></tr>"];
        }
    }
    out += ["</table><p>", join(obj.credit(), "<br>"), "</center>"];
    return [out + (.build_footer(header, info, args))];
};

public method .display() {
    arg header, info, args;
    var out, obj, what, user;
    
    obj = (| args["target"] |);
    what = #[['desc, 0], ['methods, 0], ['vars, 0]];
    if ($security_lib.check_userdb_with_optional(header['interface]))
        user = (header['interface]).get_info('run_as);
    if (user) {
        what = dict_add(what, 'desc, (| user.get_setting("www-show-descriptions", $www_preferences) |));
        what = dict_add(what, 'methods, (| user.get_setting("www-show-methods", $www_preferences) |));
        what = dict_add(what, 'vars, (| user.get_setting("www-show-variables", $www_preferences) |));
    }
    if ((| args["vars"] |))
        what = dict_add(what, 'vars, (args["vars"]) == "yes");
    if ((| args["methods"] |))
        what = dict_add(what, 'methods, (args["methods"]) == "yes");
    if ((| args["desc"] |))
        what = dict_add(what, 'desc, (args["desc"]) == "yes");
    return (.build_header(header, info, args, #[['title, obj.namef('xref)]])) + [._show_object(obj, what), .build_footer(header, info, args)];
};

public method ._show_object() {
    arg obj, what;
    var top, middle, bottom, desc, alert, nalert, line;
    
    middle = (bottom = []);
    top = [("<h1>" + (._make_object_href(obj))) + "</h1>"];
    
    // CORENOTE: merge this with a central location (likely $directories)
    alert = ("<p><font size=\"+1\" color=\"#" + (($cml_color.get_color("red"))[1])) + "\"><b>";
    nalert = "</b></font>";
    top += ["<table>"];
    top += [("<tr><td><b>Perms</b>:</td><td>" + (((obj.flags()).prefix("+")).join())) + "</td></tr>", ("<tr><td><b>Size</b>:</td><td>" + ((obj.size()).to_english())) + " bytes (on disk)</td></tr>", ("<tr><td><b>Manager</b>:</td><td>" + (._make_object_href(obj.manager()))) + "</td></tr>", ._show_header_objs(obj.writers('literal), "Writer"), ._show_header_objs(obj.parents(), "Parent")];
    if (obj.has_ancestor($located))
        top += [("<tr><td><b>Location</b>:</td><td>" + (._make_object_href(obj.location()))) + "</td></tr>"];
    if (obj.help_node())
        top += [((("<tr><td><b>Associated Help</b>:</td><td><a href=\"/bin/help?node=" + (obj.help_node())) + "\">") + (obj.help_node())) + "</a></td></tr>"];
    top += [("<tr><td><b>Credit</b>:</td><td>" + join(obj.credit(), "<br>")) + "</td></tr>"];
    top += ["</table><p><hr size=1 noshade><p>"];
    if (obj.has_ancestor($described)) {
        if (what['desc]) {
            bottom += ["<p><b>Description</b>:<blockquote><pre>"];
            desc = obj.prose();
            switch (type(desc)) {
                case 'frob:
                    for line in (desc.uncompile())
                        bottom += line.wrap_lines(79, " ");
                case 'list:
                    bottom += desc;
                case 'string:
                    bottom += [desc];
            }
            bottom += ["</pre></blockquote>"];
            middle += [._make_show_object_href("Hide Description", obj, what, 'desc, 0)];
        } else {
            middle += [._make_show_object_href("Show Description", obj, what, 'desc, 1)];
        }
        top += ["</td></tr>"];
    }
    if (what['methods]) {
        if (!(obj.has_flag('methods, this())))
            bottom += [(alert + "** No permission to List Methods **") + nalert];
        else
            bottom += (["<p><b>Methods:</b><blockquote><pre>"] + (._show_methods(obj))) + ["</pre></blockquote>"];
        middle += [._make_show_object_href("Hide Methods", obj, what, 'methods, 0)];
    } else {
        middle += [._make_show_object_href("List Methods", obj, what, 'methods, 1)];
    }
    if (what['vars]) {
        if (!(obj.has_flag('variables, this())))
            bottom += [(alert + "** No permission to Show Variables **") + nalert];
        else
            bottom += (["<p><b>Variables:</b><blockquote><pre>"] + (._show_variables(obj))) + ["</pre></blockquote>"];
        middle += [._make_show_object_href("Hide Variables", obj, what, 'vars, 0)];
    } else {
        middle += [._make_show_object_href("Show Variables", obj, what, 'vars, 1)];
    }
    return (((top + middle) + ["<p>"]) + bottom) + ["<p>"];
};

public method ._make_object_href() {
    arg obj;
    
    return ((("<a href=\"/bin/object?target=" + (obj.objname())) + "\">") + ((obj.namef('xref)).to_html())) + "</a>";
};

public method ._show_methods() {
    arg obj;
    var methods, types, m, t, out;
    
    types = #[];
    for m in ((obj.methods()).sort((obj.methods()).mmap('to_string)))
        types = types.add_elem(obj.method_access(m), [m] + (obj.method_info(m)));
    
    // hard-listing the types guarantee's their order
    out = [];
    for t in (['root, 'driver, 'frob, 'public, 'protected, 'private]) {
        if (!(types.contains(t)))
            continue;
        out += [(tostr(t).capitalize()) + " methods:"];
        for m in (types[t])
            out += [strfmt("%5l %4r " + (._make_method_href([obj, m[1], m[2]])), $object_lib.parse_method_flags(m[7]), m[5])];
    }
    return out;
};

public method ._show_variables() {
    arg obj;
    var parent, out, v, s, n;
    
    out = [];
    for parent in (obj.data()) {
        if (valid(parent[1])) {
            out += [(._make_string_to_display_href(parent[1])) + " variables:"];
            if ((parent[1]).has_flag('variables, this())) {
                for v in (parent[2]) {
                    s = $data_lib.unparse_indent_html(v[2]);
                    n = ("  " + (v[1])) + ": ";
                    s = [s[1]] + ((s.subrange(2)).prefix(" ".pad(strlen(n))));
                    out += [n].affix(s);
                }
            } else {
                out += ["  ** Permission Denied **"];
            }
        } else {
            out += [($object_lib.get_name(parent[1])) + " variables:"];
            for v in (parent[2]) {
                s = $data_lib.unparse_indent_html(v[2]);
                n = ("  " + (v[1])) + ": ";
                s = [s[1]] + ((s.subrange(2)).prefix(" ".pad(strlen(n))));
                out += [n].affix(s);
            }
        }
        refresh();
    }
    return out;
};

public method ._show_header_objs() {
    arg objs, what;
    var o, line;
    
    if ((objs.length()) > 1) {
        line = (("<tr><td><b>" + what) + "s</b>:</td><td>") + (._make_object_href(objs[1]));
        for o in (objs.subrange(2))
            line += ", " + (._make_object_href(o));
        line += "</td></tr>";
    } else if ((objs.length()) == 1) {
        line = ((("<tr><td><b>" + what) + "</b>:</td><td>") + (._make_object_href(objs[1]))) + "</td></tr>";
    } else {
        line = ("<tr><td><b>" + what) + "</b>:</td><td>(none)</td></tr>";
    }
    return line;
};

public method ._make_method_href() {
    arg m, @options;
    
    if (options) {
        options = options.mmap('join, "=");
        options = options.join("&");
    }
    return (((((((((".<a href=\"/bin/method?target=%%24" + ((m[1]).objname())) + ".") + (m[2])) + "()") + (options ? ("&" + options) : "")) + "\">") + (m[2])) + "</a>(") + (m[3])) + ")";
};

public method ._make_display_href() {
    arg obj, @args;
    
    args = args ? (args.join("")) : "";
    return (((("<a href=\"/bin/display?target=" + (obj.objname())) + args) + "\">") + ((obj.namef('xref)).to_html())) + "</a>";
};

public method .method() {
    arg header, info, args;
    var ref, str_ref, name, obj, code, def, out, line, linenumbers, user, strings, flags, trace, anc, current, m, options;
    
    ref = (| args["target"] |);
    linenumbers = (| args["linenumbers"] |);
    if (!("linenumbers" in (args['arg_list]))) {
        if ($security_lib.check_userdb_with_optional(header['interface])) {
            user = (header['interface]).get_info('run_as);
            linenumbers = (| user.get_setting("www-show-line-num", $www_preferences) |) || 0;
        }
    }
    catch any {
        name = (> tosym(ref[4]) <);
        obj = ref[3];
        def = obj.find_method(name);
        if ('native in (def.method_flags(name)))
            code = ["This method is implemented natively within the driver."];
        else
            code = (def.list_method(name)).mmap('html_escape);
        options = (("linenumbers" in (args['arg_list])) && linenumbers) ? [["linenumbers", "yes"]] : [];
        code = $code_lib.code_to_html(code, obj, options);
        if (linenumbers)
            code = code.numbered_text();
        str_ref = ((obj + ".") + name) + "()";
        out = (.build_header(header, info, args, #[['title, str_ref]])) + [((((("<h1>Method code for " + (._make_string_to_display_href(obj, "&methods=yes"))) + ((def != obj) ? (("&lt;" + (._make_string_to_display_href(def, "&methods=yes"))) + "&gt;") : "")) + ".") + name) + "()") + "</h1>", "<blockquote>"];
        strings = linenumbers ? ["no", "off"] : ["yes", "on"];
        out += [strfmt("[<A HREF=\"/bin/method?target=%s&linenumbers=%s\">Turn %s line numbering</A>]", str_ref, @strings)];
        out += ["<hr size=1 noshade width=\"50%\" align=left><pre>"];
        out += code + ["</pre><hr size=1 noshade width=\"50%\" align=left>"];
        line = "// " + ((def.credit()).join("<br>// "));
        out += [("<font color=\"#a0a0a0\">" + line) + "</font>"];
        out += ["</blockquote>"];
        strings = (trace = []);
        current = def;
        while (current) {
            trace += [current];
            current = (| def.find_next_method(name, current) |);
        }
        if ((trace.length()) > 1) {
            out += ["<h2>Method Ancestry Override:</h2>"];
            out += ["<blockquote><pre>"];
            for anc in (trace) {
                m = anc.method_info(name);
                out += [strfmt(("%5l %4r " + (._make_string_to_display_href(anc))) + (._make_method_href([anc, name, m[1]], @options)), $object_lib.parse_method_flags(m[6]), m[4])];
            }
            out += ["</pre></blockquote>"];
        }
    } with {
        switch (error()) {
            case ~type:
                return [(header['interface]).response(400, ((("Invalid method reference " + obj) + ".") + name) + "()")];
            case ~methodnf:
                line = ((obj + ".") + name) + "()";
                return [(header['interface]).response(400, line + " not found.")];
            default:
                return [(header['interface]).response(400, (traceback()[1])[2])];
        }
    }
    return [out + (.build_footer(header, info, args))];
};

public method ._list_gateways() {
    var out, line, gate;
    
    out = ["<ul>"];
    for gate in (gateways) {
        line = ((("<li><b><a href=\"/bin/" + gate) + "\">") + gate) + "</a></b>";
        out += [line];
    }
    return out + ["</ul>"];
};

public method ._make_string_to_display_href() {
    arg obj, @args;
    
    args = args ? (args.join("")) : "";
    return (((("<a href=\"/bin/display?target=" + obj) + args) + "\">") + obj) + "</a>";
};

public method ._make_show_object_href() {
    arg msg, obj, what, change, value;
    var show, x;
    
    // used by ._show_object()
    what = dict_add(what, change, value);
    show = map x in (what) to (((x[1]) + "=") + ((x[2]) ? "yes" : "no")).join("&");
    if (show)
        return ((((("[<a href=\"/bin/display?target=" + (obj.objname())) + "&") + show) + "\">") + msg) + "</a>]";
    return ((("[<a href=\"/bin/display?target=" + (obj.objname())) + "\">") + msg) + "</a>]";
};

public method ._foof() {
    arg @args;
    
    return [];
};


new object $page_desktop_login: $page;

var $root manager = $page_desktop_login;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 864277988;
var $dmi_data descriptions = #[['generate, #[['args, #[]], ['auth, [$security_lib, 'check_userdb_with_password, []]]]]];
var $root inited = 1;
var $root managed = [$page_desktop_login];
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];

public method .generate() {
    arg headers, info, args;
    var page, opts, i;
    
    opts = #[['title, "User: " + ((info['run_as]).namef('name))], ['nobody, 1]];
    page = (info['directory_object]).build_header(headers, info, args, opts);
    if (dict_contains(args, "type") && ((args["type"]) == "interactive")) {
        i = "yes";
        page += ["<frameset rows=\"40,*,50%\" framespacing=\"0\" border=\"0\">"];
    } else {
        i = "no";
        page += ["<frameset rows=\"40,*\" framespacing=\"0\" border=\"0\">"];
    }
    page += [("<frame name=\"nav\" src=\"/desktop/nav?i=" + i) + "\" scrolling=no frameborder=\"0\">"];
    page += ["<frame name=\"content\" src=\"/motd/?inframe\" frameborder=\"0\">"];
    if (i)
        page += ["<frame name=\"login\" src=\"/desktop/interactive\" scrolling=no frameborder=\"0\">"];
    page += ["</frameset>", "<noframe>", "<body bgcolor=\"#ffffff\">"];
    page += ["You must support frames", "</body>", "</noframe>", "</html>"];
    return page;
};

public method .content_frame() {
    arg headers, info, args;
    
    return ((info['directory_object]).build_header(headers, info, args, #[['title, "User Desktop"]])) + ["Content Frame", "</body>", "</html>"];
};

public method .interactive() {
    arg headers, info, args;
    var page, user, cinfo;
    
    user = (| (headers['interface]).get_info('run_as) |);
    cinfo = ((info['browser_auth])[2]).join(" ");
    page = (info['directory_object]).build_header(headers, info, args);
    page += ["<style type=\"text/css\">"];
    page += ["BODY { margin-left: 0; margin-right: 0; margin-top: 0; margin-botton: 0; }"];
    page += ["</style>"];
    page += ["<applet CODEBASE=\"/file/CupOmud/\" code=\"CupOmud.class\""];
    page += ["height=100% width=100%"];
    page += ["alt=\"Sorry, you browser does not have JAVA enabled.\">"];
    page += ["<PARAM NAME=\"host\"           value=\"www.cold.org\">"];
    page += ["<PARAM NAME=\"port\"           VALUE=\"1138\">"];
    page += ["<PARAM NAME=\"sysname\"        VALUE=\"the Cold Dark\">"];
    page += ["<PARAM NAME=\"MCP\"            VALUE=\"yes\">"];
    page += ["<PARAM NAME=\"input_bgcolor\"  VALUE=\"#d0b0b0\">"];
    page += ["<PARAM NAME=\"input_fgcolor\"  VALUE=\"#000000\">"];
    page += ["<PARAM NAME=\"output_bgcolor\" VALUE=\"#e0e0e0\">"];
    page += ["<PARAM NAME=\"output_fgcolor\" VALUE=\"#000000\">"];
    page += [("<PARAM NAME=\"command\" VALUE=\"connect " + cinfo) + "\">"];
    
    // page += ["<PARAM NAME=\"command\"        VALUE=\"help\">"];
    page += ["<p>If your browser does not support JAVA, you can try a raw"];
    page += ["connection (not a preferred method):"];
    page += ["<p><a href=\"telnet://ice.cold.org:1138/\">telnet://ice.cold.org:1138</a>"];
    page += ["</applet>"];
    page += ["</body>"];
    return page;
};

public method .nav() {
    arg headers, info, args;
    var i, page, opts, user, s, e, links;
    
    user = (| (headers['interface]).get_info('run_as) |);
    opts = #[['title, "User Desktop"]];
    e = (| args["e"] |);
    i = (| args["i"] |);
    s = info['generate];
    page = (info['directory_object]).build_header(headers, info, args, opts);
    page += ["<style type=text/css>"];
    page += ["BODY { margin-left: 0; margin-right: 5; margin-top: 0; }"];
    page += ["</style>"];
    page += ["<table border=\"0\" width=\"100%\" cellspacing=0 cellpadding=0>"];
    page += ["<tr><td valign=top><img src=\"/file/tcd-title.gif\" width=245 height=40></td>"];
    page += ["<td valign=top width=\"100%\"><font size=\"-1\">"];
    page += ["<a target=\"content\" href=\"/motd/?inframe\">[o] Home</a> | "];
    links = [];
    if (e == "docs") {
        page += [("<a href=\"" + s) + "\">[-] Documentation</a> | "];
        links += ["<a target=\"content\" href=\"/bin/help\">ColdCore Help</a> | "];
        links += ["<a target=\"content\" href=\"/bin/describe?target=introtut_start\">Introductory Tutorial</a> | "];
        links += ["<a target=\"content\" href=\"/bin/help?node=help_coldc\">ColdC Manual</a>"];
    } else {
        page += [("<a href=\"" + s) + "?e=docs\">[+] Documentation</a> | "];
    }
    if (e == "browse") {
        page += [("<a href=\"" + s) + "\">[-] Browse</a> | "];
        links += ["<a target=\"content\" href=\"/bin/describe\">the VR World</a> |"];
        links += ["<a target=\"content\" href=\"/bin/object\">ColdC Objects</a> |"];
        links += ["<a target=\"content\" href=\"/bin/who\">Who is Online</a> |"];
        links += ["<a target=\"content\" href=\"/ar/\">Action Tracking</a>"];
    } else {
        page += [("<a href=\"" + s) + "?e=browse\">[+] Browse</a> | "];
    }
    if (e == "set") {
        page += [("<a href=\"" + s) + "\">[-] Settings</a>"];
        links += ["<a href=\"/set/set_list?target=me\" target=\"content\">My Settings</a> |"];
        links += ["<a href=\"/set/set_objlist\" target=\"content\">My Objects' Settings</a> |"];
        links += ["<xa href=\"/set/msg\" target=\"content\">My Messages</xa> | "];
        links += ["<xa href=\"/set/msg\" target=\"content\">My Objects' Messages</xa>"];
    } else {
        page += [("<a href=\"" + s) + "?e=set\">[+] Settings</a>"];
    }
    if (i == "yes")
        page += ["<a target=_top href=\"/desktop/?type=non-interactive\">[+] Non-Interactive Login</a>"];
    else
        page += ["<a target=_top href=\"/desktop/?type=interactive\">[+] Interactive Login</a>"];
    page += ["<br>"];
    if (links)
        page += ["&nbsp;=&gt;"] + links;
    page += ["</font></td>", ("<td align=right valign=top>(User:&nbsp;" + ((user.namef('name)).replace(" ", "&nbsp;"))) + ")</td></tr></table>"];
    page += ["</body>", "</html>"];
    return page;
};


new object $page_file_index: $page;

var $root manager = $page_file_index;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 864282511;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $root managed = [$page_file_index];
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];

public method .generate() {
    arg headers, info, args;
    var filename, stat, i;
    
    filename = "html" + (info['path_info]);
    stat = (| $file.fstat(filename) |);
    if ((!stat) || (substr(stat[1], 1, 1) == "4"))
        return [(headers['interface]).response(404, "Unable to find URL " + (info['path_info]))];
    i = (info['path_info]).rindex(".");
    (headers['interface]).set_ctype($mime_lib.mime_type((info['path_info]).subrange(i + 1)));
    (headers['interface]).respond_with_file(stat, filename);
    return 0;
};


new object $page_root_index: $page;

var $root manager = $page_root_index;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863765389;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $root managed = [$page_root_index];
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];

public method .generate() {
    arg headers, info, args;
    var a, r;
    
    if (dict_contains(args, "login")) {
        // setup to handle root-level 'domain' login
        if (dict_contains(info, 'run_as)) {
            r = (| args["login"] |) || "/desktop/";
            return ['redirect, r];
        } else {
            return ['auth, ['basic, $directories.get_realm()]];
        }
    }
    return ['redirect, "/motd/"];
};


new object $plain_page: $page, $note;

var $root manager = $plain_page;
var $thing gender = $gender_neuter;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863765676;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $located location = $void;
var $located obvious = 1;
var $described prose = [];
var $has_name name = ['prop, "plain_page", "plain_page"];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_text text = [];
var $root managed = [$plain_page];
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];

public method .generate() {
    arg header, info, args;
    
    return [.text()];
};


new object $page_set: $page;

var $root manager = $page_set;
var $page_set prefs = #[["www-show-line-num", "Show line numbers in methods"], ["www-show-methods", "Show methods on object displays"], ["www-show-variables", "Show variables on object displays"], ["www-show-descriptions", "Show descriptions on object displays"]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 999486860;
var $dmi_data descriptions = #[['submit_new, #[['args, #[["www-show-descriptions", [[], []]], ["www-show-line-num", [[], []]], ["www-show-methods", [[], []]], ["www-show-variables", [[], []]]]]]]];
var $root inited = 1;
var $root managed = [$page_set];
var $root credit = ["Brandon Gillespie, 2001"];
var $page_set descs = #[];

public method .config() {
    arg header, info, args;
    var text, user, value, boolean, pref;
    
    user = info['run_as];
    text = .build_header(header, info, args, #[['title, "Configure Web Preferences"]]);
    text += ["<form action=\"/desktop/web_prefs/submit_new\" method=\"post\">"];
    text += ["<table><tr><th>Preference</th><th>Yes</th><th>No</th></tr>"];
    for pref in (prefs) {
        value = user.get_setting(pref[2], $www_preferences);
        text += [((("<tr><td>" + (pref[1])) + "</td>") + (map boolean in ([1, 0]) to (((((("<td><input type=\"radio\" name=\"" + (pref[2])) + "\" value=\"") + (boolean ? "1" : "0")) + "\" ") + ((value == boolean) ? "checked" : "")) + "></td>").join(""))) + "</tr>"];
    }
    text += ["</table>"];
    text += ["<input type=submit name=\"Submit new preferences\"><input type=reset>"];
    text += ["</form>", @.build_footer(header, info, args)];
    return [text];
};

public method .submit_new() {
    arg header, info, args;
    var pref, user;
    
    user = info['run_as];
    for pref in (prefs.slice(2))
        user.set_www_preferences(pref, args[pref]);
    return ['redirect, @header["Referer"]];
};

public method .set_change() {
    arg header, info, args;
    var page, setting, target, set, def, v, i, dv;
    
    (> .perms(info['run_as], sender()) <);
    set = (| args["set"] |);
    if (!set)
        return $http_interface.response(404, "Invalid Setting");
    page = .build_header(header, info, args);
    [target, setting] = split(set, ":");
    target = lookup(tosym(target));
    page += [((("<b>Changing Setting for <a href=\"set_list?target=" + target) + "\">") + (target.namef('name))) + "</a></b>"];
    page += ["<form action=\"set_change_submit\" method=POST name=n>"];
    page += ["<p><table border=0>"];
    if (dict_contains(descs, (def + ":") + setting))
        page += [("<tr><td></td><td>" + (descs[(def + ":") + setting])) + "</td></tr>"];
    def = target.setting_definer(setting);
    dv = (target.format_setting(setting, def, target.get_setting(setting, def))).html_escape();
    if (dict_contains(args, "value"))
        v = args["value"];
    else
        v = dv;
    page += ["<script language=\"Javascript\">"];
    page += ["function x_revert() {", ("document.n[\"" + set) + "\"].value ="];
    page += [("\"" + dv) + "\"; }", "</script>"];
    page += [((("<tr><td><p>@set&nbsp;<b>" + target) + ":") + setting) + "=</b></td>"];
    page += [((("<td><input name=\"" + set) + "\" value=\"") + v) + "\" size=40>"];
    page += ["</td></tr><tr><td></td><td>"];
    page += ["<b><input type=submit value=\"Change\"></b>"];
    page += [" <input type=button value=\"Revert\" onClick=\"x_revert()\">"];
    if (dict_contains(args, "msg"))
        page += [("<p><font color=\"#990000\">" + (args["msg"])) + "</font>"];
    page += ["</td></tr></table>", "</form>"];
    return page;
};

public method .set_list() {
    arg header, info, args;
    var text, opts, def, target, ts, s, v, e, g, line, sc;
    
    (> .perms(info['run_as], sender()) <);
    opts = #[['title, "Configure Web Preferences"]];
    text = .build_header(header, info, args, opts);
    target = (| args["target"] |);
    if (target == "me")
        target = sender();
    else if ((!target) || (!(target = (| $object_lib.to_dbref(target) |))))
        return $http_interface.response(404, "Object not found.");
    sc = ((info['generate]) + "?target=") + target;
    text += [((("<b><a href=\"" + sc) + "\">Settings for ") + (target.namef('name))) + "</a></b>"];
    text += [(" (@set " + target) + ":)<p>"];
    text += ["<p><i>Select setting group to see settings, or"];
    text += [("<a href=\"" + sc) + "&e=all\">expand all groups</a></i><p>"];
    text += ["<style type=\"text/css\">"];
    text += ["td { font-size: 10pt; }", "th { font-size: 10pt; }"];
    text += ["</style>"];
    text += ["<table border=0>"];
    ts = target.objname();
    e = (| args["e"] |);
    if (e == "all")
        e = -1;
    g = "none";
    for s in (sender().format_settings(target, 1)) {
        if (type(s) == 'string) {
            s = strsed(s, "[: ]+$", "");
            line = "<tr><td colspan=3>";
            if ((e == (-1)) || (e == s)) {
                line += ("<a href=\"" + sc) + "\">[-]&nbsp;";
                g = 1;
            } else {
                line += ((("<a href=\"" + sc) + "&e=") + s) + "\">[+]&nbsp;";
                g = 0;
            }
            s = lookup(tosym(substr(s, 2)));
            line += (s.namef('ref)) + ":</td></tr>";
            text += [line];
        } else if ((e == (-1)) || g) {
            [s, v] = regexp(s[1], "^([^=]+)= *(.*)$");
            s = s.trim();
            text += [((((("<tr><td width=5>&nbsp;&nbsp;&nbsp;</td><td><a href=\"set_change?set=" + ts) + ":") + s) + "\">") + s) + "</a>=</td>"];
            text += [("<td>" + v) + "</td>"];
        }
    }
    text += ["</table>"];
    return text;
};

public method .set_objlist() {
    arg header, info, args;
    var o, list, page, opts, t, user, e, n, c;
    
    (> .perms(info['run_as], sender()) <);
    user = info['run_as];
    opts = #[['title, "Configure Web Preferences"]];
    page = .build_header(header, info, args, opts);
    page += ["<style type=\"text/css\">"];
    page += ["td { font-size: 10pt; }", "th { font-size: 10pt; }"];
    page += ["</style>"];
    c = $cml_lib;
    e = (| args["e"] |);
    if (e == "m") {
        t = user.as_this_run(user, 'audit_cmd__manages, [user, 'expand, 'set]);
    } else {
        n = ("[+] Managed by " + (user.namef('ref))) + ":";
        t = [c.fmt_tr(c.fmt_td(c.fmt_href("set_objlist?e=m", n), ["colspan", "3"]))];
    }
    if (e == "w") {
        t += user.as_this_run(user, 'audit_cmd__writes, [user, 'expand, 'set]);
    } else {
        n = ("[+] Writable for " + (user.namef('ref))) + ":";
        t += [c.fmt_tr(c.fmt_td(c.fmt_href("set_objlist?e=w", n), ["colspan", "3"]))];
    }
    if (e == "t") {
        t += user.as_this_run(user, 'audit_cmd__trusted, [user, 'expand, 'set]);
    } else {
        n = ("[+] Objects which trust " + (user.namef('ref))) + ":";
        t += [c.fmt_tr(c.fmt_td(c.fmt_href("set_objlist?e=t", n), ["colspan", "3"]))];
    }
    page += [$ctext_frob.new_with([$cml_lib.fmt_table("60%,13%,27%", t)])];
    return page;
};

public method .set_change_submit() {
    arg header, info, args;
    var page, setting, target, set, def, v, i;
    
    (> .perms(info['run_as], sender()) <);
    if (((args.keys()).length()) > 1)
        return $http_interface.response(404, "Too Many Settings...");
    set = (args.keys())[1];
    [target, setting] = split(set, ":");
    target = lookup(tosym(target));
    def = target.setting_definer(setting);
    catch any
        sender().as_this_run(target, 'set_setting, [setting, def, args[set]]);
    with
        return ['redirect, (((("set_change?set=" + set) + "&msg=") + ($http.encode((traceback()[1])[2]))) + "&value=") + ($http.encode(args[set]))];
    return ['redirect, ("set_change?set=" + set) + "&msg=Setting+Changed"];
};


new object $page_ar: $page;

var $root manager = $page_ar;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 932229052;
var $dmi_data descriptions = #[['change, #[['args, #[]], ['auth, [$security_lib, 'check_userdb_with_password, []]]]]];
var $root inited = 1;
var $root trusted_by = [$no_one];
var $root managed = [$page_ar];

public method .list() {
    arg header, info, args;
    var body, groups, g, list, reports, r, all;
    
    body = .build_header(header, info, args);
    if (dict_contains(args, "group")) {
        //// I do not see any great value in allowing all groups,
        //// but will leave the code here incase somebody whines
        // g = toint(args["group"]);
        // if (g == 0) {
        //     reports = #[];
        //     for g in (setremove($argroup.children(), $dismissed_problems)) {
        //         list = filter r in (g.requests()) where (!r[2][2]);
        //         if (list)
        //             reports = dict_add(reports, g, list);
        //     }
        //     body += ["<h1>ALL Un-Resolved Action Requests</h1>"];
        //     all = 1;
        // }
        g = (| $object_lib.to_dbref(args["group"]) |);
        if ((!g) || (!(g.is($argroup))))
            return ._error("<h1>Invalid Group</h1>");
        reports = filter r in (g.requests()) where (!((r[2])[2]));
        reports = #[[g, reports]];
        body += [("<h1>Un-Resolved " + (g.name())) + " Action Requests</h1>"];
        if (reports) {
            body = strings_to_buf(body);
            body += str_to_buf("<table border=0><tr><td>\n");
            body += $parse_lib.filter_ctext(._list(reports, all), #[['formatter, $html_format], ["viewer", $no_one]]);
            body += str_to_buf("</td></tr></table>\n");
            body += strings_to_buf(.build_footer(header, info, args));
            return body;
        }
    } else {
        groups = $argroup.children();
        body += ["<h1>Select Action Request Group</h1>", "<ul>"];
        for g in (groups)
            body += [("<li><a href=\"/ar/list?group=" + g) + "\">", (g.name()) + "</a>"];
        body += ["</ul>"];
    }
    return body + (.build_footer(header, info, args));
};

public method ._list() {
    arg reports, full;
    var group, report, r, id, date, summary, resolved, str, out, tr, n, tot, bg;
    
    out = [];
    for group in (dict_keys(reports)) {
        refresh();
        for report in (reports[group]) {
            refresh();
            id = report[1];
            [r, resolved, date, summary] = report[2];
            date = $time.format("%d-%h-%Y", date);
            if (tot % 2)
                bg = [["bgcolor", "#dddddd"]];
            else
                bg = [];
            id = $cml_lib.fmt_href("/ar/view?r=" + id, "#" + id);
            id = $cml_lib.fmt_td(id, @bg, ["align", "right"]);
            date = (<$format, ["font", [["size", 1]], [date], 'do_font]>);
            date = $cml_lib.fmt_td(date, @bg);
            summary = $cml_lib.fmt_td(summary || ($cml_lib.fmt_br()), @bg);
            if (full) {
                n = $cml_lib.fmt_td(group.name(), @bg);
                tr = $cml_lib.fmt_tr(id, n, date, summary);
            } else {
                tr = $cml_lib.fmt_tr(id, date, summary);
            }
            tot++;
            out += [tr];
        }
    }
    out += [$cml_lib.fmt_subj(tot + " total", 3)];
    return $ctext_frob.new_with(out);
};

public method .view() {
    arg h, i, args;
    var body, rep, g;
    
    body = .build_header(h, i, args);
    if (!(rep = ._get_report((| args["r"] |))))
        return (body + ["<H1>Invalid Request</H1>"]) + (.build_footer(h, i, args));
    body = strings_to_buf(body);
    body += $parse_lib.filter_ctext(rep.format(1), #[['formatter, $html_format], ["viewer", $no_one]]);
    body += strings_to_buf(.build_footer(h, i, args));
    return body;
};

public method ._get_report() {
    arg report;
    var g;
    
    if (!report)
        return 0;
    report = toint(report);
    for g in ($argroup.children()) {
        if (dict_contains(g.requests(), report))
            return ((g.requests())[report])[1];
    }
    return 0;
};

public method .generate() {
    arg @args;
    
    return .list(@args);
};

public method .change() {
    arg h, i, args;
    var dbref, req, g, p, c, out, r;
    
    if (!(req = ._get_report((| args["id"] |))))
        return ._error(["<H1>Invalid Request</H1>"], h, i, args);
    if (dict_contains(args, "group")) {
        if (!(dbref = (| $object_lib.to_dbref(args["group"]) |)))
            return ._error(["<H1>Invalid Dbref</H1>"], h, i, args);
        if (!(dbref.is($argroup)))
            return ._error(["<H1>Invalid Group</H1>"], h, i, args);
        if (!(req.trusts(sender())))
            return ._error(["<H1>You are not allowed, sorry.</H1>"], h, i, args);
        req.change_group(dbref);
        return ['redirect, "/ar/view?r=" + (req.id())];
    } else if (dict_contains(args, "comment")) {
        c = args["comment"];
    
        // ugh -- need to fix
        c = strsub(c, $http.decode("%0d"), "");
        c = c.trim();
        r = (| args["resolv"] |) == "yes";
        if (r && (req.resolved_on()))
            return ._error(["<H1>Already resolved.</H1>"], h, i, args);
        if (c) {
            if (dict_contains(args, "pre"))
                c = [$cml_lib.fmt_quote(strsub(c, $http.decode("%0a"), "\n"))];
            else
                c = [strsub(c, $http.decode("%0a"), " ")];
            req.add_comment(c, sender().namef('ref));
        }
        if (r) {
            if (!(req.trusts(sender())))
                return ._error(["<H1>You are not allowed, sorry.</H1>"], h, i, args);
            req.resolve(sender());
            if ((| args["mailmsg"] |) == "yes")
                ._mailmsg(req, sender(), 1);
            return ['redirect, "/ar/list?group=" + (req.group())];
        }
        return ['redirect, "/ar/view?r=" + (req.id())];
    } else {
        return ._error(["<H1>No change specified</H1>"], h, i, args);
    }
};

private method ._error() {
    arg msg, @args;
    
    return ((.build_header(@args)) + msg) + (.build_footer(@args));
};

private method ._mailmsg() {
    arg req, from, @resolved;
    var recip, text, id, fmt, c, cmts, subj, msg;
    
    id = req.id();
    recip = [$mail_list_bugs];
    if (resolved)
        subj = (("AR #" + id) + " RESOLVED: ") + (req.summary());
    else
        subj = (("Comment on AR #" + id) + ": ") + (req.summary());
    text = ["Reported By: " + (req.submitted_by())];
    text += ["Reported On: " + ($time.format("%d-%h-%Y", req.submitted_on()))];
    text += [""];
    text += ((req.text()).mmap('wrap_lines, 70, "> ", 1)).flatten();
    cmts = req.comments();
    msg = (cmts.last())[3];
    cmts = sublist(cmts, 1, listlen(cmts) - 1);
    for c in (cmts) {
        fmt = "On " + ($time.format("%d-%h-%Y ", c[1]));
        fmt += (c[2]) + " Comments:";
        text += ["", fmt] + (((c[3]).mmap('wrap_lines, 70, "> ", 1)).flatten());
    }
    text += [""] + msg;
    $no_one.mail_as(from.namef('ref), [], subj, text, @recip);
};


new object $motd: $page;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $motd server_name = "ColdCore";
var $motd notes = ["** Welcome to your new ColdCore, use the command 'help' to **", "** learn more about how to connect with the 'create' command **"];
var $motd server_title = "Virtual Community Server";
var $motd connect_help = ["Connection Help", "===============", "", "  Connecting as a guest:  'guest <name> <email>'", "                Example:  'guest John Doe johndoe@domain.com'", "", "   Connecting as a user:  'connect <name> <password>'", "                Example:  'connect John Doe mypassword'", "", " Quitting (this screen):  '@quit'   or   'quit'", "", "Connected Users Listing:  '@who'", "", "        Creating a user:  'create <name> <password> <email@host>'", "                Example:  'create John Doe mypassword johndoe@domain.com'"];
var $motd server_url = "http://none:1180/";
var $root manager = $motd;
var $root managed = [$motd];
var $root defined_settings = #[["server-name", #[['get, ['get_server_name_setting]], ['set, ['set_server_name_setting]]]], ["server-title", #[['get, ['get_server_title_setting]], ['set, ['set_server_title_setting]]]], ["login-sequence", #[['parse, ['is_type, 'list]]]]];
var $root settings = #[["login-sequence", ['default]]];
var $root help_node = $help_obj_motd;

public method .build() {
    arg @args;
    var output, out, line;
    
    output = [];
    if (!args)
        args = ['long, 'quote];
    if ((args[1]) == 'default)
        args = ['name, "", 'title, "", "", 'quote, "", 'notes, 'admins, "", 'connected, 'core_version, 'driver_version, 'help, ""];
    while (args) {
        if (type(args[1]) == 'string) {
            output += [""];
        } else {
            switch (args[1]) {
                case 'long:
                    args = ['title, 'long_name] + sublist(args, 2);
                    continue;
                case 'short:
                    args = ['title, 'name] + sublist(args, 2);
                    continue;
                case 'title:
                    output += [server_title.center(79)];
                case 'name:
                    output += [(("+ " + server_name) + " +").center(79)];
                case 'notes:
                    output += (notes.center_lines(79)) + [""];
                case 'quote:
                    output += ($code_lib.random_quote()).center_lines(79);
                case 'admins:
                    out = ($list.to_english($list.mmap($sys.admins(), 'name))).wrap_lines(50);
                    line = out[1];
                    output += (["Administrators: " + line] + delete(out, 1)).mmap('center, 79);
                case 'connected:
                    out = "Currently Connected users: ";
                    out += tostr(($user_db.connected()).length());
                    out = out.center(79);
                    output += [out];
                case 'version:
                    args = ['driver_version, 'core_version] + sublist(args, 2);
                    continue;
                case 'driver_version:
                    out = "Driver: " + ($sys.server_info('driver_version, 'long));
                    output += [out.center(79)];
                case 'core_version:
                    out = "Core: " + ($sys.server_info('core_version, 'long));
                    output += [out.center(79)];
                case 'help:
                    out = " ** Use 'Help' for a list of commands**";
                    output += [out.center(79)];
            }
        }
        args = delete(args, 1);
    }
    return output;
};

public method .set_motd() {
    arg what, value;
    
    (> .perms(sender()) <);
    if (!(what in (.variables())))
        throw(~motd, (toliteral(what) + " is not a valid motd variable, try one of: ") + toliteral(.variables()));
    if (!(type(value) in ['string, 'list]))
        throw(~motd, "Value must be sent as a string or a list of strings.");
    set_var(what, value);
};

public method .generate() {
    arg @args;
    var page, l;
    
    // this is your home page, change it as you whim may direct you
    page = $directories.build_header(#[], #[], #[]);
    if ((l = $directories.get_server_name_img()))
        page += [l];
    else
        page += [("<h1>" + server_name) + "</h1>"];
    page += (["<p align=center><i><tt>"] + ($code_lib.random_quote())) + ["</tt></i>"];
    if (server_title)
        page += [("<h3>" + server_title) + "</h3>"];
    if (notes) {
        page += ["<table align=center border=0><tr><td bgcolor=\"#cccccc\">"];
        page += [(notes.prefix("<br>")).affix("<br>")];
        page += ["</td></tr></table>"];
    }
    page += ["<p><b>Things to do from here:</b>"];
    page += ["<ul>"];
    page += ["<li>Login <a href=\"/file/jlogin/index.html\">Interactively</a> or "];
    page += ["<a href=\"/desktop/\">Non-Interactively</a><br>"];
    page += ["<li>See <a href=\"/bin/who\">Who is Online</a><br>"];
    page += ["<li>Browse <a href=\"/bin/describe\">the VR World</a>,"];
    page += ["<a href=\"/bin/object\">ColdC Objects</a>"];
    page += [" or <a href=\"/ar\">Action Requests</a><br>"];
    page += ["<li>Read documentation: <a href=\"/bin/help\">Help Files</a>,"];
    page += [" <a href=\"/bin/describe?target=introtut_start\">Introductory Tutorial</a>"];
    page += [" or <a href=\"/bin/help?node=help_coldc\">the ColdC Manual</a>"];
    page += ["</ul>"];
    page += ["<p align=left>", "<table border=0>"];
    page += ["<tr><th valign=top align=left>Administrators:</th>"];
    page += [("<td>" + ((($sys.admins()).mmap('hname)).to_english())) + "</td></tr>"];
    page += ["<tr><th valign=top align=left>Current&nbsp;Users:</th>"];
    page += [("<td>" + ($user_db.total_connected())) + " (<a href=\"/bin/who\">Get List</a>)</td></tr>"];
    page += ["<tr><th valign=top align=left>Server Lag:</th>"];
    page += [("<td>" + ($lag_watcher.lag())) + " seconds.</td></tr>"];
    page += ["<tr><th valign=top align=left>Driver: </th>"];
    page += [("<td><a href=\"http://www.cold.org/Software/Genesis/\">Genesis</a> " + ($sys.server_info('driver_version))) + "</td></tr>"];
    page += ["<tr><th valign=top align=left>Core:</th>"];
    page += [("<td>" + ($sys.server_info('core_version, 'long))) + "</td></tr>"];
    page += ["</body>"];
    return page;
};

public method .server_name() {
    return server_name;
};

public method .server_title() {
    return server_title;
};

public method .connect_help() {
    return connect_help;
};

public method .set_connect_help() {
    arg text;
    
    (> .perms(sender(), 'manager) <);
    connect_help = text;
};

public method .server_url() {
    return ((("http://" + ($dns.hostname(""))) + ":") + ($http_daemon.current_port())) + "/";
};

root method .core_motd() {
    (| .del_method('generate) |);
    (| .rename_method('core_generate, 'generate) |);
    server_url = "http://none:1180/";
    server_name = "ColdCore";
    server_title = "Virtual Community Server";
    notes = ["** Welcome to your new ColdCore, use the command 'help' to **", "** learn more about how to connect with the 'create' command **"];
};

public method .get_server_title_setting() {
    arg @args;
    
    return server_title;
};

protected method .set_server_title_setting() {
    arg name, definer, value, @args;
    
    server_title = value;
};

public method .get_server_name_setting() {
    arg @args;
    
    return server_name;
};

protected method .set_server_name_setting() {
    arg name, definer, value, @args;
    
    server_name = value;
};

public method .set_notes() {
    arg notes;
    
    (> .perms(sender()) <);
    if (type(notes) != 'list)
        throw(~type, "notes must be a list of strings");
    set_var('notes, notes);
};

protected method .parse_default_css() {
    arg file;
    
    if (file) {
        //catch ~file {
        (> $file.fstat("html/" + file) <);
    
        // } with {
    }
    return file;
};

public method .get_default_css() {
    arg @args;
    
    return default_css;
};

protected method .set_default_css() {
    arg name, definer, value, @args;
    
    // called by @set
    default_css = value;
};

public method .get_server_name_img() {
    arg @args;
    
    return server_name_img;
};

public method .set_server_name_img() {
    arg name, definer, value, @args;
    
    server_name_img = value;
};

public method .notes() {
    return notes;
};


new object $frob: $core;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root manager = $frob;
var $root managed = [$frob];

public method .unparse() {
    arg rep;
    
    return ((("<" + this()) + ", ") + rep) + ">";
};

public method .new() {
    return (<this(), #[]>);
};

public method .to_frob() {
    arg value;
    
    // this differs from .new in it's application
    return (<this(), value>);
};

frob method .value(): nooverride {
    arg value;
    
    return value;
};

frob method .has_ancestor() {
    arg this, ancestor;
    
    return (> pass(ancestor) <);
};

frob method .is() {
    arg this, ancestor;
    
    return (> pass(ancestor) <);
};

public method .new_with() {
    arg value;
    
    return (<this(), value>);
};

frob method .destroy() {
    arg this;
    
    throw(~perm, "You cannot destroy a frob, try 'discard'");
};


new object $thing_frob: $frob, $thing;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core, 'frob];
var $located location = $void;
var $located obvious = 1;
var $described prose = [];
var $has_name name = ['uniq, "Thing Frob", "the Thing Frob"];
var $root manager = $thing_frob;
var $root managed = [$thing_frob];
var $thing gender = $gender_neuter;

frob method .match_name() {
    arg this, str;
    var t, m;
    
    if (!str)
        return 0;
    if ((m = match_begin((this['name])[2], str)))
        return 1;
    if (this.contains('name_templates)) {
        for t in (this['name_templates]) {
            if ((m = match_template(str, t)))
                return 1;
        }
    }
    return 0;
};

frob method .location() {
    arg this;
    
    return (| this['location] |) || $nowhere;
};

frob method .did_move() {
    arg this;
    
    return (<this(), this>);
};

frob method .is_obvious_to() {
    arg this, whom;
    
    return 1;
};

frob method .will_move() {
    arg this, mover, place;
    
    if (!(> .try_lock(this, mover) <))
        throw(~locked, (((((this['name])[3]).capitalize()) + " is locked to ") + ((this['lock]).lock_name('thing))) + ".");
    return 1;
};

frob method .prose() {
    arg this, @no_default;
    
    return (| this['prose] |) || (no_default ? 0 : "You see nothing special");
};

frob method .namef() {
    arg dict, @args;
    
    return .name(dict);
};

protected method .change_data() {
    arg this, what, new, @remove;
    var l;
    
    l = this['location];
    if (valid(l)) {
        if ((<this(), this>) in (l.contents()))
            (this['location]).del_frob_from_contents((<this(), this>));
    
        //    else if (what != 'location)
        //        throw(~perm, "Bogus location information in frob.");
    }
    if (remove)
        this = this.del(what);
    else
        this = this.add(what, new);
    if (valid(this['location]))
        (this['location]).add_frob_to_contents((<this(), this>));
    return (<this(), this>);
};

frob method .manager() {
    arg this;
    
    return this['manager];
};

frob method .description() {
    arg this, flags;
    var out;
    
    out = (<$ctext_frob, [[(<$format, ["subj", [], [.name(this)], 'do_subj]>)], #[]]>);
    if ((| flags['prose] |))
        return [out, .prose(this)];
    return [out];
};

frob method .name_templates() {
    arg this;
    
    return (| this['name_templates] |) || [];
};

frob method .get_description(): nooverride {
    arg this, @dflags;
    var flags, f;
    
    flags = #[['prose, 1], ['actor, sender()]];
    if (dflags && (type(dflags[1]) == 'dictionary)) {
        dflags = dflags[1];
        for f in (dflags.keys())
            flags = dict_add(flags, f, dflags[f]);
    }
    return .description(this, flags);
};

frob method .all_remote_commands() {
    arg this;
    
    return pass();
};

frob method .remote_commands() {
    arg this;
    
    return pass();
};

frob method .set_prose() {
    arg this, new;
    
    return .change_data(this, 'prose, new);
};

frob method .set_name() {
    arg this, new, @args;
    var type;
    
    if (!new)
        return;
    [(type ?= 'normal)] = args;
    (> $code_lib.valid_name(new, type) <);
    switch (type) {
        case 'prop:
            new = [type, new, new];
        case 'uniq:
            new = [type, new, "the " + new];
        case 'normal:
            new = [type, new, ((new.a_or_an()) + " ") + new];
        default:
            throw(~invarg, "Type must be one of: 'prop, 'normal or 'uniq.");
    }
    return .change_data(this, 'name, new);
};

public method .new() {
    var location;
    
    if (sender().is($location))
        location = sender();
    else if (sender().is($located))
        location = sender().location();
    else
        location = $nowhere;
    return (<this(), #[['prose, []], ['location, location], ['manager, sender()], ['name, .name('literal)]]>);
};

frob method .del_name_template() {
    arg this, template;
    var new;
    
    new = setremove(.name_templates(this), template);
    return .change_data(this, 'name_templates, new);
};

frob method .name() {
    arg dict, @args;
    var name;
    
    name = dict['name];
    if (!name)
        return tostr(this());
    if (!args)
        return name[3];
    switch (args[1]) {
        case 'type:
            return name[1];
        case 'noarticle:
            return name[2];
        default:
            return name;
    }
};

frob method .add_name_template() {
    arg this, template;
    var new;
    
    new = setadd(.name_templates(this), template);
    return .change_data(this, 'name_templates, new);
};

frob method .get_command_info() {
    arg this, @args;
    
    return pass(@args);
};

frob method .discard() {
    arg data;
    
    //// just allow anybody to discard for now..
    //  if (data['manager] != sender())
    //      throw(~perm, "You are not the manager of " + .name(data));
    (data['location]).del_frob_from_contents((<this(), data>));
};

frob method .move_to() {
    arg data, place;
    var location;
    
    if (!(place.has_ancestor($location)))
        throw(~type, "Argument is not a location.");
    location = data['location];
    if (!valid(location))
        location = $nowhere;
    (> .will_move(data, sender(), place) <);
    return .change_data(data, 'location, place);
};

frob method .perms() {
    arg this, what, @args;
    
    return (what == (this['manager])) || (> (this['location]).perms(what, @args) <);
};

frob method .visibility() {
    arg this, @args;
    
    return (| this['visibility] |) || 0;
};

public method .new_with() {
    arg @args;
    var name, prose, data, new;
    
    name = (listlen(args) > 0) && (args[1]);
    prose = (listlen(args) > 1) && (args[2]);
    new = .new();
    if (prose)
        new = new.set_prose(prose);
    if (name)
        new = new.set_name(name);
    return new;
};

frob method .configure() {
    arg this, set;
    var p, end, ctext, s, still, type;
    
    (> .perms(this, sender()) <);
    s = sender();
    still = ("Do you still want to describe " + (.name(this))) + "? [no] ";
    if (!(set.contains('described_prose))) {
        while (!end) {
            if (.is(this, $path))
                type = "exit ";
            else
                type = "";
            p = s.read((("Describe " + type) + (.name(this))) + ", Enter \".\" to finish or \"@abort\" to abort description.");
            if (p == 'aborted) {
                end = !(s.prompt_yesno(still, 0));
            } else {
                catch any {
                    ctext = (> $compiler.compile_cml(p) <);
                    s.tell(["You submitted the following description:", ""]);
                    s.tell(ctext);
                    s.tell("");
                    if (!(end = s.prompt_yesno("Keep this description? [yes] ")))
                        ctext = 0;
                } with {
                    s.tell(["The following CML compiler error occurred:", "  ", (traceback()[1])[2]]);
                    end = !(s.prompt_yesno(still, 0));
                }
            }
        }
        if (ctext)
            this = (.set_prose(this, ctext)).value();
        set = set.add('described_prose, 1);
    }
    return [this, set];
};

frob method .set_visibility() {
    arg this, name, definer, value;
    
    return .change_data(this, 'visibility, value);
};

frob method .get_msg(): nooverride {
    arg this, name, definer;
    
    return dict_union(definer.get_default_msg(name), (| (this['msgs])[name] |) || #[]);
};

frob method .eval_message() {
    arg this, name, definer, vars;
    var eval, msg;
    
    eval = (| definer.get_msg_attr(name, 'evaluator) |) || $bs_eval;
    msg = $message_frob.new_with(.get_msg(this, name, definer));
    vars = dict_add(vars, 'evaluator, eval);
    msg = msg.set_vars(vars);
    vars = dict_add(vars, 'time, 'pre);
    return msg.eval_ctext(vars);
};

frob method .set_msg(): nooverride {
    arg this, name, branch, definer, value;
    var compiler, branches, msg, definer, msgs;
    
    (> .perms(this, sender()) <);
    compiler = (| definer.get_msg_attr(name, 'compiler) |) || $compiler;
    value = (> compiler.compile_cml(value) <);
    branch ?= "general";
    if (!(branch in (definer.get_msg_attr(name, 'branches))))
        throw(~badbranch, ((("Message branch \"" + name) + ".") + branch) + "\" is not defined.");
    if (dict_contains(this, 'msgs))
        msgs = this['msgs];
    else
        msgs = #[];
    msg = dict_add((| msgs[name] |) || #[], branch, value);
    msgs = dict_add(msgs, name, msg);
    return .change_data(this, 'msgs, msgs);
};

frob method .clear_msg(): nooverride {
    arg this, name, @branches;
    var messages, branch, msg;
    
    (caller() != definer()) && (> .perms(this, sender()) <);
    if (dict_contains(this, 'msgs))
        messages = this['msgs];
    else
        messages = #[];
    if (!dict_contains(messages, name))
        return;
    if (!branches) {
        messages = dict_del(messages, name);
    } else {
        msg = messages[name];
        for branch in (branches) {
            if (dict_contains(msg, branch))
                msg = dict_del(msg, branch);
        }
        if (!msg)
            messages = dict_del(messages, name);
    }
    if (!messages)
        return .change_data(this, 'msgs, 0, 'remove);
    else
        return .change_data(this, 'msgs, messages);
};

frob method .all_msgs(): nooverride {
    arg this;
    
    if (dict_contains(this, 'msgs))
        return pass(this['msgs]);
    return pass();
};

frob method .msg_definer(): nooverride {
    arg this, name;
    
    return pass(name);
};

frob method .get_setting(): nooverride {
    arg this, name, definer;
    var i, settings;
    
    i = definer.setting_info(name);
    if (dict_contains(i, 'access))
        (> .((i['access])[1])(this, name, sender(), caller(), @sublist(i['access], 2.0)) <);
    if (dict_contains(i, 'get))
        return (> .((i['get])[1])(this, name, definer, @sublist(i['get], 2)) <);
    if ((!dict_contains(this, 'settings)) || (!dict_contains(this['settings], name)))
        return (> pass(name, definer) <);
    return (this['settings])[name];
};

frob method .set_setting(): nooverride {
    arg this, name, definer, value;
    var i, args, settings;
    
    (> .perms(this, sender()) <);
    i = (> definer.setting_info(name) <);
    if (dict_contains(i, 'parse)) {
        args = sublist(i['parse], 2);
        catch ~methodnf
            value = (> .((i['parse])[1])(value, @args) <);
        with
            value = (> $settings.((i['parse])[1])(value, @args) <);
    }
    if (dict_contains(i, 'set)) {
        return (> .((i['set])[1])(this, name, definer, value, @sublist(i['set], 2)) <);
    } else {
        settings = dict_add((| this['settings] |) || #[], name, value);
        return .change_data(this, 'settings, settings);
    }
};

frob method .clear_setting(): nooverride {
    arg this, name, definer;
    var info, args, settings;
    
    (caller() == definer()) || (> .perms(this, sender()) <);
    info = (> definer.setting_info(name) <);
    if (dict_contains(info, 'clear)) {
        args = sublist(info['clear], 2);
        return (> .((info['clear])[1])(this, name) <);
    } else if (dict_contains(this, 'settings) && dict_contains(this['settings], name)) {
        settings = dict_del(settings, name);
        if (!settings)
            return .change_data(this, 'settings, 0, 'remove);
        else
            return .change_data(this, 'settings, settings);
    }
};

frob method .all_defined_settings(): nooverride {
    arg this;
    
    (> .perms(this, sender()) <);
    return ._all_defined_settings();
};

frob method .setting_definer(): nooverride {
    arg this, name;
    
    return pass(name);
};

frob method .format_setting(): nooverride {
    arg this, name, definer, value;
    var i, args;
    
    return pass(name, definer, value);
};

frob method .set_gender(): nooverride {
    arg name, definer, value;
    
    throw(~perm, "You cannot set the gender on frobs, sorry.");
};

public method .try_lock() {
    arg this, @args;
    
    return (| this['lock] |) ? ((this['lock]).try(@args)) : 1;
};

frob method .local_commands() {
    arg this;
    
    return pass();
};

frob method .shortcuts() {
    arg this;
    
    return pass();
};

frob method .all_local_commands() {
    arg this;
    
    return pass();
};

frob method .all_shortcuts() {
    arg this;
    
    return pass();
};

frob method .set_lock() {
    arg this, name, definer, value;
    
    if (class(value) == $true_lock_frob)
        return .change_data(this, 'lock, 0, 'remove);
    else
        return .change_data(this, 'lock, value);
};

frob method .get_lock() {
    arg this, name, definer;
    
    return (| this['lock] |) || (<$true_lock_frob, []>);
};

frob method .writers(): nooverride {
    arg this, @literal;
    
    if (literal)
        return [];
    return [this['manager]];
};

frob method .is_writable_by() {
    arg this, obj;
    
    return (| obj in (.writers(this)) |) || ($sys.is_system(obj));
};

frob method .lock() {
    arg this;
    
    return this['lock];
};

frob method .msgs(): nooverride {
    arg this;
    
    return (| this['msgs] |) || #[];
};


new object $logic_frob: $frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $logic_frob;
var $root managed = [$logic_frob];
var $logic_frob token = 0;

public method .try() {
    arg @args;
    
    return 0;
};

public method .token() {
    return token;
};

public method .set_token() {
    arg new;
    
    (> .perms(sender(), 'manager) <);
    token = new;
};


new object $xor: $logic_frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $xor;
var $root managed = [$xor];
var $logic_frob token = "^";

public method .test() {
    arg xorlist, @args;
    var val, x;
    
    val = 0;
    for x in (xorlist) {
        catch ~type, ~methodnf
            val = val ? (!(x.test(@args))) : (x.test(@args));
        with
            val = val ? (!x) : x;
    }
    return val;
};

frob method .unparse() {
    arg xorlist;
    var str, x;
    
    str = "";
    for x in (xorlist) {
        catch any
            str = (str + (x.unparse())) + " XOR ";
        with
            str = (str + tostr(x)) + " XOR ";
    }
    return ("(" + (str && (str.subrange(1, (str.length()) - 4)))) + ")";
};


new object $and: $logic_frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $and;
var $root managed = [$and];
var $logic_frob token = "&&";

public method .test() {
    arg andlist, @args;
    var val, x;
    
    val = 0;
    for x in (andlist) {
        catch ~type, ~methodnf
            val = x.test(@args);
        with
            val = x;
        if (!val)
            break;
    }
    return val;
};

frob method .unparse() {
    arg andlist;
    var str, x;
    
    str = "";
    for x in (andlist) {
        catch any
            str += (x.unparse()) + " AND ";
        with
            str += x + " AND ";
    }
    return ("(" + (str && substr(str, 1, strlen(str) - 4))) + ")";
};


new object $and_lock_frob: $and;

var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $and_lock_frob;
var $root managed = [$and_lock_frob];

public method .new_lock() {
    arg lhs, rhs;
    
    if ((type(lhs) != 'frob) || (type(rhs) != 'frob))
        throw(~perm, "Arguments are not both frobs.");
    return (<this(), [lhs, rhs]>);
};

public method .try() {
    arg lock, obj;
    
    return ((lock[1]).try(obj)) && ((lock[2]).try(obj));
};

public method .lock_name() {
    arg lock, @type;
    
    [(type ?= 'literal)] = type;
    switch (type) {
        case 'literal:
            return ((("(" + ((lock[1]).lock_name(type))) + " && ") + ((lock[2]).lock_name(type))) + ")";
        default:
            return (((lock[1]).lock_name(type)) + " and ") + ((lock[2]).lock_name(type));
    }
};


new object $lock_frob: $logic_frob;

var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $lock_frob names = 0;
var $root manager = $lock_frob;
var $root managed = [$lock_frob];
var $lock_frob lock_types = [["inside", $inside_lock_frob], ["indirect", $indirect_lock_frob], ["owner", $owner_lock_frob], ["carry", $carry_lock_frob], ["parent", $parent_lock_frob], ["group", $group_lock_frob]];

public method .lock_name() {
    arg value, @type;
    
    [(type ?= 'default)] = type;
    if (type == 'literal)
        type = 'default;
    return (| names[type] |) || (names['default]);
};

public method .set_lock_name() {
    arg name;
    
    (> .perms(sender(), 'manager) <);
    lock_name = name;
};

public method .add_name() {
    arg type, name;
    
    (> .perms(sender(), 'manager) <);
    if (!names)
        names = #[];
    names = names.add(type, name);
};

public method .new_with() {
    arg str;
    
    return (> .parse(str, sender()) <);
};

public method .parse() {
    arg s, who;
    var stack, lock, n, m, obj, type, i;
    
    stack = [];
    s = " " + s;
    s = strsed(s, "&([^&])", "&&%1", "g");
    s = strsed(s, "\|([^\|])", "||%1", "g");
    s = strsub(s, " or ", " || ");
    s = strsub(s, " and ", " && ");
    s = strsub(s, " not ", " !");
    s = strsub(s, " xor ", " ^^");
    while (1) {
        // Look for valid prefixes.
        while (1) {
            (s = s.trim()) || throw(~parse, "String ends unexpectedly.");
            if ((s[1]) == "(") {
                stack = ['open, @stack];
                s = s.subrange(2);
            } else if ((s[1]) == "!") {
                if (stack && ((stack[1]) == 'not))
                    stack = stack.subrange(2);
                else
                    stack = ['not, @stack];
                s = s.subrange(2);
            } else {
                break;
            }
        }
    
        // Look for an object name or tag
        m = regexp(s, "^([^)&|]+)(.*)");
        if (!m)
            throw(~parse, "Null object obj_name.");
        s = m[2];
        lock = (m[1]).trim();
        if (!lock)
            throw(~parse, "Null object obj_name.");
    
        // try and match it, default to object type
        type = $object_lock_frob;
        for i in (lock_types) {
            if (lock.match_begin((i[1]) + ":")) {
                type = i[2];
                lock = lock.subrange(((i[1]).length()) + 2);
                break;
            }
        }
        switch (lock) {
            case "any", "true", "anybody", "yes":
                lock = $true_lock_frob.new();
            case "none", "false", "nobody", "no":
                lock = $false_lock_frob.new();
            default:
                if ((obj = (| type.parse_value(lock, who) |)))
                    lock = type.new_lock(obj);
                else
                    throw(~parse, ("Invalid lock tag \"" + lock) + "\"");
        }
        stack = [lock, @stack];
    
        // Loop until no more reduction to be done.
        while (1) {
            // Process negations, ands, ors.
            while (1) {
                if ((stack.length()) < 2)
                    break;
                if ((stack[2]) == 'not)
                    stack = [$not_lock_frob.new_lock(stack[1]), @stack.subrange(3)];
                else if ((stack[2]) == 'and)
                    stack = [$and_lock_frob.new_lock(stack[1], stack[3]), @stack.subrange(4)];
                else if ((stack[2]) == 'or)
                    stack = [$or_lock_frob.new_lock(stack[1], stack[3]), @stack.subrange(4)];
                else
                    break;
            }
    
            // Close parens, if necessary; otherwise stop.
            if ((!s) || ((s[1]) != ")"))
                break;
            while (s && ((s[1]) == ")")) {
                if (((stack.length()) < 2) || ((stack[2]) != 'open))
                    throw(~parse, "Misplaced right parenthesis.");
                stack = [stack[1], @stack.subrange(3)];
                s = (s.subrange(2)).trim();
            }
        }
    
        // Are we done?
        if (!s) {
            if ((stack.length()) > 1)
                throw(~parse, "Unmatched left parentheses.");
            return stack[1];
        }
    
        // No, we're at a conjunction.
        if ((s[1]) == "&") {
            stack = ['and, @stack];
            s = s.subrange(3);
        } else if ((s[1]) == "|") {
            stack = ['or, @stack];
            s = s.subrange(3);
        } else {
            throw(~parse, "Illegal character following right parenthesis.");
        }
    }
};

public method .parse_value() {
    arg value, who;
    
    return (> who.match_environment(value) <);
};


new object $object_lock_frob: $lock_frob;

var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $object_lock_frob;
var $root managed = [$object_lock_frob];

public method .new_lock() {
    arg obj;
    
    if (type(obj) != 'objnum)
        throw(~perm, "Argument is not a dbref.");
    return (<this(), [obj]>);
};

public method .try() {
    arg lock, obj;
    
    return ((lock[1]) == obj) || ((obj == sender()) || ($sys.is_system(obj)));
};

public method .lock_name() {
    arg value, @type;
    
    return (value[1]).name();
};

frob method .unparse() {
    arg obj;
    
    return toliteral(obj[1]);
};


new object $inside_lock_frob: $lock_frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $inside_lock_frob;
var $root managed = [$inside_lock_frob];

public method .try() {
    arg lock, obj;
    
    return ((lock[1]).contains(obj)) || ($sys.is_system(obj));
};

public method .new_lock() {
    arg obj;
    
    if (type(obj) != 'objnum)
        throw(~perm, "Argument is not a dbref.");
    return (<this(), [obj]>);
};

public method .lock_name() {
    arg value, @type;
    
    return "inside:" + ((value[1]).name());
};


new object $indirect_lock_frob: $lock_frob;

var $root manager = $indirect_lock_frob;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847067040;
var $root inited = 1;
var $root managed = [$indirect_lock_frob];

public method .new_lock() {
    arg obj;
    
    if (type(obj) != 'objnum)
        throw(~perm, "Argument is not a dbref.");
    return (<this(), [obj]>);
};

public method .try() {
    arg lock, obj;
    
    return ((lock[1]).try_indirect_lock(obj)) || ($sys.is_system(obj));
};

public method .lock_name() {
    arg value, @type;
    
    return "indirect:" + ((value[1]).name());
};


new object $owner_lock_frob: $lock_frob;

var $root manager = $owner_lock_frob;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847067045;
var $root inited = 1;
var $root managed = [$owner_lock_frob];

public method .new_lock() {
    arg obj;
    
    if (type(obj) != 'objnum)
        throw(~perm, "Argument is not a dbref.");
    return (<this(), [obj]>);
};

public method .try() {
    arg lock, obj;
    
    return ((lock[1]) in (obj.owners())) || ($sys.is_system(obj));
};

public method .lock_name() {
    arg value, @type;
    
    return "owner:" + ((value[1]).name());
};


new object $carry_lock_frob: $lock_frob;

var $root manager = $carry_lock_frob;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855862163;
var $root inited = 1;
var $root managed = [$carry_lock_frob];

public method .try() {
    arg lock, obj;
    
    lock = lock[1];
    return (lock == obj) || ((lock in (obj.contents())) || ((obj == sender()) || ($sys.is_system(obj))));
};

public method .lock_name() {
    arg value, @type;
    
    return "carry:" + ((value[1]).name());
};

public method .new_lock() {
    arg obj;
    
    if (type(obj) != 'objnum)
        throw(~perm, "Argument is not a dbref.");
    return (<this(), [obj]>);
};

public method .unparse() {
    arg rep;
    
    return "carry:" + (rep[1]);
};


new object $parent_lock_frob: $lock_frob;

var $root manager = $parent_lock_frob;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856053423;
var $root inited = 1;
var $root managed = [$parent_lock_frob];

public method .try() {
    arg lock, obj;
    
    return (obj.has_ancestor(lock[1])) || ($sys.is_system(obj));
};

public method .new_lock() {
    arg obj;
    
    if (type(obj) != 'objnum)
        throw(~perm, "Argument is not a dbref.");
    return (<this(), [obj]>);
};

public method .lock_name() {
    arg value, @type;
    
    return "parent:" + ((value[1]).name());
};


new object $group_lock_frob: $lock_frob;

var $root manager = $group_lock_frob;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 1000919162;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $root managed = [$group_lock_frob];

public method .try() {
    arg group, obj;
    
    return (group[1]).includes(obj);
};

public method .lock_name() {
    arg value, @type;
    
    return "group:" + ((value[1]).name());
};

public method .new_lock() {
    arg obj;
    
    if ((type(obj) != 'objnum) && (!(obj.is(group))))
        throw(~perm, "Argument is not a dbref or $group");
    return (<this(), [obj]>);
};

public method .unparse() {
    arg rep;
    
    return "group:" + (rep[1]);
};

public method .parse_value() {
    arg value, who;
    var groups, g;
    
    if (((value.length()) > 1) && ((value[1]) == "$")) {
        if ((g = (| $object_lib.to_dbref(value) |)))
            return g;
    }
    if ((g = $group.match_descendants(value)))
        return g;
    throw(~match, ("Unable to find group named '" + value) + "'");
};


new object $not: $logic_frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $not;
var $root managed = [$not];

public method .test() {
    arg notlist, @args;
    var val;
    
    catch ~range {
        catch ~type, ~methodnf
            return !((notlist[1]).test(@args));
        with
            return !(notlist[1]);
    } with {
        return 1;
    }
};

frob method .unparse() {
    arg notlist;
    
    catch any {
        catch ~type, ~methodnf
            return "NOT " + ((notlist[1]).unparse());
        with
            return "NOT " + tostr(notlist[1]);
    } with {
        return "";
    }
};


new object $not_lock_frob: $not;

var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $not_lock_frob;
var $root managed = [$not_lock_frob];

public method .new_lock() {
    arg lock;
    
    if (type(lock) != 'frob)
        throw(~perm, "Argument is not a lock.");
    return (<this(), [lock]>);
};

public method .try() {
    arg lock, obj;
    
    return !((lock[1]).try(obj));
};

public method .lock_name() {
    arg lock, @type;
    
    [(type ?= 'literal)] = type;
    switch (type) {
        case 'literal:
            return ("(!" + ((lock[1]).lock_name(type))) + ")";
        default:
            return "not " + ((lock[1]).lock_name(type));
    }
};


new object $or: $logic_frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $or;
var $root managed = [$or];

public method .test() {
    arg orlist, @args;
    var val, x;
    
    val = 0;
    for x in (orlist) {
        catch ~type, ~methodnf
            val = x.test(@args);
        with
            val = x;
        if (val)
            break;
    }
    return val;
};

frob method .unparse() {
    arg orlist;
    var str, x;
    
    str = "";
    for x in (orlist) {
        catch any
            str += (x.unparse()) + " OR ";
        with
            str += x + " OR ";
    }
    return ("(" + (str && substr(str, 1, strlen(str) - 4))) + ")";
};


new object $or_lock_frob: $or;

var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $or_lock_frob;
var $root managed = [$or_lock_frob];

public method .new_lock() {
    arg lhs, rhs;
    
    if ((type(lhs) != 'frob) || (type(rhs) != 'frob))
        throw(~perm, "Arguments are not both frobs.");
    return (<this(), [lhs, rhs]>);
};

public method .try() {
    arg lock, obj;
    
    return ((lock[1]).try(obj)) || ((lock[2]).try(obj));
};

public method .lock_name() {
    arg lock, @type;
    
    [(type ?= 'literal)] = type;
    switch (type) {
        case 'literal:
            return ((("(" + ((lock[1]).lock_name(type))) + " || ") + ((lock[2]).lock_name(type))) + ")";
        default:
            return (((lock[1]).lock_name(type)) + " or ") + ((lock[2]).lock_name(type));
    }
};


new object $true: $logic_frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $true;
var $root managed = [$true];

frob method .unparse() {
    arg dummy;
    
    return "yes";
};

public method .test() {
    arg @args;
    
    return 1;
};


new object $true_lock_frob: $true;

var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $true_lock_frob;
var $root managed = [$true_lock_frob];

public method .new_lock() {
    return (<this(), []>);
};

public method .try() {
    arg lock, obj;
    
    return 1;
};

public method .lock_name() {
    arg value, @type;
    
    return "yes";
};


new object $false: $logic_frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $false;
var $root managed = [$false];

frob method .unparse() {
    arg dummy;
    
    return "no";
};

public method .test() {
    arg @args;
    
    return 0;
};


new object $false_lock_frob: $false;

var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $false_lock_frob;
var $root managed = [$false_lock_frob];

public method .new_lock() {
    return (<this(), []>);
};

public method .try() {
    arg lock, obj;
    
    return 0;
};

public method .lock_name() {
    arg value, @type;
    
    return "no";
};


new object $read_parser: $frob;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $read_parser;
var $root managed = [$read_parser];

public method .parse_line() {
    arg dict, line;
    var cmd;
    
    if (!line) {
        // we have to do this as such, because of logic (shrug)
        dict = dict.add('status, 'not_done);
        return dict.add_elem('lines, line);
    } else if ((line[1]) == ".") {
        if (((line.length()) > 1) && ((line[2]) == "."))
            line = line.subrange(2);
        else if ((line.length()) == 1)
            return dict.add('status, 'done);
    
        //// No, bad Brandon, Bad, no scooby snack
        //// Decomment this if you want '>' to escape commands when reading
        //   } else if (line[1] == ">") {
        //       if (line.length() > 1 && line[2] == ">") {
        //           line = line.subrange(2);
        //       } else {
        //           dict = dict.add('command, line.subrange(2));
        //           return dict.add('status, 'pass_command);
        //       }
    } else if (line == "@abort") {
        return dict.add('status, 'abort);
    }
    dict = dict.add('status, 'not_done);
    return dict.add_elem('lines, line);
};

public method .new_with() {
    arg task_id, count;
    
    return (<this(), #[['lines, []], ['status, 'not_done], ['count, count], ['task_id, task_id]]>);
};

public method .parse() {
    arg dict, line;
    var line, result;
    
    // checks the incoming line to see if its a keeper, or a command.
    if ((dict['count]) == 'one) {
        dict = dict.add_elem('lines, line);
        return (<this(), (dict.add('status, 'done))>);
    } else {
        return (<this(), (.parse_line(dict, line))>);
    }
};

public method .status() {
    arg dict;
    
    return dict['status];
};

public method .task_id() {
    arg dict;
    
    return dict['task_id];
};

public method .lines() {
    arg dict;
    
    return dict['lines];
};

public method .command() {
    arg dict;
    
    return (| dict['command] |) || "";
};

public method .add() {
    arg dict, @args;
    
    return (<this(), ((> dict.add(@args) <))>);
};


new object $callback: $frob;

var $root manager = $callback;
var $root created_on = 799275808;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root managed = [$callback];

public method .new() {
    arg method, static_args;
    
    return (<this(), [sender(), method, static_args]>);
};

public method .exec() {
    arg self, @args;
    
    return (self[1]).(self[2])(self[3], args);
};


new object $message_frob: $frob;

var $root manager = $message_frob;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root managed = [$message_frob];

public method .add_entry() {
    arg this, key, what;
    var data;
    
    this = this.add(key, what);
    return (<this(), this>);
};

public method .del_entry() {
    arg this, key;
    
    this = this.del(key);
    return (<this(), this>);
};

public method .eval_ctext() {
    arg this, vars;
    var key, new, temp, t, list, vars, okey, keys;
    
    new = .new();
    vars = vars.add('this, sender());
    if (dict_contains(this, "general"))
        vars = vars.add("$general", "general");
    if (vars['varkeys]) {
        for temp in (vars['varkeys]) {
            okey = temp[2];
            key = ((temp[1]) + ".") + (| (vars[temp[2]]).objname() |);
            if (dict_contains(this, key)) {
                this = dict_add(this, temp[1], this[key]);
                this = dict_del(this, key);
            }
        }
        for key in (dict_keys(this)) {
            okey = "$" + key;
            if (dict_contains(vars, okey) || dict_contains(vars, key)) {
                temp = ((this[key]).set_var('this, vars['this])).eval_ctext();
                new = new.add_entry((| vars[okey] |) || (vars[key]), temp);
            }
        }
    } else {
        for key in (dict_keys(this)) {
            temp = ((this[key]).set_var('this, vars['this])).eval_ctext();
            new = new.add_entry((| vars["$" + key] |) || (vars[key]), temp);
        }
    }
    return new;
};

public method .has_entry() {
    arg this, name;
    
    return name in (this.keys());
};

public method .get_part() {
    arg this, part;
    
    return this[part];
};

public method .uncompile() {
    arg this;
    var key;
    
    return hash key in (this) to ([key[1], (key[2]).uncompile()]);
};

public method .parts() {
    arg this;
    
    return this.keys();
};

public method .message() {
    arg name, @definer;
    var a, message, mes, m;
    
    //retrieve the specified message as ctext
    if (definer)
        definer = definer[1];
    else
        definer = (._find_message_definer(name))[2];
    message = $message_frob.new();
    for a in (.ancestors()) {
        catch ~methodnf, ~messagenf
            return a.local_message(name, definer);
    }
    throw(~messagenf, "No matching message.");
};

public method .set_vars() {
    arg this, new;
    var d;
    
    return (<this(), (hash d in (this) to ([d[1], (d[2]).set_vars(new)]))>);
};

public method .format() {
    arg this, vars;
    
    return ((.to_ctext(this, vars)).append([], "br")).format();
};

public method .change_entry() {
    arg this, old, new;
    var value;
    
    value = (> this[old] <);
    this = dict_del(this, old);
    this = dict_add(this, new, value);
    return (<this(), this>);
};

public method .propagate() {
    arg self, f;
    
    return ($filtered_frob.new_with(self, sender())).propagate(f);
};

public method .to_ctext() {
    arg this, vars;
    var new;
    
    new = (| this[vars['receiver]] |) || ((| this["general"] |) || ($ctext_frob.new_with([""])));
    new = new.set_vars(vars);
    return new;
};


new object $trie: $frob;

var $root manager = $trie;
var $root help_node = $help_obj_trie;
var $root created_on = 800074237;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root managed = [$trie];
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];

public method .match_begin() {
    arg trie, key;
    var n, t;
    
    if ((trie[1]) && ((key == ((trie[1])[1])) || (((trie.length()) == 2) && match_begin((trie[1])[1], key))))
        return trie[1];
    if (!key)
        throw(~ambig, "Trie: ambiguous match.");
    if (!(n = (key[1]) in (trie[2])))
        throw(~keynf, "Trie: key not found.");
    (> (t = .match_begin(trie[n + 2], key.subrange(2))) <);
    t = t.replace(1, (key[1]) + (t[1]));
    return t;
};

public method .add() {
    arg @args;
    
    return (<$trie, (._add(@args))>);
};

public method .del() {
    arg @args;
    
    return (<$trie, (._del(@args))>);
};

public method ._add() {
    arg trie, key, @values;
    var n, word;
    
    // This still ain't working. Current problem: values get mingled
    if (trie[1]) {
        if (key == ((trie[1])[1]))
            return trie.replace(1, [key, @values]);
        word = (trie[1])[1];
        if (word) {
            if (!(n = (word[1]) in (trie[2])))
                trie = [@trie.replace(2, (trie[2]) + (word[1])), ._add([0, ""], word.subrange(2), @(trie[1]).subrange(2))];
            else
                trie = trie.replace(n + 2, ._add(trie[n + 2], word.subrange(2), @(trie[1]).subrange(2), @values));
            trie = trie.replace(1, 0);
        }
    }
    if (((!(trie[1])) && ((trie.length()) == 2)) || (!key))
        return trie.replace(1, [key, @values]);
    if (!(n = (key[1]) in (trie[2])))
        return [@trie.replace(2, (trie[2]) + (key[1])), ._add([0, ""], key.subrange(2), @values)];
    return trie.replace(n + 2, ._add(trie[n + 2], key.subrange(2), @values));
};

public method ._del() {
    arg trie, key;
    var n, t1;
    
    if ((trie[1]) && (key == ((trie[1])[1]))) {
        trie = trie.replace(1, 0);
        if (((trie.length()) == 3) && (!((trie[3])[2])))
            trie = [((trie[3])[1]).replace(1, (trie[2]) + (((trie[3])[1])[1])), ""];
        return trie;
    }
    if (!key)
        throw(~ambig, "Trie: Can't delete more than one key.");
    if (!(n = (key[1]) in (trie[2])))
        throw(~keynf, "Trie: No such key.");
    t1 = (> ._del(trie[n + 2], key.subrange(2)) <);
    if (t1 == [0, ""])
        trie = (trie.delete(n + 2)).replace(2, ((trie[2]).subrange(1, n - 1)) + ((trie[2]).subrange(n + 1)));
    else
        trie = trie.replace(n + 2, t1);
    if (((trie.length()) == 3) && ((!(trie[1])) && (!((trie[3])[2]))))
        trie = [((trie[3])[1]).replace(1, (trie[2]) + (((trie[3])[1])[1])), ""];
    return trie;
};

public method .match_exact() {
    arg trie, key;
    var n, t;
    
    if ((trie[1]) && (key == ((trie[1])[1])))
        return trie[1];
    if ((!key) || (!(n = (key[1]) in (trie[2]))))
        throw(~keynf, "Trie: key not found.");
    (> (t = .match_exact(trie[n + 2], key.subrange(2))) <);
    t = t.replace(1, (key[1]) + (t[1]));
    return t;
};

public method .keys() {
    arg trie, @prefix;
    var n, i, l;
    
    [(prefix ?= "")] = prefix;
    l = (trie[1]) ? [prefix + ((trie[1])[1])] : [];
    if (trie[2]) {
        for i in [1 .. (trie[2]).length()]
            l += .keys(trie[2 + i], prefix + ((trie[2])[i]));
        refresh();
    }
    return l;
};

public method .to_dict() {
    arg trie, @prefix;
    var n, i, dict;
    
    // This function will only convert single-valued tries (such as were
    // probably obtained from dictionaries
    [(prefix ?= "")] = prefix;
    dict = (trie[1]) ? #[[prefix + ((trie[1])[1]), (trie[1])[2]]] : #[];
    if (trie[2]) {
        for i in [1 .. (trie[2]).length()]
            dict = dict_union(dict, .to_dict(trie[2 + i], prefix + ((trie[2])[i])));
        refresh();
    }
    return dict;
};

public method .new() {
    arg @ignore;
    
    return (<this(), [0, ""]>);
};


new object $ctext_frob: $frob;

var $root manager = $ctext_frob;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837584074;
var $root inited = 1;
var $root managed = [$ctext_frob];

public method .new_with() {
    arg data, @vars;
    
    [(vars ?= #[])] = vars;
    return (<this(), [data, vars]>);
};

public method .eval_ctext() {
    arg this;
    var data, vars;
    
    vars = this[2];
    vars = dict_add(vars, 'time, 'pre);
    if (!(| vars['sender] |))
        vars = dict_add(vars, 'sender, sender());
    if (!(| vars['evaluator] |))
        vars = dict_add(vars, 'evaluator, $bs_eval);
    vars = dict_union(vars, (vars['evaluator]).init());
    return .new_with(@(vars['evaluator])._eval_ctext(this[1], vars));
};

public method .format() {
    arg this;
    var vars;
    
    vars = this[2];
    vars = dict_add(vars, 'time, 'post);
    if (!(| vars['receiver] |))
        vars = dict_add(vars, 'receiver, sender());
    if (!(| vars['evaluator] |))
        vars = dict_add(vars, 'evaluator, $bs_eval);
    if (!(| vars['formatter] |))
        vars = dict_add(vars, 'formatter, $plain_format);
    vars = dict_union(vars, (vars['formatter]).init());
    return (vars['formatter]).format(this[1], vars);
};

public method .set_var() {
    arg this, name, value;
    var vars;
    
    vars = this[2];
    vars = vars.add(name, value);
    return (<this(), [this[1], vars]>);
};

public method .get_var() {
    arg this, name;
    
    return (this[2])[name];
};

public method .vars() {
    arg this;
    
    return this[2];
};

public method ._ctext() {
    arg this;
    
    return this[1];
};

public method .set_vars() {
    arg this, new;
    var vars, key;
    
    return (<this(), [this[1], dict_union(this[2], new)]>);
    vars = this[2];
    for key in (new.keys())
        vars = dict_add(vars, key, new[key]);
    return (<this(), [this[1], vars]>);
};

public method .uncompile() {
    arg this;
    var vars;
    
    vars = this[2];
    if (!(| vars['uncompiler] |))
        vars = dict_add(vars, 'uncompiler, $uncompiler);
    vars = dict_union(vars, (vars['uncompiler]).init());
    return ((vars['uncompiler])._eval_ctext(this[1], vars))[1];
};

public method .append() {
    arg this, new, @br;
    var data, tmp, vars;
    
    data = this[1];
    vars = this[2];
    if (br) {
        switch (br[1]) {
            case "p":
                data += [(<$format, ["p", [], [], 'do_p]>)];
            case "br":
                data += [(<$format, ["br", [], [], 'do_br]>)];
            default:
                data += [$format.new_tag(br[1], [], [])];
        }
    }
    if (type(new) == 'list) {
        data += new;
    } else if ((type(new) == 'frob) && (class(new) == $ctext_frob)) {
        data += new._ctext();
        vars = dict_union(vars, new.vars());
    } else {
        data += [new];
    }
    return (<this(), [data, vars]>);
};


new object $tag: $frob;

var $root manager = $tag;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837584128;
var $root inited = 1;
var $root managed = [$tag];

public method .new_tag() {
    arg name, flags, args, method;
    var item, eflags;
    
    eflags = [];
    for item in (flags) {
        switch (type(item)) {
            case 'string:
                eflags = eflags.addkey(item, 1);
            case 'list:
                if (type(item[1]) != 'string)
                    throw(~flagerr, "Flag name must be a string.");
                eflags = eflags.addkey(item[1], item[2]);
            default:
                throw(~flagerr, "Flag must be a string or key,value pair.");
        }
    }
    return (<this(), [name, eflags, args, method]>);
};

public method .name() {
    arg self;
    
    return self[1];
};

public method .add_ctext_flag() {
    arg self, key, value;
    var eflags, uflags;
    
    eflags = (self[2]).addkey(key, value);
    self = self.replace(2, eflags);
    return (<this(), self>);
};

public method .args() {
    arg self;
    
    return self[3];
};

public method .set_args() {
    arg self, args;
    
    return (<this(), (self.replace(3, args))>);
};

public method .append_arg() {
    arg self, new;
    var args;
    
    args = (self[3]) + [new];
    return (<this(), (self.replace(3, args))>);
};

public method .method() {
    arg self;
    
    return self[4];
};

public method .ctext_flags() {
    arg self;
    
    return self[2];
};

public method .eval_flags() {
    arg this, vars;
    var flags, i, l, val, s;
    
    flags = this[2];
    l = [];
    s = sender();
    for i in (flags) {
        if (type(i[2]) != 'string) {
            [val, vars] = s._eval_ctext(i[2], vars);
            l += [[i[1], val]];
        } else {
            l += [i];
        }
    }
    return [this[1], l, this[3], this[4]];
};


new object $format: $tag;

var $root manager = $format;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837584154;
var $root inited = 1;
var $root managed = [$format];

public method .new_tag() {
    arg name, flags, args;
    
    return pass(name, flags, args, tosym("do_" + (name.strip())));
};


new object $generator: $tag;

var $root manager = $generator;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837584238;
var $root inited = 1;
var $root managed = [$generator];

public method .new_tag() {
    arg name, flags, args;
    
    return pass(name, flags, args, tosym("gen_" + (name.strip())));
};


new object $climate_frob: $frob;

var $root manager = $climate_frob;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837904716;
var $root inited = 1;
var $root managed = [$climate_frob];

public method .new_with() {
    arg attributes, seasons;
    
    return (<this(), [attributes, seasons, #[]]>);
};

public method .add_weather() {
    arg self, name, attrs, probs, message, ch_messages;
    
    return (<this(), [self[1], self[2], (self[3]).add(name, [attrs, probs, message, ch_messages])]>);
};

public method .show() {
    arg self;
    var out, seasons, attrs, weathers, x, i;
    
    attrs = self[1];
    seasons = self[2];
    weathers = self[3];
    out = [("Attributes: " + (attrs.to_english())) + ".", ("Seasons: " + (seasons.to_english())) + "."];
    for x in (weathers) {
        out += [((((" * " + (x[1])) + "> (probs) ") + (map i in [1 .. seasons.length()] to ((tostr(seasons[i]) + ":") + (((x[2])[2])[i])).join(", "))) + " (attrs) ") + (map i in [1 .. attrs.length()] to ((tostr(attrs[i]) + ":") + (((x[2])[1])[i])).join(", "))];
        out += ["   Description = " + ((((x[2])[3]).uncompile()).join())];
        if ((x[2])[4]) {
            out += ["   Change messages:"];
            for i in ((x[2])[4])
                out += ["      " + ((i.uncompile()).join())];
        }
    }
    return out;
};

public method .read_new() {
    arg user;
    var attrs, seasons, i;
    
    attrs = (> user.prompt("Weather attribute names (default:visibility severity):") <);
    if (attrs == "@abort")
        throw(~abort, "User aborted.");
    if (type(attrs) == 'symbol)
        throw(~engaged, "Already reading.");
    attrs = attrs || "visibility severity";
    attrs = (attrs.explode()).mmap('to_symbol);
    seasons = (> user.prompt("Season list (default:winter spring summer fall):") <);
    if (type(seasons) == 'symbol)
        throw(~engaged, "Already reading.");
    seasons = seasons || "winter spring summer fall";
    seasons = (seasons.explode()).mmap('to_symbol);
    return .new_with(attrs, seasons);
};

public method .del_weather() {
    arg self, weather;
    
    return (<this(), [self[1], self[2], (self[3]).del(weather)]>);
};

public method .read_weather() {
    arg self, user, weather;
    var attrs, probs, message, ch_messages, i;
    
    attrs = (> user.prompt("Attributes:") <);
    if (((self[1]).length()) != ((attrs = attrs.explode_quoted()).length()))
        throw(~parse, "Wrong number of attributes");
    attrs = map i in (attrs) to ((tostr(toint(i)) == i) ? toint(i) : i);
    probs = (> user.prompt("Seasonal probabilities [0-99]:") <);
    if (((self[2]).length()) != ((probs = probs.explode()).length()))
        throw(~parse, "Wrong number of attributes");
    probs = map i in (probs) to (toint(i));
    message = (> user.prompt("Weather description:") <);
    (> (message = $compiler.compile_cml(message)) <);
    ch_messages = user.read("Enter messages to be displayed during the change ('.' to finish)");
    if (type(ch_messages) == 'symbol)
        throw(~stop, "");
    (> (ch_messages = map i in (ch_messages) to ($compiler.compile_cml(i))) <);
    return .add_weather(self, weather, attrs, probs, message, ch_messages);
};

public method ._distances() {
    arg self, from, season;
    var i, j, attr, w, refattr;
    
    w = self[3];
    refattr = (w[from])[1];
    return map i in (w.keys()) to ([i, ((map j in [1 .. (attr = (w[i])[1]).length()] to (abs((attr[j]) - (refattr[j]))).sum()) * 100) / (((w[i])[2])[season])]);
};

public method .advance() {
    arg self, current, season, fuzz;
    var dists, i, w, s;
    
    w = self[3];
    dists = ._distances(self, current, season);
    dists = dists.sort(dists.slice(2));
    i = 1;
    while ((i < (dists.length())) && (random(20 + ((dists[i])[2])) < fuzz))
        i++;
    return (dists[i])[1];
};


new object $rect: $frob;

var $root manager = $rect;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 843360251;
var $root inited = 1;
var $root managed = [$rect];

public method .union() {
    arg r1, r2;
    
    return [$math.minor(r1[1], r2[1]), $math.major(r1[2], r2[2])];
};

public method .intersection() {
    arg r1, r2;
    
    // Doesn't check for validity
    return [$math.major(r1[1], r2[1]), $math.minor(r1[2], r2[2])];
};

public method .rect_size() {
    arg r1;
    var i, s;
    
    s = 0.0;
    for i in ($math.sub(@r1))
        s += i;
    return -s;
};

public method .nondegenerate() {
    arg r1;
    
    return $math.is_lower(@r1);
};

public method .inside() {
    arg point, box;
    
    return ($math.is_lower(point, box[2])) && ($math.is_lower(box[1], point));
};


new object $rtree: $frob;

var $root manager = $rtree;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 843361817;
var $rtree max_length = 4;
var $root inited = 1;
var $root managed = [$rtree];
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];

public method ._insert_where() {
    arg rlist, new;
    var i, u, min, t;
    
    u = 0;
    min = 1e+27;
    for i in [1 .. rlist.length()] {
        if ((t = $rect.rect_size($rect.union(rlist[i], new))) < min) {
            min = t;
            u = i;
        }
    }
    return u;
};

public method ._insert() {
    arg tree, box, obj;
    var u, ret, xret, boxes, trees;
    
    trees = tree[2];
    boxes = tree[1];
    if (((trees[1]).length()) == 1) {
        // add leaf node to boxes and trees
        if ((trees.length()) < max_length) {
            return [[boxes + [box], trees + [obj]]];
        } else {
            // return two nodes:
            return ._split(boxes + [box], trees + [obj]);
        }
    } else {
        u = ._insert_where(boxes, box);
        ret = ._insert(trees[u], box, obj);
        if ((ret.length()) == 1)
            return [[boxes.replace(u, $rect.union(box, boxes[u])), trees.replace(u, ret[1])]];
        else if ((trees.length()) < max_length)
            return [[(boxes.delete(u)) + (ret.slice(3)), (trees.delete(u)) + [[(ret[1])[1], (ret[1])[2]], [(ret[2])[1], (ret[2])[2]]]]];
        else
            return ._split((boxes.delete(u)) + (ret.slice(3)), (trees.delete(u)) + [[(ret[1])[1], (ret[1])[2]], [(ret[2])[1], (ret[2])[2]]]);
    }
};

public method ._split() {
    arg rlist, nlist;
    var i, j, m1, m2, r1, r2, l1, l2, n1, n2, len, min, seed1, seed2, min1, box;
    
    // First find the two rects that unioned create the greatest size...
    len = rlist.length();
    min = 1e+27;
    for i in [1 .. len - 1] {
        for j in [i + 1 .. len] {
            if (min > (min1 = $rect.rect_size($rect.union(rlist[i], rlist[j])))) {
                min = min1;
                seed1 = i;
                seed2 = j;
            }
        }
    }
    l1 = [(r1 = rlist[seed1])];
    l2 = [(r2 = rlist[seed2])];
    n1 = [nlist[seed1]];
    n2 = [nlist[seed2]];
    rlist = rlist.delete(seed2);
    rlist = rlist.delete(seed1);
    nlist = nlist.delete(seed2);
    nlist = nlist.delete(seed1);
    
    // Now add to the list that shows lower increase in size
    // l1,l2 are rectangle lists, n1,n2 are node lists, and r1, r2 are
    // current bounding rectangles
    for i in [1 .. rlist.length()] {
        box = rlist[i];
        m1 = $rect.union(r1, box);
        m2 = $rect.union(r2, box);
        if (($rect.rect_size(m1)) < ($rect.rect_size(m2))) {
            r1 = m1;
            l1 += [box];
            n1 += [nlist[i]];
        } else {
            r2 = m2;
            l2 += [box];
            n2 += [nlist[i]];
        }
    }
    return [[l1, n1, r1], [l2, n2, r2]];
};

public method .insert() {
    arg self, box, obj;
    var ret;
    
    if (!(self[1]))
        return (<$rtree, [[box], [obj]]>);
    ret = ._insert(self, box, obj);
    if ((ret.length()) == 1)
        return (<$rtree, (ret[1])>);
    else
        return (<$rtree, [ret.slice(3), [[(ret[1])[1], (ret[1])[2]], [(ret[2])[1], (ret[2])[2]]]]>);
};

public method .new() {
    return (<$rtree, [[], []]>);
};

public method .search() {
    arg self, point;
    var boxes, trees, i, l;
    
    if ((self.length()) == 1)
        return self;
    boxes = self[1];
    trees = self[2];
    l = [];
    for i in [1 .. boxes.length()] {
        if ($rect.inside(point, boxes[i]))
            l += .search(trees[i], point);
    }
    return l;
};

public method ._delete() {
    arg self, key, point;
    var i, trees, boxes, ret, l, b, mod, box;
    
    if ((self.length()) == 1) {
        if (self == key)
            return [0, 1, 0];
        else
            return [self, 0, 0];
    }
    trees = self[2];
    boxes = self[1];
    l = [];
    b = [];
    mod = 0;
    for i in [1 .. boxes.length()] {
        if ($rect.inside(point, boxes[i])) {
            ret = ._delete(trees[i], key, point);
            if ((ret[1]) == 0) {
                mod = 1;
                continue;
            }
            l += [ret[1]];
            mod = mod || (ret[2]);
            b += [(ret[3]) ? (ret[3]) : (boxes[i])];
        } else {
            l += [trees[i]];
            b += [boxes[i]];
        }
    }
    if (!l)
        return [0, 1];
    if (mod) {
        box = b[1];
        for i in (b.subrange(2))
            box = box.union(i);
        return [[b, l], 1, box];
    }
    return [self, 0, 0];
};

public method .delete() {
    arg self, point, box;
    var ret;
    
    ret = ._delete(self, point, box);
    return (ret[1]) ? (<this(), (ret[1])>) : (.empty());
};


new object $propagator: $frob;

var $root manager = $propagator;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 861726346;
var $root inited = 1;
var $root managed = [$propagator];

public method .new_with() {
    arg str;
    var ctext, i, m, effect, props;
    
    if (str in ["n", "no", "none", "0"])
        return 0;
    effect = 0;
    props = #[];
    if ((m = str.match_pattern("*/*"))) {
        [str, effect] = m;
        if (((effect.length()) >= 2) && ((effect[1]) == ".")) {
            if (!(effect = effect.match_pattern("*(*)")))
                throw(~parse, "Effect is not of the form .method(arg, ...)");
            effect = [tosym((effect[1]).subrange(2)), @map i in ((effect[2]).split(",")) to (fromliteral(i))];
        }
    }
    for i in ((str.explode(";")).mmap('trim)) {
        if (!(m = i.match_pattern("*=*")))
            throw(~parse, "'=' expected");
        if (!((m[2]).is_numeric()))
            throw(~parse, "Illegal propagator value");
        props = props.add(tosym(m[1]), toint(m[2]));
    }
    props = effect ? [props, effect] : [props];
    return (<this(), props>);
};

public method .format() {
    arg prop;
    var i, str, pref, val;
    
    if (!prop)
        return "no";
    [val, (pref ?= "")] = prop;
    str = map i in (val) to ((tostr(i[1]) + "=") + (i[2])).join("; ");
    if (pref) {
        if (type(pref) == 'string)
            str += " /" + pref;
        else
            str += strfmt(" /.%l(%l)", pref[1], map i in (pref.subrange(2)) to (toliteral(i)).join(","));
    }
    return str;
};

public method .senses() {
    arg self;
    
    return self[1];
};

public method .effect() {
    arg self;
    
    return ((self.length()) > 1) ? (self[2]) : 0;
};


new object $slate: $thing;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $slate connection = 0;
var $slate remote_host = "";
var $slate remote_port = 0;
var $slate request_method = "";
var $slate received_text = [];
var $located location = $void;
var $located obvious = 1;
var $described prose = [];
var $has_name name = ['uniq, "Generic Slate", "the Generic Slate"];
var $root manager = $slate;
var $root managed = [$slate];
var $thing gender = $gender_neuter;

root method .init_slate() {
    connection = 0;
    remote_host = "";
    remote_port = 0;
    request_method = "";
    received_text = [];
};

root method .uninit_slate() {
    connection = 0;
    remote_host = "";
    remote_port = 0;
    request_method = "";
    received_text = [];
};

protected method .received_text() {
    return received_text;
};

protected method .connection() {
    return connection;
};

protected method .remote_host() {
    return remote_host;
};

protected method .remote_port() {
    return remote_port;
};

protected method .request_method() {
    return request_method;
};

protected method .send() {
    arg line;
    
    connection.send(line);
};

public method .connection_ending();


new object $nothing: $thing;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $located location = $void;
var $located obvious = 1;
var $described prose = [];
var $has_name name = ['prop, "nothing whatsoever", "nothing whatsoever"];
var $root manager = $nothing;
var $thing gender = $gender_neuter;
var $root managed = [$nothing];


new object $introtut_user_graffiti: $thing;

var $root manager = $introtut_user_graffiti;
var $thing lock = <$object_lock_frob, [$introtut_desc]>;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874175358;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "graffiti", "graffiti"];
var $described prose = <$ctext_frob, [["This is a list of descriptions from people around ", <$generator, ["server_name", [], [], 'gen_servername]>, ". It is randomly sampled, and if you look at it again it will represent different descriptions."], #[]]>;
var $located location = $introtut_desc;
var $located obvious = 1;
var $thing gender = $gender_neuter;
var $root inited = 1;
var $introtut_user_graffiti users = [];
var $root managed = [$introtut_user_graffiti];

public method .description() {
    arg flags;
    var p, i, lines, d, u, brake;
    
    p = $ctext_frob.new_with([$cml_lib.format_hr_tag()]);
    lines = [];
    if (users) {
        u = users;
    } else {
        u = [];
        d = ($user_db.database()).to_dict();
        brake = 0;
        while ((listlen(u) < 4) && (brake++ < 20)) {
            i = dict_keys(d).random();
            if (((d[i]).prose()) != "You see nothing special") {
                u += [d[i]];
                d = dict_del(d, i);
            }
        }
    }
    for i in (u)
        lines += [p, i.prose()];
    return (> pass(flags) <) + lines;
};

public method .set_users() {
    arg list;
    
    // specify a list of objects which have good descriptions for users, to
    // be used as examples.  If this list exists then the descriptions will
    // not be randomly selected.  If it is zero-length, they will be.
    (> .perms(sender()) <);
    users = list;
};

public method .core_introtut_user_graffiti() {
    var o;
    
    users = filter o in (users) where (valid(o));
};

public method .users() {
    return users;
};


new object $introtut_leaflet: $thing;

var $root manager = $introtut_leaflet;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874177644;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['normal, "leaflet", "a leaflet"];
var $described prose = <$ctext_frob, [["You see writing on the leaflet, which appears to be: ", <$format, ["np", [], [], 'do_np]>, "You have now looked at a room and at objects. If you look at a person you will find the description contains a lot more information. For an example, look at yourself using the command:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["look me"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "As you can see, more information is given. The name and description exist--like with other objects--but you also see the person's activity status. A person is asleep if they are not online, and if they are inactive (they have not typed anything for a while) the status will be something corresponding with how inactive they are, such as 'He is daydreaming' or 'She is long gone'. ", <$format, ["np", [], [], 'do_np]>, "You will also see a list of objects the user is carrying. You can look at these just as you looked at this leaflet in the mailbox, using one of the following commands:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["look at <object> on <player>", <$format, ["br", [], [], 'do_br]>, "look at <player>'s <object>"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If the person is an administrator, you will also see something about their system priviledges. By default, this is referred to as Mojo. Mojo is simply a representation of the administrator's system priviledges. If an administrator's Mojo is active, they have full system priviledges--if not, their priviledges are like any other programmers. ", <$format, ["np", [], [], 'do_np]>, "For more information, read the help documentation on the ", <$format, ["link", [["node", "$help_cmd_look"]], ["look"], 'do_link]>, " command."], #[['links, #[["look", "$help_cmd_look"]]]]]>;
var $located location = $introtut_mailbox;
var $located obvious = 1;
var $thing gender = $gender_neuter;
var $root inited = 1;
var $thing lock = <$object_lock_frob, [$introtut_mailbox]>;
var $root managed = [$introtut_leaflet];


new object $character: $thing;

var $root manager = $character;
var $root managed = [$character];
var $root flags = ['variables, 'methods, 'code, 'core, 'fertile];
var $root created_on = 890933084;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "Generic Character", "Generic Character"];
var $described prose = [];
var $located location = $nowhere;
var $located obvious = 1;
var $thing gender = $gender_neuter;
var $root inited = 1;
var $character dead = 0;
var $character identity = 0;
var $character affiliation = 0;
var $character deaths = 0;
var $character str = 0;
var $character agl = 0;
var $character app = 0;
var $character itg = 0;
var $character int = 0;
var $character per = 0;
var $character cha = 0;
var $character wil = 0;
var $character cra = 0;
var $character awr = 0;
var $character dmg = 0;
var $character rea = 0;
var $character cmb = 0;
var $character npc = 0;
var $character lrn = 0;
var $character end = 0;
var $character lif = 0;
var $character hum = 0;
var $character kno = 0;
var $character src = 0;
var $character csrc = 0;

public method .fmta() {
    arg stat;
    var base, cur;
    
    [base, cur] = get_var(stat) || [10, 10];
    if (base == cur)
        return pad(tostr(cur), -2) + "    ";
    return strfmt("%2r/%2l", cur, base) + " ";
};

public method .fmts() {
    arg score;
    var v;
    
    v = get_var(score);
    switch (score) {
        case 'hum:
            if (v > 0)
                return pad("+" + v, 6);
    }
    return pad(tostr(v), 6);
};

public method .format_sheet() {
    var out, line;
    
    line = (("  Strength: " + (.fmta('str))) + " Intellect: ") + (.fmta('int));
    line += (("    Craft: " + (.fmta('cra))) + " STR DMG: ") + (.fmts('dmg));
    out = [line];
    line = (("   Agility: " + (.fmta('agl))) + "Perception: ") + (.fmta('per));
    line += (("Awareness: " + (.fmta('awr))) + " CMB REA: ") + (.fmts('cmb));
    out += [line];
    line = (("Appearance: " + (.fmta('app))) + "  Charisma: ") + (.fmta('cha));
    line += "   -------        NPC REA: " + (.fmts('npc));
    out += [line];
    line = ((" Integrity: " + (.fmta('itg))) + " Willpower: ") + (.fmta('wil));
    line += ((" Humanity: " + (.fmta('hum))) + "   Learn: ") + (.fmts('lrn));
    out += [line, ""];
    line = ((((((" Endurance: " + (.fmts('end))) + " Knowledge: ") + (.fmts('kno))) + "   Source: ") + (.fmts('src))) + " Cur Src: ") + (.fmts('csrc));
    out += [line];
    line = ("   ** Life: " + (.fmts('lif))) + "    DAMAGE: x/x    CRITICAL: x/x     HEALTH: x/x";
    return out + [line];
};

public method .lower_attr() {
    arg attribute, difference;
    var new;
    
    new = (get_var(attribute)[1]) - difference;
    set_var(attribute, get_var(attribute).replace(1, new));
};

public method .raise_attr() {
    arg attribute, difference;
    var new;
    
    new = (get_var(attribute)[1]) + difference;
    if (new > (get_var(attribute)[2]))
        new = get_var(attribute)[2];
    set_var(attribute, get_var(attribute).replace(1, new));
};

public method .attribute() {
    arg attribute;
    
    if (caller() != definer())
        (> .perms(sender(), 'trusts) <);
    if (!(attribute in (.attributes())))
        throw(~invattr, "Invalid Attribute: " + attribute);
    return get_var(attribute) || [10, 10];
};

public method .dead() {
    return dead;
};

public method .ok_to_raise_initial() {
    arg attr, amt;
    var a, tot, phys, ment, meta, list, i, end;
    
    phys = .physical_attributes();
    ment = .mental_attributes();
    meta = .meta_attributes();
    for a in ((phys + ment) + meta) {
        if ((a = get_var(a)))
            tot += a[1];
        else
            tot += 10;
    }
    if (tot > 110)
        return "No initial points left, try reducing another attribute.";
    end = ((get_var(attr) || [10])[1]) + amt;
    if (end > 16)
        return "Initial Attributes may not be more than 16";
    if (attr in phys) {
        list = phys;
        i = [56, "Physical"];
    } else if (attr in ment) {
        list = ment;
        i = [56, "Mental"];
    } else if (attr in meta) {
        list = meta;
        i = [30, "Meta-Physical"];
    } else {
        throw(~invattr, "Invalid Attribute: " + attr);
    }
    tot = 0;
    for a in (list) {
        if ((a = get_var(a)))
            tot += a[1];
        else
            tot += 10;
    }
    if ((tot + amt) > (i[1]))
        return ((("This would go beyond the max (" + (i[1])) + ") for ") + (i[2])) + " Attributes";
    return end;
};

public method .init_character() {
    str = (agl = (app = (itg = (int = (per = (cha = (wil = (cra = (awr = [10, 10])))))))));
};

public method .ok_to_lower_initial() {
    arg attr, amt;
    var end;
    
    end = ((get_var(attr) || [10])[1]) - amt;
    if (end < 6)
        return "Initial Attributes may not be less than 6";
    return end;
};

public method .meta_attributes() {
    return ['cra, 'awr];
};

public method .physical_attributes() {
    return ['str, 'agl, 'app, 'itg];
};

public method .mental_attributes() {
    return ['int, 'per, 'cha, 'wil];
};

public method .attributes() {
    return ((.physical_attributes()) + (.mental_attributes())) + (.meta_attributes());
};

public method .set_attribute() {
    arg attribute, base;
    var cur;
    
    (> .perms(caller(), $player) <);
    if (!(attribute in (.attributes())))
        throw(~invattr, "Invalid Attribute: " + attribute);
    cur = get_var(attribute) || [10, 10];
    cur = replace(cur, 1, base);
    if ((cur[2]) > base)
        cur = replace(cur, 2, base);
    set_var(attribute, cur);
};


new object $wearable: $thing;

var $root manager = $wearable;
var $wearable worn = 0;
var $root flags = ['variables, 'methods, 'code, 'core, 'fertile];
var $root created_on = 1011584085;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[["remove|shed", [["remove|shed", "*", "remove|shed <this>", 'remove_cmd, #[[1, ['this, []]]]]]], ["wear", [["wear", "*", "wear <this>", 'wear_cmd, #[[1, ['this, []]]]]]]];
var $has_commands local = #[];
var $has_name name = ['prop, "Generic Wearable Thing", "Generic Wearable Thing"];
var $described prose = [];
var $located location = $void;
var $located obvious = 1;
var $thing gender = $gender_neuter;
var $root inited = 1;
var $root managed = [$wearable];

public method .wear_cmd() {
    arg cmdstr, cmd, what;
    
    (> .perms('command, caller()) <);
    if ((.location()) != sender())
        throw(~stop, ((("You must be holding " + (.name())) + " in order to wear ") + ((.gender()).pronoun('po))) + ".");
    if (worn)
        throw(~stop, ("You are already wearing " + (.name())) + "!");
    worn = sender().wear();
    return ("You wear " + (.name())) + ".";
};

public method .will_move() {
    arg mover, place;
    
    (> pass(mover, place) <);
    if (worn)
        throw(~worn, ((.name()).capitalize()) + " is currently being worn.");
};

public method .shed_cmd() {
    arg cmd, cmdstr, what;
    
    (> .perms('command, caller()) <);
    if ((.location()) != sender())
        throw(~stop, ("You are not holding " + (.name())) + ".");
    if (!worn)
        throw(~stop, ("You are not wearing " + (.name())) + ".");
    clear_var('worn);
    sender().shed();
    return ("You remove " + (what.name())) + ".";
};


new object $path: $physical;

var $root manager = $path;
var $path ways = #[];
var $root flags = ['variables, 'methods, 'code, 'core, 'fertile];
var $root created_on = 881987340;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[["@lock", [["@lock", "*", "@lock <this>", 'lock_cmd, #[[1, ['this, []]]]], ["@lock", "* with|to *", "@lock <this> with|to <any>", 'lock_with_cmd, #[[1, ['this, []]], [3, ['any, []]]]]]], ["@unlock", [["@unlock", "*", "@unlock <this>", 'unlock_cmd, #[[1, ['this, []]]]]]], ["open", [["open", "*", "open <this>", 'open_cmd, #[[1, ['this, []]]]]]], ["close", [["close", "*", "close <this>", 'close_cmd, #[[1, ['this, []]]]]]]];
var $has_commands local = #[];
var $has_name name = ['uniq, "Generic Path", "the Generic Path"];
var $described prose = [];
var $root inited = 1;
var $path msg_vars = #[["$actor", 0], ["actor", 0], ["$source", 0], ["source", 0], ["$dest", 0], ["dest", 0], ["$this", 0], ["this", 0], ["$lock", 0]];
var $path closable = 0;
var $path closed = 0;
var $path lock = 0;
var $path names = #[];
var $foundation msgs = #[["invoke", #[["actor", <$ctext_frob, [["You take ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["source", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " goes through ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["dest", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " arrives."], #[['this, $path]]]>]]], ["exit-close", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " closes ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["actor", <$ctext_frob, [["You close ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>]]], ["exit-open", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " opens ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["actor", <$ctext_frob, [["You open ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>]]], ["lock-fail", #[["actor", <$ctext_frob, [[<$generator, ["this", [], [], 'gen_this]>, " is locked."], #[['this, $path]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " tries to go through ", <$generator, ["this", [], [], 'gen_this]>, ", but it is locked."], #[]]>]]], ["lock-try", #[["actor", <$ctext_frob, [["You use ", <$generator, ["lock", [], [], 'gen_lock]>, " on ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["general", <$ctext_frob, [[], #[['this, $path]]]>]]], ["lock-unlock", #[["actor", <$ctext_frob, [["You unlock ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $path]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " unlocks ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $path]]]>]]], ["lock-lock", #[["actor", <$ctext_frob, [["You lock ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $path]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " locks ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $path]]]>]]], ["exit-closed", #[["actor", <$ctext_frob, [["You try to go through ", <$generator, ["this", [], [], 'gen_this]>, ", but it is closed."], #[]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " tries to go through ", <$generator, ["this", [], [], 'gen_this]>, ", but it is closed."], #[]]>]]]];
var $foundation defined_msgs = #[["invoke", #[['branches, ["actor.*", "source.*", "dest.*"]], ['parser, 'parse_exit_msg], ['varkeys, #[["actor", "$source"], ["source", "$source"], ["dest", "$dest"]]]]], ["exit-open", #[['branches, ["actor", "general"]]]], ["exit-close", #[['branches, ["actor", "general"]]]], ["lock-fail", #[['branches, ["general", "actor"]]]], ["lock-try", #[['branches, ["general", "actor"]]]], ["lock-unlock", #[['branches, ["general", "actor"]]]], ["lock-lock", #[['branches, ["general", "actor"]]]], ["exit-closed", #[['branches, ["actor", "general"]]]]];
var $root defined_settings = #[["closable", #[['get, ['get_closable]], ['set, ['set_closable]], ['parse, ['is_boolean]], ['clear, ['clear_closable]], ['format, ['format_boolean]]]], ["transparent", #[['get, ['get_transparent]], ['set, ['set_transparent]], ['parse, ['parse_transparent]], ['clear, ['clear_transparent]], ['format, ['format_transparent]]]], ["close-style", #[['get, ['get_close_style]], ['set, ['set_close_style]], ['parse, ['parse_close_style]], ['clear, ['clear_close_style]], ['format, ['format_close_style]]]]];
var $path transparent = 0;
var $path close_style = 0;
var $root managed = [$path];

public method .parse_exit_msg() {
    arg def, name, @branch;
    var target, obj;
    
    if (listlen(branch) == 1)
        return [def, name, branch[1]];
    target = branch[2];
    if (target == "here")
        obj = user().location();
    else if ((target == "source") || (target == "src"))
        obj = (| user().location() |);
    else if (match_begin(target, "destination") || (target == "there"))
        obj = (| ways[user().location()] |);
    else if (!(obj = (| $object_lib.to_dbref(target) |)))
        obj = (> user().match_environment(target) <);
    if ((!ways) || ((!dict_contains(ways, obj)) || (!(obj in (ways.values())))))
        throw(~invobj, ((("The branch '" + target) + "' matches ") + (obj.name())) + " which is not a valid way for the path.");
    return [def, name, ((branch[1]) + ".") + (obj.objname())];
};

protected method .detach() {
    arg source;
    var dest;
    
    if (ways && dict_contains(ways, source)) {
        source.detach_exit('source, this());
        dest = ways[source];
        dest.detach_exit('dest, this());
        if (dict_contains(names, source))
            names = dict_del(names, source);
        if (dict_contains(names, dest))
            names = dict_del(names, dest);
        ways = dict_del(ways, source);
    }
};

root method .uninit_nexit() {
    var s;
    
    for s in (ways)
        (| .detach(s) |);
    (| clear_var('ways) |);
    (| clear_var('lock) |);
    (| clear_var('closable) |);
    (| clear_var('closed) |);
    (| clear_var('msg_vars) |);
};

public method .attach() {
    arg src, dst, @ignore;
    
    (> .perms(sender()) <);
    (src.is($place)) || throw(~place, (src.namef('ref)) + " is not a place.");
    (dst.is($place)) || throw(~place, (dst.namef('ref)) + " is not a place.");
    (> src.will_attach('source, sender()) <);
    (> dst.will_attach('dest, sender()) <);
    if (!ways)
        ways = #[];
    ways = ways.add(src, dst);
    (> src.attach_exit('source, this()) <);
    (> dst.attach_exit('dest, this()) <);
};

public method .exit_msg_vars() {
    arg actor, source, dest, @more;
    var vars;
    
    vars = dict_add(default_var('msg_vars), "$actor", actor);
    vars = dict_add(vars, "actor", actor.name());
    vars = dict_add(vars, "$source", source);
    vars = dict_add(vars, "source", source.name());
    vars = dict_add(vars, "$dest", dest);
    vars = dict_add(vars, "dest", dest.name());
    vars = dict_add(vars, "$this", this());
    vars = dict_add(vars, "this", .name());
    vars = dict_add(vars, "$lock", lock);
    if (more)
        vars = dict_union(vars, more[1]);
    return vars;
};

public method .invoke() {
    arg @flags;
    var here, vars, m, actor, ln, v, dest, source, doclose;
    
    actor = sender();
    source = actor.location();
    dest = (> .get_way(source) <);
    if (closed) {
        if (close_style || (!(actor.is($user)))) {
            m = .eval_message("exit-closed", $path, .path_msg_vars(actor, source, dest));
            return source.announce(m);
        } else {
            .open_path(actor, source, dest);
            doclose = 1;
        }
    }
    if (flags)
        flags = flags[1];
    else
        flags = #[];
    flags = dict_add(flags, 'actor, actor);
    flags = flags.add_elem('exclude, actor);
    if (lock && (!(lock.try(actor)))) {
        v = #[["lock", lock.lock_name()]];
        m = .eval_message("lock-fail", $path, .path_msg_vars(actor, source, dest, v));
        return source.announce(m);
    }
    m = .eval_message("invoke", $path, .path_msg_vars(actor, source, dest));
    actor.tell(m);
    actor.move_to(dest);
    dest.announce(m, actor);
    source.announce(m);
    if (doclose)
        .close_path(actor, dest, source);
};

public method .lock() {
    return lock || ($true_lock_frob.new());
};

public method .dest() {
    arg @src;
    
    if (!ways)
        return $nowhere;
    if (!src)
        src = sender();
    else
        src = src[1];
    return (| ways[src] |) || throw(~noway, "No path exists from " + src);
};

public method .source() {
    arg @dst;
    var i;
    
    if (!ways)
        return $nowhere;
    if (!dst)
        dst = sender();
    else
        dst = dst[1];
    if ((i = dst in dict_values(ways)))
        return dict_keys(ways)[i];
    throw(~noway, "No path exists from " + dst);
};

public method .lock_cmd() {
    arg cmdstr, cmd, this;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    lock = $false_lock_frob.new();
    return "You lock " + (.name());
};

public method .lock_with_cmd() {
    arg cmdstr, cmd, this, prep, str;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    catch ~objnf, ~parse {
        lock = $lock_frob.parse(str, sender());
        return ((("You lock " + (.name())) + " to allow ") + (lock.lock_name('exit))) + ".";
    } with {
        switch (error()) {
            case ~objnf:
                return "Object not found in lock string.";
            case ~parse:
                return "Invalid lock string.";
        }
    }
};

public method .unlock_cmd() {
    arg cmdstr, cmd, this;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    lock = $true_lock_frob.new();
    sender().tell("You unlock " + (.name()));
};

public method .is_visible_to() {
    arg whom;
    
    return (.visibility()) >= ((whom.location()).darkness());
};

public method .try_lock() {
    arg @args;
    
    (.lock()).try(@args);
};

protected method .description() {
    arg flags;
    var out, src;
    
    out = (> pass(flags) <);
    
    // transparent: -1=when-open, 0=yes, 1=no
    src = (flags['actor]).location();
    switch (transparent) {
        case 1:
            return out;
        case 0:
            if (closed)
                out += [(.name()) + " is closed."];
            return out + [(<$ctext_frob, [[(<$format, ["subj", [], [("Through " + (.name())) + " you see.."], 'do_subj]>)], #[]]>), (.dest(src)).get_description(flags)];
        case -1:
            if (closed)
                return out + [(.name()) + " is closed."];
            return out + [(<$ctext_frob, [[(<$format, ["subj", [], [("Through " + (.name())) + " you see.."], 'do_subj]>)], #[]]>), (.dest(src)).get_description(flags)];
    }
};

protected method .get_ways() {
    arg actor;
    var s;
    
    s = actor.location();
    if (!dict_contains(ways, s))
        throw(~notexit, "That exit is not where you are.");
    return [s, ways[s]];
};

public method .close_cmd() {
    arg cmdstr, cmd, this;
    var vars, m, source, dest;
    
    catch ~locked
        .try_lock(sender());
    with
        return (traceback()[1])[2];
    source = sender().location();
    dest = .get_way(source);
    if (closable) {
        if (closed)
            return ((.name()).capitalize()) + " is already closed.";
        else
            .close_path(sender(), source, dest);
    } else {
        return ((.name()).capitalize()) + " cannot be closed.";
    }
};

public method .open_cmd() {
    arg cmdstr, cmd, this;
    var vars, m, source, dest;
    
    catch ~locked
        .try_lock(sender());
    with
        return (traceback()[1])[2];
    source = sender().location();
    dest = .get_way(source);
    if (closable) {
        if (closed)
            .open_path(sender(), source, dest);
        else
            return ((.name()).capitalize()) + " is already open.";
    } else {
        return ((.name()).capitalize()) + " cannot be opened.";
    }
};

public method .get_closable() {
    arg name, definer;
    
    return closable;
};

protected method .clear_closable() {
    arg name;
    
    (| clear_var('closable) |);
};

public method .place_destroyed() {
    arg place;
    var s;
    
    (> .perms(caller(), $place) <);
    if (dict_contains(ways, place))
        .detach(place);
    for s in (ways || #[]) {
        if ((s[2]) == place)
            .detach(s[1]);
    }
    if (!ways)
        $sys.destroy_sender();
};

public method .ways() {
    return ways || #[];
};

protected method .set_closable() {
    arg name, definer, value;
    
    if (value) {
        closable = 1;
    } else if (closable) {
        if (closed)
            (| clear_var('closed) |);
        (| clear_var('closable) |);
    }
};

root method .init_path() {
    names = #[];
};

root method .uninit_path() {
    var s;
    
    for s in (ways || #[])
        (| .detach(s[1]) |);
    (| clear_var('ways) |);
    (| clear_var('lock) |);
    (| clear_var('closable) |);
    (| clear_var('closed) |);
    (| clear_var('msg_vars) |);
};

public method .name() {
    arg @args;
    var name, loc;
    
    if (user())
        loc = user().location();
    else
        loc = (| sender().location() |) || sender();
    if (!(name = (| names[loc] |)))
        name = (| dict_values(names)[1] |) || ['normal, "path", "a ", []];
    if (!args)
        return (name[3]) + (name[2]);
    switch (args[1]) {
        case 'type:
            return name[1];
        case 'noarticle:
            return (name[3]) + (name[2]);
        default:
            return name;
    }
};

public method .set_name() {
    arg name, @args;
    var type, loc, set;
    
    (> .perms(sender()) <);
    [(type ?= 'normal), (loc ?= 0)] = args;
    if (!loc) {
        if (!user())
            throw(~error, "Unable to determine source for name -- no task user");
        loc = user().location();
    }
    if ((!dict_contains(ways, loc)) && (!(loc in dict_values(ways))))
        throw(~invloc, ((loc.namef('ref)) + " is not a valid way for ") + this());
    (> $code_lib.valid_name(name, type) <);
    set = (| names[loc] |) || [0, 0, 0, []];
    set = replace(set, 1, type);
    set = replace(set, 2, name);
    switch (type) {
        case 'prop:
            set = replace(set, 3, "");
        case 'uniq:
            set = replace(set, 3, "the ");
        case 'normal:
            set = replace(set, 3, (name.a_or_an()) + " ");
    }
    names = dict_add(names, loc, set);
};

public method .match_name() {
    arg str;
    var m, t, name;
    
    name = .name('literal);
    if ((m = match_begin(name[2], str)))
        return m;
    for t in (name[4]) {
        if ((m = match_template(str, t)))
            return m;
    }
    return 0;
};

public method .name_templates() {
    return (.name('literal))[4];
};

public method .add_name_template() {
    arg template, @args;
    var p, name, loc;
    
    (> .perms(sender()) <);
    if (args) {
        loc = args[1];
    } else {
        if (!user())
            throw(~error, "Unable to determine source for name -- no task user");
        loc = user().location();
    }
    name = (| names[loc] |) || ['normal, "path", "a ", []];
    template = template.trim();
    for p in (explode(template, "|")) {
        if (match_begin(name[2], p.strip()))
            throw(~redundant, ("Redundant name template part \"" + p) + "\" already matches name.");
    }
    name = replace(name, 4, setadd(name[4], template));
    names = dict_add(names, loc, name);
};

public method .del_name_template() {
    arg template;
    var loc, name;
    
    (> .perms(sender()) <);
    if (!user())
        throw(~error, "Unable to determine source for name -- no task user");
    loc = user().location();
    name = (| names[loc] |) || ['normal, "path", "a ", []];
    names = dict_add(names, loc, replace(name, 4, setremove(name[4], template)));
};

public method .match_name_exact() {
    arg str;
    
    return str == (.name('noarticle));
};

public method .hname() {
    arg @args;
    
    // WARNING: THIS IS WRONG AND WILL NOT WORK
    return ((("<a href=\"/bin/describe?target=" + (.objname())) + "\">") + (.name())) + "</a>";
};

public method .path_name() {
    arg loc, @args;
    var name, loc;
    
    if (!(name = (| names[loc] |)))
        name = (| dict_values(names)[1] |) || ['normal, "path", "a ", []];
    if (!args)
        return (name[3]) + (name[2]);
    switch (args[1]) {
        case 'type:
            return name[1];
        case 'noarticle:
            return (name[3]) + (name[2]);
        default:
            return name;
    }
};

public method .get_way() {
    arg source;
    var dest;
    
    if (!(dest = (| ways[source] |)))
        throw(~invsrc, "You are not located in any source for this exit");
    if (!valid(dest))
        return actor.tell((.name()) + " has an invalid destination!");
    return dest;
};

public method .get_transparent() {
    arg name, definer;
    
    return transparent;
};

protected method .clear_transparent() {
    arg name;
    
    (| clear_var('transparent) |);
};

protected method .set_transparent() {
    arg name, definer, value;
    
    if (!value)
        (| clear_var('transparent) |);
    else
        transparent = value;
};

protected method .format_transparent() {
    arg value;
    
    switch (value) {
        case 1:
            return "no";
        case 0:
            return "yes";
        case -1:
            return "when-open";
        default:
            return "<<ERROR>>";
    }
};

protected method .parse_transparent() {
    arg value, @args;
    var bool;
    
    // -1=when-open, 0=yes, 1=no
    if ((bool = value.is_boolean()) != (-1)) {
        return !bool;
    } else if (value == "when-open") {
        if (!closable)
            throw(~inv, "Transparent setting of 'when-open' only works with closable paths.");
        return -1;
    } else {
        throw(~invtype, "Invalid transparency setting, try: yes, no, when-open");
    }
};

public method .get_close_style() {
    arg name, definer;
    
    return close_style;
};

protected method .format_close_style() {
    arg value;
    
    if (value)
        return "manual";
    return "auto";
};

protected method .parse_close_style() {
    arg value, @args;
    var bool;
    
    // 0=auto 1=manual
    if (match_begin(value, "manual"))
        return 1;
    else if (match_begin(value, "auto"))
        return 0;
    else
        throw(~invtype, "Invalid close-style setting, try: auto, manual");
};

protected method .clear_close_style() {
    arg name;
    
    (| clear_var('close_style) |);
};

protected method .set_close_style() {
    arg name, definer, value;
    
    if (!value)
        (| clear_var('close_style) |);
    else
        close_style = value;
};

protected method .close_path() {
    arg actor, source, dest;
    var vars, m;
    
    if (!closable)
        throw(~perm, "That is not closable, what are you thinking?");
    closed = 1;
    vars = .path_msg_vars(actor, @.get_ways(actor));
    m = .eval_message("exit-close", $path, vars);
    source.announce(m);
    dest.announce(m);
};

protected method .open_path() {
    arg actor, source, dest;
    var vars, m;
    
    if (!closable)
        throw(~perm, "That is not closable, what are you thinking?");
    (| clear_var('closed) |);
    vars = .path_msg_vars(actor, @.get_ways(actor));
    m = .eval_message("exit-open", $path, vars);
    source.announce(m);
    dest.announce(m);
};

public method .path_msg_vars() {
    arg actor, source, dest, @more;
    var vars;
    
    vars = dict_add(default_var('msg_vars), "$actor", actor);
    vars = dict_add(vars, "actor", actor.name());
    vars = dict_add(vars, "$source", source);
    vars = dict_add(vars, "source", source.name());
    vars = dict_add(vars, "$dest", dest);
    vars = dict_add(vars, "dest", dest.name());
    vars = dict_add(vars, "$this", this());
    vars = dict_add(vars, "this", .path_name(source));
    vars = dict_add(vars, "$lock", lock);
    if (more)
        vars = dict_union(vars, more[1]);
    return vars;
};


new object $introtut_path1: $path;

var $root manager = $introtut_path1;
var $path ways = #[[$introtut_moving, $introtut_moving_1], [$introtut_moving_1, $introtut_moving]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 882834737;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "path_140", "path_140"];
var $described prose = [];
var $path names = #[[$introtut_moving, ['prop, "east", "", []]], [$introtut_moving_1, ['prop, "west", "", []]]];
var $root inited = 1;
var $root managed = [$introtut_path1];


new object $introtut_path2: $path;

var $root manager = $introtut_path2;
var $path ways = #[[$introtut_moving_1, $introtut_moving_2], [$introtut_moving_2, $introtut_moving_1]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 882834737;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "path_142", "path_142"];
var $described prose = [];
var $path names = #[[$introtut_moving_1, ['prop, "stairs", "", ["d?own"]]], [$introtut_moving_2, ['prop, "stairs", "", ["u?p"]]]];
var $root inited = 1;
var $root managed = [$introtut_path2];


new object $exit: $physical;

var $exit source = $void;
var $exit dest = $void;
var $exit lock = <$true_lock_frob, []>;
var $exit msg_vars = #[["$actor", 0], ["actor", 0], ["$source", 0], ["source", 0], ["$dest", 0], ["dest", 0], ["$this", 0], ["this", 0], ["$lock", 0]];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $described prose = [];
var $has_name name = ['uniq, "Generic Exit", "the Generic Exit"];
var $has_commands remote = #[["@lock", [["@lock", "*", "@lock <this>", 'lock_cmd, #[[1, ['this, []]]]], ["@lock", "* with|to *", "@lock <this> with|to <any>", 'lock_with_cmd, #[[1, ['this, []]], [3, ['any, []]]]]]], ["@unlock", [["@unlock", "*", "@unlock <this>", 'unlock_cmd, #[[1, ['this, []]]]]]], ["open", [["open", "*", "open <this>", 'open_cmd, #[[1, ['this, []]]]]]], ["close", [["close", "*", "close <this>", 'close_cmd, #[[1, ['this, []]]]]]]];
var $exit closed = 0;
var $exit closable = 0;
var $root manager = $exit;
var $foundation defined_msgs = #[["invoke", #[['branches, ["actor", "source.*", "dest.*"]], ['parser, 'parse_exit_msg]]], ["exit-open", #[['branches, ["actor", "general"]]]], ["exit-close", #[['branches, ["actor", "general"]]]], ["lock-fail", #[['branches, ["general", "actor"]]]], ["lock-try", #[['branches, ["general", "actor"]]]], ["lock-unlock", #[['branches, ["general", "actor"]]]], ["lock-lock", #[['branches, ["general", "actor"]]]], ["exit-closed", #[['branches, ["actor", "general"]]]]];
var $foundation msgs = #[["invoke", #[["actor", <$ctext_frob, [["You take ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $exit]]]>], ["source", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " goes through ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $exit]]]>], ["dest", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " arrives."], #[['this, $exit]]]>]]], ["exit-close", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " closes ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $exit]]]>], ["actor", <$ctext_frob, [["You close ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $exit]]]>]]], ["exit-open", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " opens ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $exit]]]>], ["actor", <$ctext_frob, [["You open ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $exit]]]>]]], ["lock-fail", #[["actor", <$ctext_frob, [[<$generator, ["this", [], [], 'gen_this]>, " is locked."], #[['this, $exit]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " tries to take ", <$generator, ["this", [], [], 'gen_this]>, " but its locked!"], #[['this, $exit]]]>]]], ["lock-try", #[["actor", <$ctext_frob, [["You use ", <$generator, ["lock", [], [], 'gen_lock]>, " on ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $exit]]]>], ["general", <$ctext_frob, [[], #[['this, $exit]]]>]]], ["lock-unlock", #[["actor", <$ctext_frob, [["You unlock ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $exit]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " unlocks ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $exit]]]>]]], ["lock-lock", #[["actor", <$ctext_frob, [["You lock ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $exit]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " locks ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $exit]]]>]]], ["exit-closed", #[["actor", <$ctext_frob, [["You try to go through ", <$generator, ["this", [], [], 'gen_this]>, " but it is closed!"], #[['this, $exit]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " tries to take ", <$generator, ["this", [], [], 'gen_this]>, " but it is closed!"], #[['this, $exit]]]>]]]];
var $root settings = #[["closable", "no"]];
var $root defined_settings = #[["closable", #[['get, ['get_closable]], ['set, ['set_closable]], ['clear, ['clear_closable]], ['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $root managed = [$exit];

root method .uninit_exit() {
    (| .detach() |);
    (| clear_var('source) |);
    (| clear_var('dest) |);
    (| clear_var('lock) |);
};

public method .invoke() {
    arg @flags;
    var s, here, vars, m, actor, ln, v, edest, esource;
    
    s = (actor = sender());
    esource = .source();
    edest = .dest();
    if (closed) {
        m = .eval_message("exit-closed", $exit, .exit_msg_vars(s));
        return esource.announce(m);
    }
    if (flags)
        flags = flags[1];
    else
        flags = #[];
    flags = flags.add('actor, s);
    flags = flags.add_elem('exclude, s);
    if (!valid(edest))
        return s.tell((.name()) + " has an invalid destination!");
    if (lock && (!(lock.try(s)))) {
        v = #[["lock", lock.lock_name()]];
        m = .eval_message("lock-fail", $exit, .exit_msg_vars(s, v));
        return esource.announce(m);
    }
    m = .eval_message("invoke", $exit, .exit_msg_vars(s));
    actor.tell(m);
    s.move_to(edest);
    edest.announce(m, actor);
    esource.announce(m);
};

public method .lock() {
    return lock || ($true_lock_frob.new());
};

public method .attach() {
    arg src, dst, @ignore;
    
    (> .perms(sender()) <);
    (src.is($place)) || throw(~place, (source.namef('ref)) + " is not a place.");
    (dst.is($place)) || throw(~place, (dest.namef('ref)) + " is not a place.");
    (| .detach() |);
    (> src.will_attach('source, sender()) <);
    (> dst.will_attach('dest, sender()) <);
    source = src;
    dest = dst;
    (> source.attach_exit('source, this()) <);
    (> dest.attach_exit('dest, this()) <);
};

public method .dest() {
    return dest;
};

public method .source() {
    return source;
};

public method .place_destroyed() {
    arg place;
    
    (> .perms(caller(), $place) <);
    .detach();
    if (sender() in [dest, source])
        $sys.destroy_sender();
};

public method .destination_destroyed() {
    var msg, line, name;
    
    (> .perms(caller(), $place) <);
    $sys.destroy_sender();
};

public method .detach() {
    source && (source.detach_exit('source, this()));
    dest && (dest.detach_exit('dest, this()));
    source = 0;
    dest = 0;
};

public method .lock_cmd() {
    arg cmdstr, cmd, this;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    lock = $false_lock_frob.new();
    return "You lock " + (.name());
};

public method .lock_with_cmd() {
    arg cmdstr, cmd, this, prep, str;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    catch ~objnf, ~parse {
        lock = $lock_frob.parse(str, sender());
        return ((("You lock " + (.name())) + " to allow ") + (lock.lock_name('exit))) + ".";
    } with {
        switch (error()) {
            case ~objnf:
                return "Object not found in lock string.";
            case ~parse:
                return "Invalid lock string.";
        }
    }
};

public method .unlock_cmd() {
    arg cmdstr, cmd, this;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    lock = $true_lock_frob.new();
    sender().tell("You unlock " + (.name()));
};

public method .is_visible_to() {
    arg whom;
    
    return (.visibility()) >= ((whom.location()).darkness());
};

protected method .description() {
    arg flags;
    var desc;
    
    if (closed)
        return (> pass(flags) <) + [(.name()) + " is closed."];
    if ((!(| flags['prose] |)) || (!valid(.dest())))
        return (> pass(flags) <);
    return [(<$ctext_frob, [[(<$format, ["subj", [], [("Through " + (.name())) + " you see.."], 'do_subj]>)], #[]]>), (.dest()).get_description(flags)];
};

private method .invoke_notify() {
    arg actor, flags;
    var vars, m;
    
    if (flags.contains('simple)) {
        actor.tell("You take " + (.name()));
        (.dest()).announce((actor.name()) + " arrives.");
        (.source()).announce((((actor.name()) + " goes through ") + (.name())) + ".");
    } else {
        vars = #[["$actor", actor], ["actor", actor.name()], ["$source", .source()], ["source", (.source()).name()], ["$dest", .dest()], ["dest", (.dest()).name()], ["$exit", this()], ["exit", .name()]];
        m = .eval_message("invoke", $exit, vars);
        (.dest()).announce(m);
        (.source()).announce(m);
    }
};

public method .exit_msg_vars() {
    arg actor, @more;
    var vars, esource, edest;
    
    esource = .source();
    edest = .dest();
    vars = #[["$actor", actor], ["actor", actor.name()], ["$source", esource], ["source", esource.name()], ["$dest", edest], ["dest", edest.name()], ["$this", this()], ["this", .name()], ["$lock", lock]];
    if (more)
        vars = dict_union(vars, more[1]);
    return vars;
};

public method .try_lock() {
    arg @args;
    
    lock.try(@args);
};

public method .close_cmd() {
    arg cmdstr, cmd, this;
    var vars, m;
    
    catch ~locked
        .try_lock(sender());
    with
        return (traceback()[1])[2];
    if (closable) {
        if (closed) {
            return ((.name()).capitalize()) + " is already closed.";
        } else {
            closed = 1;
            vars = #[["$actor", sender()], ["actor", sender().name()], ["$this", this()], ["this", .name()]];
            m = .eval_message("exit-close", $exit, vars);
            source.announce(m);
            dest.announce(m);
        }
    } else {
        return ((.name()).capitalize()) + " cannot be closed.";
    }
};

public method .open_cmd() {
    arg cmdstr, cmd, this;
    var vars, m;
    
    catch ~locked
        .try_lock(sender());
    with
        return (traceback()[1])[2];
    if (closable) {
        if (closed) {
            clear_var('closed);
            vars = #[["$actor", sender()], ["actor", sender().name()], ["$this", this()], ["this", .name()]];
            m = .eval_message("exit-open", $exit, vars);
            source.announce(m);
            dest.announce(m);
        } else {
            return ((.name()).capitalize()) + " is already open.";
        }
    } else {
        return ((.name()).capitalize()) + " cannot be opened.";
    }
};

public method .get_closable() {
    arg @args;
    
    return closable;
};

protected method .clear_closable() {
    arg name;
    
    if (closed)
        (| clear_var('closed) |);
    (| clear_var('closable) |);
};

public method .set_closable() {
    arg name, definer, value;
    
    if (value) {
        closable = 1;
    } else if (dict_contains(this, 'closable)) {
        if (closed)
            (| clear_var('closed) |);
        (| clear_var('closable) |);
    }
};


new object $coord_exit: $exit;

var $root manager = $coord_exit;
var $coord_exit coordinates = 0;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848977724;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $described prose = [];
var $exit source = $nowhere;
var $exit dest = $nowhere;
var $exit lock = <$true_lock_frob, []>;
var $root inited = 1;
var $root managed = [$coord_exit];

public method .coordinates() {
    return coordinates || [0, 0, 0];
};

public method .configure() {
    arg set;
    var s, radial, azimuth, distance, ans, c, dist, m;
    
    set = (> pass(set) <);
    if (set.contains('exit_coordinates))
        return set;
    s = sender();
    if (!(| s.get_setting("experienced", $user) |))
        s.tell($place_lib.build_hint(5));
    while (1) {
        ans = (> s.prompt(((("Exit coordinates for " + (.name())) + " (to ") + ((.dest()).name())) + ") ") <);
        if (ans == "@skip")
            return set;
        if (ans == "@shortcuts") {
            s.tell(["-- Coordinate Shortcuts:", map c in ($place_lib.coordinate_shortcuts()) to (strfmt(" %20l %7l %s", c[1], @c[2]))]);
            continue;
        }
        if (!ans) {
            s.tell("Invalid Coordinates.");
            continue;
        }
        catch ~coordnf, ~invcoord {
            if (ans.is_numeric()) {
                ans = ans.explode_english_list();
                if ((ans.length()) != 2) {
                    s.tell("Seperate coordinates with a comma.");
                    continue;
                }
                if ((!((ans[1]).is_numeric())) || (!((ans[2]).is_numeric()))) {
                    s.tell("Invalid coordinates.");
                    continue;
                }
                if ((!((ans[1]).is_numeric())) || (!((ans[2]).is_numeric()))) {
                    s.tell("Invalid coordinates.");
                    continue;
                }
                radial = toint(ans[1]);
                azimuth = toint(ans[2]);
            } else {
                ans = $place_lib.coordinates(ans);
                radial = ans[1];
                azimuth = ans[2];
            }
            (> $place_lib.valid_coordinates(radial, azimuth) <);
        } with {
            s.tell((traceback()[1])[2]);
            continue;
        }
    }
    while (!dist) {
        ans = (> s.prompt(("Distance from center of room (metric) [" + ($place_lib.get_default('distance))) + "] ") <);
        if (!ans)
            dist = $place_lib.get_default('distance);
        else if (ans == "@skip")
            return set;
        else if ((m = match_regexp(ans, "^ *([0-9]+) *M *$")))
            dist = toint(m[1]) * 100;
        else if ((m = match_regexp(ans, "^ *([0-9]+) *C?M? *$")))
            dist = toint(m[1]);
        else
            s.tell("Distance must be either centimeters (cm) or meters (m).");
    }
    coordinates = [radial, azimuth, dist];
    return set.add('exit_coordinates);
};

public method .uninit_coord_exit() {
    (| clear_var('coordinates) |);
};


new object $weather_system: $misc;

var $root manager = $weather_system;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855309892;
var $root inited = 1;
var $root managed = [$weather_system];


new object $climate: $has_commands, $weather_system;

var $root manager = $climate;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 839895133;
var $has_commands shortcuts = #[];
var $has_commands remote = #[["@list-climate", [["@list-climate", "*", "@list-climate <this>", 'show_cmd, #[[1, ['this, []]]]]]], ["@setup", [["@setup", "* seasons * daylengths *", "@setup <this> seasons <any> daylengths <any>", 'setup_cmd, #[[1, ['this, []]], [3, ['any, []]], [5, ['any, []]]]]]], ["@add-weather", [["@add-weather", "* type * prob?abilities *", "@add-weather <this> type <descendant of $weather> prob?abilities <any>", 'add_weather_cmd, #[[1, ['this, []]], [3, ['descendant, [$weather]]], [5, ['any, []]]]]]], ["@del-weather", [["@del-weather", "* type *", "@del-weather <this> type <descendant of $weather>", 'del_weather_cmd, #[[1, ['this, []]], [3, ['descendant, [$weather]]]]]]]];
var $has_commands local = #[];
var $root inited = 1;
var $climate seasons = [];
var $climate weathers = #[];
var $root managed = [$climate];
var $climate daylengths = [];
var $root help_node = $help_sys_climate;
var $climate realm = $realm_of_creation;
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];

public method .setup_cmd() {
    arg cmdstr, cmd, this, p, vals, p, dls;
    var s, line, attrs, att2, extras, ex2, i;
    
    (> .perms(sender()) <);
    seasons = vals.explode();
    daylengths = map i in (dls.explode()) to (toint(i));
    weathers = #[];
    return ("Seasons: " + (seasons.to_english())) + ". The weather list has been wiped.";
};

public method .add_weather_cmd() {
    arg cmdstr, cmd, this, p1, weather, p2, probs;
    var i;
    
    (> .perms(sender()) <);
    probs = map i in (probs.explode()) to (toint(i));
    if ((probs.length()) != (seasons.length()))
        throw(~parse, "Wrong number of probabilities.");
    weathers = weathers.add(weather, probs);
    return ("Weather `" + (weather.name())) + "' added.";
};

public method .del_weather_cmd() {
    arg cmdstr, cmd, this, p1, weather;
    var i;
    
    (> .perms(sender()) <);
    if (!(weathers.contains(weather)))
        return "That weather doesn't belong to this climate.";
    weathers = weathers.del(weather);
    return ("Weather `" + (weather.name())) + "' removed.";
};

public method .show_cmd() {
    arg cmdstr, cmd, this;
    var out, x, i, hdr;
    
    if (definer() == this())
        return "The base climate object does not define anything--refer to its children.";
    hdr = [];
    for x in [1 .. listlen(seasons)] {
        i = (((seasons[x]) + " (") + (daylengths[x])) + ")";
        hdr += [[i, pad("", strlen(i), "-")]];
    }
    return ((map i in (weathers) to ([(i[1]).name(), @i[2]]).transpose()).tabulate([["Weather type", "------------"]] + hdr)) + ["---"];
};

public method .advance() {
    arg current, season, dependancies;
    var dists, i, w, d, fuzz;
    
    fuzz = 3;
    dists = ._probabilities(current, season, fuzz);
    dists = dists.sort(dists.slice(2));
    for i in (dependancies) {
        d = (i[1]).get_setting("weather-time", $realm);
        dists += ((i[2]) * ((d[3])._probabilities(d[1], d[2], fuzz))) / 100;
    }
    w = random(10000);
    i = 1;
    d = 0;
    while ((i <= (dists.length())) && ((d += (dists[i])[2]) < w))
        i++;
    if (i > (dists.length()))
        i--;
    return (dists[i])[1];
};

public method ._probabilities() {
    arg from, season, fuzz;
    var i, j, attr, refattr, dists, sum, t;
    
    season = season in seasons;
    refattr = from.attributes();
    dists = map i in (weathers.keys()) to (refresh() && [i, (100 * ((weathers[i])[season])) / (fuzz + ((type((t = (| map j in [1 .. (attr = i.attributes()).length()] to (abs((attr[j]) - (refattr[j]))).sum() |))) == 'error) ? 1000000 : t))]);
    
    // normalize the list - the sum should be around 10,000
    sum = (dists.slice(2)).sum();
    return map i in (dists) to ([i[1], ((i[2]) * 10000) / sum]);
};

public method .ctext_variables() {
    arg current, season;
    var vars;
    
    vars = #[["weather", current.name()], ["weather_desc", current.prose()], ["season", season]];
    vars = dict_union(vars, current.attribute_vars());
    return vars;
};

public method .daylength() {
    arg season;
    
    return daylengths[season in seasons];
};

public method .match_weather() {
    arg weather_str;
    var i, out;
    
    if ((out = find i in (weathers.keys()) where ((i.name()) == weather_str)))
        return (weathers.keys())[out];
    if ((out = find i in (weathers.keys()) where (weather_str.match_begin(i.name()))))
        return (weathers.keys())[out];
    throw(~keynf, "No such weather in this climate.");
};

public method .realm() {
    return realm;
};


new object $climate_creation: $climate;

var $root manager = $climate_creation;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 839896989;
var $climate seasons = ["spring", "summer", "fall", "winter"];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $root inited = 1;
var $climate daylengths = [0, 2, 0, -2];
var $climate weathers = #[[$weather_nice, [50, 40, 20, 10]], [$weather_hot, [30, 60, 10, 2]], [$weather_windy, [10, 5, 10, 15]], [$weather_stormy, [0, 10, 0, 0]], [$weather_rainy, [30, 20, 60, 40]], [$weather_snowy, [10, 1, 10, 40]]];
var $root managed = [$climate_creation];
var $climate realm = $realm_of_creation;


new object $weather_attributes: $has_commands, $weather_system;

var $root manager = $weather_attributes;
var $weather_attributes attributes = #[["precipitation", ["fine", "drizzle", "rain", "shower", "snow"]], ["humidity", ["dry", "fine", "humid"]], ["temperature", ["hot", "warm", "cold", "freezing"]], ["visibility", ["clear", "hazy", "murky"]], ["clouds", ["clear", "cloudy", "overcast"]], ["wind", ["serene", "windy", "stormy"]]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855309872;
var $has_commands shortcuts = #[];
var $has_commands remote = #[["@awa", [["@awa", "* values * to *", "@awa <any> values <any> to <this>", 'add_attrib_cmd, #[[1, ['any, []]], [3, ['any, []]], [5, ['this, []]]]]]], ["@dwa", [["@dwa", "* from *", "@dwa <any> from <this>", 'del_attrib_cmd, #[[1, ['any, []]], [3, ['this, []]]]]]], ["@lwa", [["@lwa", "*", "@lwa <this>", 'list_attribs_cmd, #[[1, ['this, []]]]]]], ["@aea", [["@aea", "* values * to *", "@aea <any> values <any> to <this>", 'add_extra_cmd, #[[1, ['any, []]], [3, ['any, []]], [5, ['this, []]]]]]], ["@add-weather-attribute", [["@add-weather-attribute", "* values * to *", "@add-weather-attribute <any> values <any> to <this>", 'add_attrib_cmd, #[[1, ['any, []]], [3, ['any, []]], [5, ['this, []]]]]]], ["@del-weather-attribute", [["@del-weather-attribute", "* from *", "@del-weather-attribute <any> from <this>", 'del_attrib_cmd, #[[1, ['any, []]], [3, ['this, []]]]]]], ["@list-weather-attributes", [["@list-weather-attributes", "*", "@list-weather-attributes <this>", 'list_attrib_cmd, #[[1, ['this, []]]]]]], ["@add-extra-attribute", [["@add-extra-attribute", "* values * to *", "@add-extra-attribute <any> values <any> to <this>", 'add_extra_cmd, #[[1, ['any, []]], [3, ['any, []]], [5, ['this, []]]]]]]];
var $has_commands local = #[];
var $root inited = 1;
var $weather_attributes extra_attributes = #[];
var $root help_node = $help_sys_weather_attributes;
var $root managed = [$weather_attributes];

public method .add_attrib_cmd() {
    arg cmdstr, cmd, name, p1, vals, p2, p3;
    
    (> .perms(sender()) <);
    vals = (vals.explode(";")).mmap('trim);
    attributes = (attributes || #[]).add(name, vals);
    return ("Defined attributes: " + ((attributes.keys()).to_english())) + ".";
};

public method .list_attribs_cmd() {
    arg @who_cares;
    var i, a1, a2;
    
    a1 = attributes ? map i in (attributes) to ("@awa %l values %l to %l".format(i[1], (i[2]).join(";"), definer())) : [];
    a2 = extra_attributes ? map i in (extra_attributes) to ("@aea %l values %l to %l".format(i[1], (i[2]).join(";"), definer())) : [];
    return ["Weather attributes:", @a1, @a2, "---"];
};

public method .add_extra_cmd() {
    arg cmdstr, cmd, name, p1, vals, p2, p3;
    
    (> .perms(sender()) <);
    vals = (vals.explode(";")).mmap('trim);
    extra_attributes = (extra_attributes || #[]).add(name, vals);
    return ("Defined extra attributes: " + ((extra_attributes.keys()).to_english())) + ".";
};

public method .del_attrib_cmd() {
    arg cmdstr, cmd, name, @rest;
    
    (> .perms(sender()) <);
    if ((| attributes.contains(name) |)) {
        attributes = attributes.del(name);
        return ("Attribute " + name) + " deleted.";
    } else if ((| extra_attributes.contains(name) |)) {
        extra_attributes = extra_attributes.del(name);
        return ("Extra attribute " + name) + " deleted.";
    } else {
        return name + " not found.";
    }
};

public method .alist_dict() {
    arg attrlist;
    var i, k, v;
    
    k = attributes.keys();
    v = attributes.values();
    return hash i in [1 .. attrlist.length()] to ([k[i], (v[i])[attrlist[i]]]);
};

public method .parse_attribute_list() {
    arg attrlist;
    var i, alist, akeys, out, m, key, val;
    
    alist = (attrlist.explode(";")).mmap('trim);
    akeys = attributes.keys();
    if (!("=" in attrlist)) {
        if ((alist.length()) != (akeys.length()))
            throw(~parse, "Can't parse those weather attributes.");
        alist = ([akeys, alist].transpose()).mmap('join, "=");
    }
    out = #[];
    for i in (alist) {
        if (!(m = i.match_pattern("*=*")))
            throw(~parse, "Entry not of the form attribute=value.");
        key = ((m[1]) in akeys) || find i in [1 .. akeys.length()] where ((akeys[i]).match_begin(m[1]));
        if (!key)
            throw(~parse, "No such attribute.");
        if (!(val = (m[2]) in (attributes[akeys[key]])))
            throw(~parse, "Illegal value for %l:%l.".format(akeys[key], m[2]));
        out = out.add(akeys[key], val);
    }
    if (!(((out.keys()).length()) == (akeys.length())))
        throw(~parse, "Missing attributes.");
    return map i in (akeys) to (out[i]);
};

public method .extra_attributes() {
    return extra_attributes;
};


new object $weather: $described, $weather_system;

var $root manager = $weather;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855309306;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['uniq, "Generic Weather", "the Generic Weather"];
var $described prose = [];
var $root inited = 1;
var $foundation defined_msgs = #[["invoke", #[['branches, ["general"]]]]];
var $foundation msgs = #[["invoke", #[["general", <$ctext_frob, [["The weather has changed to ", <$generator, ["weather", [], [], 'gen_weather]>, "."], #[['this, $weather]]]>]]]];
var $root help_node = $help_sys_weather;
var $root defined_settings = #[["attributes", #[['parse, ['parse_setting_attributes]], ['format, ['format_setting_attributes]]]]];
var $root managed = [$weather];
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];

public method .attributes() {
    return .get_setting("attributes", $weather);
};

public method .attribute_vars() {
    var i, attr, extra, a;
    
    a = .attributes();
    attr = $weather_attributes.alist_dict(a);
    for i in ($weather_attributes.extra_attributes())
        dict_add(attr, @i);
    return attr;
};

public method .parse_setting_attributes() {
    arg value;
    
    if (type(value) == 'list)
        value = (value.join()).trim();
    return (> $weather_attributes.parse_attribute_list(value) <);
};

public method .format_setting_attributes() {
    arg value;
    var i;
    
    return map i in ($weather_attributes.alist_dict(value)) to (((i[1]) + "=") + (i[2])).join("; ");
};


new object $weather_nice: $weather;

var $root manager = $weather_nice;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855447987;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "nice", "nice"];
var $described prose = <$ctext_frob, [["The weather is nice. The sun is shining and all that."], #[['this, $weather_nice]]]>;
var $root inited = 1;
var $root settings = #[["attributes", [1, 2, 2, 1, 1, 1]]];
var $root managed = [$weather_nice];
var $foundation msgs = #[["invoke", #[["general", <$ctext_frob, [["The weather is clear and nice."], #[]]>]]]];


new object $weather_hot: $weather;

var $root manager = $weather_hot;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855462673;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "hot", "hot"];
var $described prose = [];
var $root inited = 1;
var $root settings = #[["attributes", [1, 2, 1, 1, 1, 1]]];
var $root managed = [$weather_hot];


new object $weather_windy: $weather;

var $root manager = $weather_windy;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855462710;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "stormy", "stormy"];
var $described prose = [];
var $root inited = 1;
var $root settings = #[["attributes", [4, 3, 4, 3, 3, 3]]];
var $root managed = [$weather_windy];
var $foundation msgs = #[["invoke", #[["general", <$ctext_frob, [["The wind blows in strong gusts."], #[]]>]]]];


new object $weather_stormy: $weather;

var $root manager = $weather_stormy;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855462768;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "stormy", "stormy"];
var $described prose = [];
var $root inited = 1;
var $root settings = #[["attributes", [4, 3, 2, 3, 3, 3]]];
var $root managed = [$weather_stormy];


new object $weather_rainy: $weather;

var $root manager = $weather_rainy;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855463377;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "rainy", "rainy"];
var $described prose = [];
var $root inited = 1;
var $foundation msgs = #[["invoke", #[["general", <$ctext_frob, [["It starts to rain."], #[['this, $weather_rainy]]]>]]]];
var $root settings = #[["attributes", [3, 3, 3, 3, 3, 1]]];
var $root managed = [$weather_rainy];


new object $weather_snowy: $weather;

var $root manager = $weather_snowy;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855463379;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "snowy", "snowy"];
var $described prose = [];
var $root inited = 1;
var $root settings = #[["attributes", [5, 2, 4, 2, 3, 1]]];
var $root managed = [$weather_snowy];
var $foundation msgs = #[["invoke", #[["general", <$ctext_frob, [["It starts to snow."], #[]]>]]]];


new object $help_node: $has_name;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['uniq, "help_node", "the help_node"];
var $help_node links = 0;
var $help_node body = 0;
var $root trusted_by = [$help_index_driver, $help_index_core, $help_index_cmds, $help_index_subsystem, $help_index_function, $help_index_objects, $help_updates, $help_sys_weather, $help_sys_weather_attributes, $help_sys_climate, $help_weather_system];
var $root manager = $help_node;
var $help_node group = 0;
var $foundation edit_types = ["help"];
var $help_node nolist = 1;
var $help_node index = 0;
var $help_node holder = 0;
var $root defined_settings = #[["nolist", #[['get, ['nolist]], ['set, ['set_nolist]], ['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["group", #[['get, ['group]], ['set, ['set_group]], ['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["index", #[['get, ['get_index_setting]], ['set, ['set_index_setting]], ['parse, ['parse_index_setting]], ['format, ['format_index]]]], ["holder", #[['get, ['get_holder_setting]], ['set, ['set_holder_setting]], ['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $root help_node = $help_obj_help_node;
var $root managed = [$help_node];

root method .init_help_node() {
    links = #[];
    .set_body(["This node isn't written yet"]);
};

root method .uninit_help_node() {
    var obj;
    
    if (index)
        (| index.node_going_away() |);
    links = #[];
    body = [];
    $help_updates.touched();
};

public method .index_going_away() {
    (> .perms(caller(), $help_index) <);
    (| clear_var('index) |);
};

public method .set_body() {
    arg new_body;
    var new_body, anchors, key, keys, values, value;
    
    (> .perms(sender()) <);
    
    // Compile a string into help ctext
    new_body = $compiler.compile_cml(new_body);
    body = new_body;
    anchors = (| new_body.get_var('links) |) || #[];
    body = (<$ctext_frob, [body._ctext(), (| (body.vars()).del('links) |) || (body.vars())]>);
    keys = anchors.keys();
    values = anchors.values();
    links = #[];
    for key in (keys)
        links = links.add(key, $object_lib.to_dbref(anchors[key]));
    if ((!(.has_ancestor($help_index))) && (!(this() == $help_updates)))
        $help_updates.touched();
};

public method .body() {
    return body;
};

public method .links() {
    return links || #[];
};

public method .node_going_away() {
    var node;
    
    (> .perms(caller(), $help_node) <);
    node = sender();
    
    // do something intelligent with the text body as well
    links = links.del(node);
};

protected method .get_index_setting() {
    arg @args;
    
    return index || 0;
};

public method .traverse() {
    var n, out;
    
    // traverse the higherarchy with a depth-first priority rather than width
    out = [this()];
    for n in (children())
        out += n.traverse();
    return out;
};

protected method .set_index_setting() {
    arg name, definer, value, @args;
    
    ._set_index(value);
};

public method .node_name() {
    var name;
    
    if (this() == definer())
        return "";
    name = ((.parents())[1]).node_name();
    if (!name)
        return (.name()).word(1, "|");
    return (name + ": ") + ((.name()).word(1, "|"));
};

public method .html_node_name() {
    arg @this;
    var name, index, hname;
    
    if (this() == definer())
        return "";
    name = ((.parents())[1]).html_node_name();
    if (this)
        hname = (.name()).word(1, "|");
    else if (holder)
        hname = ("<i>" + ((.name()).word(1, "|"))) + "</i>";
    else
        hname = ((("<a href=\"/bin/help?node=" + this()) + "\">") + ((.name()).word(1, "|"))) + "</a>";
    if (!name)
        return hname;
    return (name + ": ") + hname;
};

public method .set_name() {
    arg new, @ignore;
    var old;
    
    if ("=" in new)
        throw(~perm, "You cannot have \"=\" in a help node name.");
    old = .name();
    (> pass(new, 'prop) <);
    if (index)
        index.node_changed_name(old);
};

public method .edit_help() {
    var p;
    
    (> .perms(sender()) <);
    p = (.body()).uncompile();
    (> sender().invoke_editor(this(), '_edit_help_callback, p, []) <);
};

public method ._edit_help_callback() {
    arg text, client_data;
    
    (> .perms(caller(), $editor_reference) <);
    .set_body(text);
    return ['success, ["Help node body set."]];
};

public method .group() {
    arg @args;
    
    return !group;
};

public method .nolist() {
    arg @args;
    
    return nolist;
    
    // whether or not this node should be listed as a 'descendant' node of
    // its parent.
};

protected method .set_group() {
    arg name, definer, value, @args;
    
    // invert it, more db friendly this way since 99% of the nodes want groups
    value = !value;
    if (value)
        group = value;
    else
        (| clear_var('group) |);
};

protected method .set_nolist() {
    arg name, definer, value, @args;
    
    nolist = value;
};

public method .top_of_help_heirarchy() {
    return definer() == this();
};

public method .index() {
    return index;
};

public method .set_index() {
    arg index;
    
    (> .perms(sender()) <);
    return (> ._set_index(index) <);
};

protected method ._set_index() {
    arg i;
    
    if (index)
        (| index.del_help_node(this()) |);
    if (!i) {
        clear_var('index);
        return;
    }
    index = i;
    (> index.add_help_node(this()) <);
};

protected method .set_holder_setting() {
    arg name, definer, value, @args;
    
    if (value)
        holder = 1;
    else if (holder)
        clear_var('holder);
};

protected method .get_holder_setting() {
    arg @args;
    
    return holder;
};

public method .holder() {
    return holder;
};

public method .small_name() {
    return ((.name()).word(1, "|")).word(1);
};

protected method .parse_index_setting() {
    arg value, @args;
    var i;
    
    if (!value)
        return 0;
    if ((value[1]) == "$") {
        i = (> $object_lib.to_dbref(value) <);
        if (!(i.has_ancestor($help_index)))
            throw(~bad, ("\"" + (i.namef('ref))) + "\" is not a help index.");
    } else {
        value = strsed(value, " *index *", "");
        if (!(i = $help_index.match_children(value)))
            throw(~bad, ("\"" + value) + "\" is not a help index.");
    }
    return i;
};

public method .format_index() {
    arg value;
    
    if (!value)
        return "";
    return (((value.name()) + " INDEX (") + value) + ")";
};

public method .dump_to_disk() {
    arg fh, curdir;
    var child;
    
    (> .perms(sender(), @.parents()) <);
    (| fh.close() |);
    if (!(fh.is($file)))
        throw(~arg, "First argument must be a $file");
    curdir = .dump_to_disk__store(fh, curdir);
    for child in (.children()) {
        pause();
        child.dump_to_disk(fh, curdir);
    }
};

private method .dump_to_disk__store() {
    arg fh, curdir;
    var fname, stat, body, s, set, n, p, head, tail;
    
    body = .body();
    if (!body)
        return curdir;
    fname = tostr(.objname());
    fname = strsed(fname, "^help_", "");
    if (((.children()).length()) > 0) {
        curdir += "/" + fname;
        if (!(| fh.fstat(curdir) |)) {
            if (!(> fh.fmkdir(curdir) <))
                throw(~failed, ("Cannot mkdir(" + curdir) + ")");
        }
        fname = "index";
    }
    
    // write out the CML first...
    stat = (> fh.open(((curdir + "/") + fname) + ".cml", ">") <);
    set = "@set " + this();
    for s in (["group", "holder", "index", "nolist"])
        fh.fwrite((((set + ":") + s) + "=") + (.get_setting(s, $help_node)));
    fh.fwrite("@hwrite " + this());
    for s in ((.body()).uncompile()) {
        fh.fwrite(s);
        refresh();
    }
    fh.fwrite(".");
    fh.fclose();
    
    // now write our HTML...
    //  stat = (> fh.open(curdir + "/" + fname + ".html", ">") <);
    // fh.close();
    return curdir;
};


new object $db: $misc;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $db database = #[];
var $root manager = $db;
var $root managed = [$db];

root method .init_db() {
    database = #[];
};

public method .database() {
    return database;
};

public method .value_changed() {
    arg key, new_value;
    
    // change the value of a key.
    if ((!(sender() == this())) && (!(.trusts(caller()))))
        (> .perms(sender(), 'writer) <);
    (> .remove(key) <);
    (> .insert(key, new_value) <);
};

public method .remove() {
    arg key;
    
    // remove a key/value from the database
    if ((!(sender() == this())) && (!(.trusts(caller()))))
        (> .perms(sender(), 'writer) <);
    database = database.del(key);
};

public method .exact_match() {
    arg key;
    var match;
    
    // get an exact match of a key, return the value
    match = (| (type(database) == 'dictionary) ? (database[key]) : ((database.match_exact(key))[2]) |);
    if (match == ~keynf)
        throw(~matchnf, ("No object by the key \"" + key) + "\" exists.");
    return match;
};

public method .match_begin() {
    arg key;
    var matches, entry;
    
    // First check if we're using $trie frob
    if (type(database) == 'frob) {
        matches = (| (database.match_begin(key))[2] |);
        if (matches == ~keynf)
            throw(~matchnf, "No entries in the database match that key.");
        if (matches == ~ambig)
            throw(~ambig, "More than one object matches that key.");
        return matches;
    }
    
    // use match_begin of the key, return the value
    matches = [(| .exact_match(key) |)];
    if (!(matches[1])) {
        matches = [];
        for entry in (database) {
            if (match_begin(entry[1], key))
                matches = setadd(matches, entry[2]);
        }
    }
    if (matches) {
        if ((matches.length()) == 1)
            return matches[1];
        else
            throw(~ambig, "More than one object matches that key.", matches);
    } else {
        throw(~matchnf, "No entries in the database match that key.");
    }
};

public method .insert() {
    arg key, value;
    
    // insert a key/value to the database
    if ((!(sender() == this())) && (!(.trusts(caller()))))
        (> .perms(sender(), 'writer) <);
    database = database.add(key, value);
};

root method .uninit_db() {
    database = 0;
};

public method .key_changed() {
    arg old_key, new_key;
    var val;
    
    // change the value of a key.
    if ((!(sender() == this())) && (!(.trusts(caller()))))
        (> .perms(sender(), 'writer) <);
    val = (> .exact_match(old_key) <);
    .remove(old_key);
    .insert(new_key, val);
};

protected method .set_database() {
    arg newdb;
    
    // this should not be called often, its primarily for corification
    database = newdb;
};

protected method .clean_database() {
    var elem;
    
    // clean up a  "STR"=>$obj  style database
    for elem in (database) {
        if (!valid(elem[2]))
            database = database.del(elem[1]);
    }
};


new object $registry: $db;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $db database = #[];
var $registry stripped_characters = "";
var $registry min_char_len = 0;
var $registry max_char_len = 0;
var $registry max_word_len = 0;
var $registry reserved_names = [];
var $registry invalid_names = [];
var $root manager = $registry;
var $root managed = [$registry];
var $registry stripped = 0;

public method .set_max_word_len() {
    arg value;
    
    (> .perms(sender(), 'manager) <);
    if (type(value) != 'integer)
        throw(~type, "Value is not an integer");
    max_word_len = value;
};

public method .set_max_char_len() {
    arg value;
    
    (> .perms(sender(), 'manager) <);
    if (type(value) != 'integer)
        throw(~type, "Value is not an integer");
    max_char_len = value;
};

public method .set_min_char_len() {
    arg value;
    
    (> .perms(sender(), 'manager) <);
    if (type(value) != 'integer)
        throw(~type, "Value is not an integer");
    min_char_len = value;
};

public method .insert() {
    arg name, obj;
    
    // registers obj with obj.name
    if ((!(.trusts(caller()))) && ((!sender()) == this()))
        throw(~perm, "Permission denied.");
    name = .strip_key(name);
    (> pass(name, obj) <);
};

public method .remove() {
    arg name;
    
    // removes the object from the database.
    // THIS: is what is broken with guests, should fix it.
    if ((!(.trusts(caller()))) && (sender() != this()))
        throw(~perm, "Permission denied.");
    name = .strip_key(name);
    (> pass(name) <);
};

public method .database() {
    if (!(.has_flag('variables, sender())))
        throw(~perm, "Database is not readable by sender.");
    return (> pass() <);
};

public method .exact_match() {
    arg name;
    
    // returns a direct match of the name (if there is one)
    if (!(.has_flag('variables)))
        throw(~perm, "Database is not readable by sender.");
    name = .strip_key(name);
    return (> pass(name) <);
};

public method .valid_name() {
    arg name;
    var word, sname, matched_obj, m;
    
    // returns 1 if the name is valid
    /// if (!.has_flag('variables,sender()))
    //    throw(~perm, "Database is not readable by sender.");
    (> .perms(caller(), 'trusts) <);
    
    // check name itself first
    sname = .strip_key(name);
    if (max_word_len && (listlen(name.explode()) > max_word_len))
        throw(~invname, ("Names can only be " + max_word_len) + " words long.");
    if (min_char_len && (strlen(sname) < min_char_len))
        throw(~invname, ("Names must have at least " + min_char_len) + " alpha-numeric characters in them");
    if (max_char_len && ((name.length()) > max_char_len))
        throw(~invname, ("Names can only be " + max_char_len) + " characters long.");
    
    // see if it already exists
    if ((| (matched_obj = .exact_match(name)) |)) {
        if (matched_obj != sender())
            throw(~invname, ((("The name \"" + name) + "\" conflicts with the existing user \"") + (matched_obj.name())) + "\"");
    }
    
    // check reserved and invalid names
    if (sname in (.reserved_names()))
        throw(~invname, ("`" + name) + "' is a reserved name.");
    if (invalid_names && (m = regexp(sname, invalid_names)))
        throw(~invname, ("`" + (m[2])) + "' is not allowed as part of a name.");
};

public method .match_begin() {
    arg name;
    var matches, obj;
    
    // returns a direct match, or partial matches
    name = .strip_key(name);
    if (!name)
        throw(~matchnf, "No entries in the database match that key.");
    return (> pass(name) <);
};

public method .strip_key() {
    arg key;
    
    anticipate_assignment();
    if (stripped)
        return key.strip();
    return key;
};

public method .key_changed() {
    arg old_name, new_name;
    
    // adjusts the database for the new name
    if ((!(.trusts(caller()))) && (sender() != this()))
        throw(~perm, "Permission denied.");
    old_name = .strip_key(old_name);
    new_name = .strip_key(new_name);
    (> pass(old_name, new_name) <);
};

public method .search() {
    arg name;
    var tmp;
    
    name = .strip_key(name);
    name || throw(~namenf, "No matches found.");
    tmp = (| .exact_match(name) |);
    if (tmp)
        return tmp;
    catch any {
        tmp = (> .match_begin(name) <);
    } with {
        switch (error()) {
            case ~ambig:
                rethrow(error());
            default:
                throw(~namenf, "No matches found.");
        }
    }
    return tmp;
};

public method .reserved_names() {
    return reserved_names || [];
};


new object $help_index: $has_name, $registry, $help_node;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Index", "Index"];
var $db database = #[];
var $root manager = $help_index;
var $root managed = [$help_index];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[], #[]]>;
var $help_index dirty = 1;
var $help_node holder = 1;
var $help_node nolist = 0;

root method .init_help_index() {
    .add_trusted($help_node);
};

root method .uninit_help_index() {
    var key;
    
    for key in ((.database()).keys())
        (.match_exact(key)).index_going_away();
};

public method .add_help_node() {
    arg node;
    var part;
    
    if ((caller() != $help_node) && (!(.is_writable_by(caller()))))
        throw(~perm, "Permission denied.");
    for part in ((node.name()).explode("|"))
        .insert(part, node);
};

public method .del_help_node() {
    arg node;
    var part;
    
    if ((!(caller() in [$help_node, definer()])) && ((!(.is_writable_by(sender()))) && (sender() != this())))
        throw(~perm, "Permission denied.");
    for part in ((node.name()).explode("|"))
        .remove(part);
};

public method .node_going_away() {
    (> .perms(caller(), $help_node) <);
    .del_help_node(sender());
};

public method .body() {
    var key, out, body, col, db;
    
    body = pass();
    if (dirty || (!body)) {
        (| clear_var('dirty) |);
        db = .database();
        out = ["{table cols=25%,25%,25%,25%:"];
        for key in ((db.keys()).sort()) {
            if (!col)
                out += ["{tr:"];
            out += [((("{td:{link node=" + (db[key])) + ":") + key) + "}}"];
            if (col == 3) {
                out += ["}"];
                col = 0;
            } else {
                col++;
            }
        }
        if (col != 0)
            out += ["}}"];
        else
            out += ["}"];
        .set_body(out);
        body = pass();
    }
    return body;
};

public method .node_name() {
    return (.name()) + " INDEX";
};

public method .html_node_name() {
    arg @args;
    
    return .node_name();
};

public method .insert() {
    arg name, obj;
    
    (> pass(name, obj) <);
    dirty++;
};

public method .remove() {
    arg name;
    
    (> pass(name) <);
    dirty++;
};

public method .node_changed_name() {
    arg old;
    var node, part;
    
    (> .perms(caller(), $help_node) <);
    node = sender();
    for part in (old.explode("|"))
        (| .remove(part) |);
    for part in ((node.name()).explode("|"))
        (| .insert(part, node) |);
};

public method .strip_key() {
    arg key;
    
    anticipate_assignment();
    return key.strip("!#$%^&*()");
};

root method .core_help_index(): nooverride {
    .set_body("");
    .clean_database();
    dirty++;
};

public method .reset_index() {
    var v, part, dbv;
    
    (> .perms(sender()) <);
    dirty++;
    dbv = ((.database()).values()).compress();
    .set_database(#[]);
    for v in (dbv) {
        if (valid(v)) {
            for part in ((v.name()).explode("|"))
                (| .insert(part, v) |);
        }
    }
};


new object $help_index_driver: $help_index;

var $root manager = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837910423;
var $db database = #[["Object Oriented Programming", $help_coldc_oop], ["OOP", $help_coldc_oop], ["Regexps", $help_coldc_regexp], ["Regular Expressions", $help_coldc_regexp], ["Integer", $help_coldc_types_ints], ["Number", $help_coldc_types_ints], ["Object Number", $help_coldc_types_dbref], ["objnum", $help_coldc_types_dbref], ["Object Name", $help_coldc_types_dbref], ["objname", $help_coldc_types_dbref], ["dbref", $help_coldc_types_dbref], ["Error Codes", $help_coldc_types_errors], ["Error-Handling", $help_coldc_err_stmts], ["catch", $help_coldc_err_stmts], ["Overridden Methods", $help_coldc_mcall_over], ["override", $help_coldc_mcall_over], ["if-else", $help_coldc_cond_ifelse], ["else", $help_coldc_cond_ifelse], ["Increment", $help_coldc_incdec], ["Decrement", $help_coldc_incdec], ["Objects", $help_coldc_objs], ["Textdump", $help_coldc_textdump], ["Functions", $help_coldc_func], ["Native Method Reference", $help_coldc_native], ["Referencing Objects", $help_coldc_objs_ref], ["Variables", $help_coldc_objs_vars], ["Special Object Status", $help_coldc_objs_special], ["Tokens", $help_coldc_tokens], ["Data Types", $help_coldc_types], ["Expressions", $help_coldc_expr], ["Statements", $help_coldc_stmts], ["Tasks and Frames", $help_coldc_tasks], ["Errors", $help_coldc_types_errors], ["Security", $help_coldc_security], ["Networking", $help_coldc_net], ["Files", $help_coldc_files], ["Float", $help_coldc_types_floats], ["String", $help_coldc_types_strings], ["Symbol", $help_coldc_types_symbols], ["List", $help_coldc_types_lists], ["Dictionary", $help_coldc_types_dicts], ["Frob", $help_coldc_types_frobs], ["Buffer", $help_coldc_types_buffers], ["Data", $help_coldc_data], ["Operators", $help_coldc_ops], ["Variable Expression", $help_coldc_vars], ["Function Call Expression", $help_coldc_fcall], ["Method Call Expression", $help_coldc_mcall], ["Error Handling Expression", $help_coldc_err_expr], ["Looping Expressions", $help_coldc_loop_expr], ["Simple", $help_coldc_simple_stmts], ["Looping Statements", $help_coldc_loop_stmts], ["Flags", $help_coldc_methods_flags], ["Access", $help_coldc_methods_access], ["Frames", $help_coldc_tasks_frames], ["Preempting", $help_coldc_tasks_preempt], ["Server Connection", $help_coldc_net_server], ["Client Connection", $help_coldc_net_client], ["Operator Precedence", $help_coldc_prec], ["Index Operators", $help_coldc_index], ["Arithmetic Operators", $help_coldc_arith], ["Assignments", $help_coldc_assign], ["Logical Operators", $help_coldc_logical], ["Conditional", $help_coldc_cond], ["List Splice Operator", $help_coldc_splice], ["map", $help_coldc_map], ["hash", $help_coldc_hash], ["find", $help_coldc_find], ["filter", $help_coldc_filter], ["Comment", $help_coldc_comment_stmt], ["Compound", $help_coldc_compound_stmt], ["Return", $help_coldc_return_stmt], ["if", $help_coldc_cond_if], ["switch", $help_coldc_cond_switch], ["for-list", $help_coldc_forlist], ["for-range", $help_coldc_forrange], ["while", $help_coldc_while], ["break", $help_coldc_break], ["continue", $help_coldc_continue], ["Scatter", $help_coldc_scatter_assign], ["Dual", $help_coldc_dual_assign], ["Default", $help_coldc_default_assign], ["Methods", $help_coldc_methods], ["ColdC Reference Manual", $help_coldc]];
var $has_name name = ['prop, "Driver", "Driver"];
var $registry stripped_characters = "!@#$%^&*()";
var $root trusted = [$help_node];
var $root inited = 1;
var $root managed = [$help_index_driver];
var $help_node body = <$ctext_frob, [[], #[]]>;
var $help_node links = #[];
var $help_node nolist = 0;
var $help_index dirty = 6;


new object $help_index_core: $help_index;

var $root manager = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837910430;
var $db database = #[["CML", $help_cml], ["Cold Markup Language", $help_cml], ["Heap", $help_heap], ["General Information", $help_general], ["Building", $help_building], ["Programming", $help_prog], ["Reference Library", $help_reference], ["Weather System", $help_weather_system], ["Mutex", $help_mutex], ["Conventions", $help_conventions], ["Objects", $help_objects], ["Environment", $help_environment], ["Appearance", $help_appearance], ["Commands", $help_commands], ["Interaction", $help_interaction], ["Interface", $help_interface], ["Theme", $help_theme], ["Places", $help_build_places], ["Programming Commands", $help_prog_commands], ["Climate", $help_sys_climate], ["Weather", $help_sys_weather], ["Attributes", $help_sys_weather_attributes], ["Names", $help_app_names], ["Description", $help_app_desc], ["Gender", $help_app_gender], ["Wearing", $help_app_wearing], ["VR vs Non-VR", $help_commands_vr], ["Matching Conventions", $help_commands_matching], ["Clients", $help_interface_client], ["Format", $help_interface_format], ["Settings", $help_settings], ["Formatters", $help_cml_formatters], ["Generators", $help_cml_generators], ["Environment Conditions", $help_places_env], ["Security", $help_security], ["Administration", $help_admin], ["Credit", $help_credit], ["COPYRIGHT", $help_copyright], ["Groups", $help_security_groups], ["Traceback Recording", $help_traceback_recording], ["Help", $help_help], ["@help", $help_help], ["Heirarchy", $help_help_heirarchy], ["Options", $help_help_options], ["Searching", $help_help_searching], ["Object-Levels", $help_security_levels], ["Pathways", $help_places_paths], ["paths", $help_places_paths], ["exits", $help_places_paths], ["entrances", $help_places_paths], ["Permissions", $help_places_perms], ["Builder Permissions", $help_places_perms], ["perms", $help_places_perms], ["Cold Help System", $help_coldcore]];
var $has_name name = ['prop, "Core", "Core"];
var $registry stripped_characters = "!@#$%^&*()";
var $root trusted = [$help_node];
var $root inited = 1;
var $root managed = [$help_index_core];
var $help_node body = <$ctext_frob, [[], #[]]>;
var $help_node links = #[];
var $help_node nolist = 0;
var $help_index dirty = 1;


new object $help_index_cmds: $help_index;

var $root manager = $help_index_cmds;
var $help_node links = #[];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043048;
var $db database = #[["@add-command", $help_cmd_addcmd], ["@ac", $help_cmd_addcmd], ["@del-command", $help_cmd_delcmd], ["@dc", $help_cmd_delcmd], ["@def-msg", $help_cmd_defmsg], ["@undef-msg", $help_cmd_defmsg], ["@nh", $help_cmd_nh], ["@new-help-node", $help_cmd_nh], ["@ant", $help_cmd_ant], ["@add-name-template", $help_cmd_ant], ["@dnt", $help_cmd_dnt], ["@del-name-template", $help_cmd_dnt], ["say", $help_cmd_say], ["emote", $help_cmd_emote], ["to say", $help_cmd_tosay], ["whisper", $help_cmd_whisper], ["@page", $help_cmd_page], ["think", $help_cmd_think], ["@display", $help_cmd_display], ["@program", $help_cmd_program], ["@set", $help_cmd_set], ["@adjust", $help_cmd_adjust], ["@mojo", $help_cmd_mojo], ["@rehash-all", $help_cmd_rehashall], ["@backup", $help_cmd_backup], ["@shutdown", $help_cmd_shutdown], ["@tasks", $help_cmd_tasks], ["@kill", $help_cmd_kill], ["@reap", $help_cmd_reap], ["@core", $help_cmd_core], ["@descendants", $help_cmd_descendants], ["@describe", $help_cmd_describe], ["@new", $help_cmd_new], ["@spawn", $help_cmd_spawn], ["@rename", $help_cmd_rename], ["@remember", $help_cmd_remember], ["@msg", $help_cmd_msg], ["@read", $help_mail_read], ["@mail", $help_mail_mail], ["@subscribe", $help_mail_subscribe], ["@unsubscribe", $help_mail_unsubscribe], ["@mail-lists", $help_mail_mail_lists], ["@send", $help_mail_send], ["@nn", $help_mail_next_new], ["@rmmail", $help_mail_rmmail], ["@reply", $help_mail_reply], ["@list", $help_cmd_list], ["@show", $help_cmd_show], ["@help-list", $help_cmd_hlist], ["@hlist", $help_cmd_hlist], ["@hl", $help_cmd_hlist], ["@help-write", $help_cmd_hwrite], ["@hwrite", $help_cmd_hwrite], ["@hw", $help_cmd_hwrite], ["@boot", $help_cmd_boot], ["@rehash", $help_cmd_rehash], ["@which", $help_cmd_which], ["@dump", $help_cmd_dump], ["@move", $help_cmd_move], ["@mv", $help_cmd_move], ["@copy", $help_cmd_move], ["@cp", $help_cmd_move], ["@add-v?ariable", $help_cmd_addvariable], ["@av", $help_cmd_addvariable], ["@ancestors", $help_cmd_ancestors], ["@eval", $help_cmd_eval], ["@grep", $help_cmd_grep], ["@id", $help_cmd_id], ["@join", $help_cmd_join], ["@trace-method", $help_cmd_trace], ["@trace", $help_cmd_trace], ["@teleport", $help_cmd_teleport], ["@go", $help_cmd_teleport], ["@attach", $help_cmd_attach], ["@destroy", $help_cmd_destroy], ["@report", $help_cmd_report], ["@build", $help_cmd_build], ["@dig", $help_cmd_dig], ["discard", $help_cmd_discard], ["@age", $help_cmd_age], ["@audit", $help_cmd_audit], ["@context", $help_cmd_context], ["@date", $help_cmd_date], ["@time", $help_cmd_date], ["@finger", $help_cmd_finger], ["@ustat", $help_cmd_finger], ["@map", $help_cmd_map], ["@monitor", $help_cmd_monitor], ["@news", $help_cmd_news], ["@password", $help_cmd_password], ["@passwd", $help_cmd_password], ["@quit", $help_cmd_quit], ["@status", $help_cmd_status], ["@ways", $help_cmd_exits], ["@exits", $help_cmd_exits], ["@whereis", $help_cmd_whereis], ["@where-is", $help_cmd_whereis], ["@who", $help_cmd_who], ["drop", $help_cmd_drop], ["get", $help_cmd_get], ["take", $help_cmd_get], ["@examine", $help_cmd_examine], ["inventory", $help_cmd_inventory], ["wear", $help_cmd_wear], ["shed", $help_cmd_wear], ["remove", $help_cmd_wear], ["@add-shortcut", $help_cmd_addshortcut], ["@as", $help_cmd_addshortcut], ["@chmod", $help_cmd_chmod], ["@mmod", $help_cmd_chmod], ["@omod", $help_cmd_chmod], ["@chflags", $help_cmd_chmod], ["@config-setting", $help_cmd_configsetting], ["@configure-setting", $help_cmd_configsetting], ["@def-setting", $help_cmd_defsetting], ["@define-setting", $help_cmd_defsetting], ["@del-shortcut", $help_cmd_delshortcut], ["@ds", $help_cmd_delshortcut], ["@undef-setting", $help_cmd_undefsetting], ["@undefine-setting", $help_cmd_undefsetting], ["@commands", $help_cmd_commands], ["look", $help_cmd_look], ["examine", $help_cmd_look], ["@chparents", $help_cmd_chparent], ["@add-parent", $help_cmd_addparent], ["@ap", $help_cmd_addparent], ["@parents", $help_cmd_parents], ["@realms", $help_cmd_realms], ["@children", $help_cmd_children], ["@kids", $help_cmd_children], ["@del-variable", $help_cmd_delvariable], ["@dv", $help_cmd_delvariable], ["@del-method", $help_cmd_delmethod], ["@dm", $help_cmd_delmethod], ["@del-parent", $help_cmd_delparent], ["@dp", $help_cmd_delparent], ["@paste", $help_cmd_paste], ["@paste-to", $help_cmd_paste], ["quote", $help_cmd_quote], ["@remembered", $help_cmd_remembered], ["@forget", $help_cmd_forget], ["@add-command-a?lias", $help_cmd_aca], ["@aca?lias", $help_cmd_aca], ["@del-command-a?lias", $help_cmd_dca], ["@dca?lias", $help_cmd_dca], ["@command-a?liases", $help_cmd_ca], ["@ca?liases", $help_cmd_ca], ["@new-password", $help_cmd_newpwd], ["@newpwd", $help_cmd_newpwd], ["@edit", $help_cmd_edit], ["@cleanup-sessions", $help_cmd_cs], ["@c-s", $help_cmd_cs], ["@mcp-upload-session", $help_cmd_mcp_upload], ["give", $help_cmd_give], ["put", $help_cmd_give], ["walk", $help_cmd_walk], ["go", $help_cmd_walk], ["@registered", $help_cmd_registered], ["@add-channel-manager", $help_cmd_channel_acm], ["@acm", $help_cmd_channel_acm], ["@del-channel-manager", $help_cmd_channel_dcm], ["@dcm", $help_cmd_channel_dcm], ["@join-lock-channel", $help_cmd_channel_join_lock], ["@jlc", $help_cmd_channel_join_lock], ["@leave-lock-channel", $help_cmd_channel_leave_lock], ["@llc", $help_cmd_channel_leave_lock], ["@use-lock-channel", $help_cmd_channel_use_lock], ["@ulc", $help_cmd_channel_use_lock], ["@purge-channel", $help_cmd_channel_purge], ["@desc-channel", $help_cmd_channel_desc], ["@channels", $help_cmd_channels], ["@name-templates", $help_cmd_name_templates], ["@templates", $help_cmd_name_templates], ["@add-channel", $help_cmd_channel_add], ["@addcom", $help_cmd_channel_add], ["@kick", $help_cmd_kick], ["spoof", $help_cmd_spoof], ["@register", $help_cmd_register_name], ["@unregister", $help_cmd_register_name], ["@register-name", $help_cmd_register_name], ["@unregister-name", $help_cmd_register_name], ["@quota", $help_cmd_quota], ["Admin Commands", $help_admin_commands], ["@bugs", $help_cmd_bugs], ["@pr", $help_cmd_bugs], ["@problems", $help_cmd_bugs], ["Commands", $help_building_commands], ["Building", $help_building_commands], ["Builder", $help_building_commands]];
var $has_name name = ['prop, "Commands", "Commands"];
var $registry stripped_characters = "!#^$&*()";
var $root trusted = [$help_node];
var $root inited = 1;
var $help_node body = <$ctext_frob, [[], #[]]>;
var $root managed = [$help_index_cmds];
var $help_node nolist = 0;
var $help_index dirty = 6;


new object $help_index_subsystem: $help_index;

var $root manager = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847916269;
var $has_name name = ['prop, "Subsystems", "Subsystems"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[], #[]]>;
var $db database = #[["Updates", $help_updates], ["Events", $help_sys_events], ["Editor", $help_sys_editor], ["Channels", $help_sys_channels], ["Messages", $help_sys_message], ["Word Generator", $help_sys_word], ["Message Propagation", $help_msg_prop], ["Ranges", $help_ranges], ["Bad Commands", $help_sys_bad_commands], ["Mail System", $help_mail], ["Administrators", $help_administrators], ["Admins", $help_administrators], ["Command Parsing System", $help_sys_parser], ["Command Parser", $help_sys_parser], ["Command Modules", $help_parser_command_modules]];
var $registry stripped_characters = "!#$%^&*()";
var $root trusted = [$help_node];
var $root inited = 1;
var $root managed = [$help_index_subsystem];
var $help_node nolist = 0;
var $help_index dirty = 1;


new object $help_index_function: $help_index;

var $root manager = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847916275;
var $has_name name = ['prop, "Function", "Function"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[], #[]]>;
var $db database = #[["sin", $help_func_math], ["exp", $help_func_math], ["log", $help_func_math], ["cos", $help_func_math], ["tan", $help_func_math], ["sqrt", $help_func_math], ["asin", $help_func_math], ["acos", $help_func_math], ["atan", $help_func_math], ["pow", $help_func_math], ["atan2", $help_func_math], ["add_var", $help_func_add_var], ["clear_var", $help_func_clear_var], ["del_var", $help_func_del_var], ["get_var", $help_func_get_var], ["set_var", $help_func_set_var], ["variables", $help_func_variables], ["add_method", $help_func_add_method], ["list_method", $help_func_list_method], ["del_method", $help_func_del_method], ["find_method", $help_func_find_method], ["find_next_method", $help_func_find_next_method], ["method_bytecode", $help_func_method_bytecode], ["method_access", $help_func_method_access], ["method_flags", $help_func_method_flags], ["method_info", $help_func_method_info], ["methods", $help_func_methods], ["rename_method", $help_func_rename_method], ["set_method_access", $help_func_set_method_access], ["set_method_flags", $help_func_set_method_flags], ["ancestors", $help_func_ancestors], ["children", $help_func_children], ["chparents", $help_func_chparents], ["create", $help_func_create], ["data", $help_func_data], ["del_objname", $help_func_del_objname], ["destroy", $help_func_destroy], ["has_ancestor", $help_func_has_ancestor], ["lookup", $help_func_lookup], ["objname", $help_func_objname], ["objnum", $help_func_objnum], ["parents", $help_func_parents], ["set_objname", $help_func_set_objname], ["backup", $help_func_backup], ["set_heartbeat", $help_func_set_heartbeat], ["shutdown", $help_func_shutdown], ["anticipate_assignment", $help_func_anticipate_assignment], ["config", $help_func_config], ["atomic", $help_func_atomic], ["caller", $help_func_caller], ["cancel", $help_func_cancel], ["definer", $help_func_definer], ["method", $help_func_method], ["pause", $help_func_pause], ["refresh", $help_func_refresh], ["resume", $help_func_resume], ["sender", $help_func_sender], ["stack", $help_func_stack], ["suspend", $help_func_suspend], ["task_id", $help_func_task_id], ["tasks", $help_func_tasks], ["this", $help_func_this], ["tick", $help_func_tick], ["ticks_left", $help_func_ticks_left], ["set_user", $help_func_set_user], ["user", $help_func_user], ["pass", $help_func_pass], ["task_info", $help_func_task_info], ["call_trace", $help_func_call_trace], ["debug_callers", $help_func_debug_callers], ["error", $help_func_error], ["rethrow", $help_func_rethrow], ["throw", $help_func_throw], ["traceback", $help_func_traceback], ["bind_port", $help_func_bind_port], ["close_connection", $help_func_close_connection], ["connection", $help_func_connection], ["cwrite", $help_func_cwrite], ["cwritef", $help_func_cwritef], ["open_connection", $help_func_open_connection], ["reassign_connection", $help_func_reassign_connection], ["unbind_port", $help_func_unbind_port], ["dblog", $help_func_dblog], ["execute", $help_func_execute], ["fchmod", $help_func_fchmod], ["fclose", $help_func_fclose], ["feof", $help_func_feof], ["fflush", $help_func_fflush], ["file", $help_func_file], ["files", $help_func_files], ["fmkdir", $help_func_fmkdir], ["fopen", $help_func_fopen], ["fread", $help_func_fread], ["fremove", $help_func_fremove], ["frename", $help_func_frename], ["frmdir", $help_func_frmdir], ["fseek", $help_func_fseek], ["fstat", $help_func_fstat], ["fwrite", $help_func_fwrite], ["bind_function", $help_func_bind_function], ["ctime", $help_func_ctime], ["localtime", $help_func_localtime], ["mtime", $help_func_mtime], ["unbind_function", $help_func_unbind_function], ["size", $help_func_size], ["toerr", $help_func_toerr], ["tofloat", $help_func_tofloat], ["toint", $help_func_toint], ["toliteral", $help_func_toliteral], ["toobjnum", $help_func_toobjnum], ["tostr", $help_func_tostr], ["tosym", $help_func_tosym], ["type", $help_func_type], ["valid", $help_func_valid], ["fromliteral", $help_func_fromliteral], ["buf_replace", $help_func_buf_replace], ["buf_to_str", $help_func_buf_to_str], ["buf_to_strings", $help_func_buf_to_strings], ["bufgraft", $help_func_bufgraft], ["buflen", $help_func_buflen], ["str_to_buf", $help_func_str_to_buf], ["strings_to_buf", $help_func_strings_to_buf], ["subbuf", $help_func_subbuf], ["bufidx", $help_func_bufidx], ["dict_add", $help_func_dict_add], ["dict_contains", $help_func_dict_contains], ["dict_del", $help_func_dict_del], ["dict_keys", $help_func_dict_keys], ["dict_union", $help_func_dict_union], ["dict_values", $help_func_dict_values], ["delete", $help_func_delete], ["insert", $help_func_insert], ["join", $help_func_join], ["listgraft", $help_func_listgraft], ["listlen", $help_func_listlen], ["replace", $help_func_replace], ["setadd", $help_func_setadd], ["setremove", $help_func_setremove], ["sublist", $help_func_sublist], ["union", $help_func_union], ["listidx", $help_func_listidx], ["crypt", $help_func_crypt], ["explode", $help_func_explode], ["lowercase", $help_func_lowercase], ["match_begin", $help_func_match_begin], ["match_pattern", $help_func_match_pattern], ["match_regexp", $help_func_match_regexp], ["match_template", $help_func_match_template], ["pad", $help_func_pad], ["regexp", $help_func_regexp], ["strcmp", $help_func_strcmp], ["strfmt", $help_func_strfmt], ["strgraft", $help_func_strgraft], ["strlen", $help_func_strlen], ["strsed", $help_func_strsed], ["strsub", $help_func_strsub], ["substr", $help_func_substr], ["uppercase", $help_func_uppercase], ["match_crypted", $help_func_match_crypted], ["split", $help_func_split], ["stridx", $help_func_stridx], ["abs", $help_func_abs], ["max", $help_func_max], ["min", $help_func_min], ["random", $help_func_random], ["frob_class", $help_func_class], ["frob_value", $help_func_frob_value], ["frob_handler", $help_func_frob_handler], ["cache_info", $help_func_cache_info]];
var $registry stripped_characters = "!#$%^&*()";
var $root trusted = [$help_node];
var $root inited = 1;
var $root managed = [$help_index_function];
var $help_node nolist = 0;
var $help_index dirty = 19;


new object $help_index_objects: $help_index;

var $root manager = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847917435;
var $has_name name = ['prop, "Objects", "Objects"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[], #[]]>;
var $db database = #[["List Library", $help_obj_list], ["Trie", $help_obj_trie], ["has_text", $help_obj_has_text], ["Colors", $help_cml_colors], ["Math Library", $help_obj_math], ["Integer", $help_obj_integer], ["Data Lib", $help_obj_data_lib], ["Object Lib", $help_obj_object_lib], ["Help Node", $help_obj_help_node], ["Code Lib", $help_obj_code_lib], ["Generic Map", $help_obj_generic_map], ["Command Cache", $help_obj_command_cache], ["World Time", $help_obj_world_time], ["Time", $help_obj_time], ["Robot", $help_obj_robot], ["@reactions", $help_obj_robot], ["@activate-reaction", $help_obj_robot], ["@deactivate-reaction", $help_obj_robot], ["@add-reaction", $help_obj_robot], ["Robot Methods", $help_obj_robot_methods], ["motd", $help_obj_motd], ["Mail List", $help_obj_mail_list], ["Float", $help_obj_float]];
var $registry stripped_characters = "!#%^&*()";
var $root trusted = [$help_node];
var $root inited = 1;
var $root managed = [$help_index_objects];
var $help_node nolist = 0;
var $help_index dirty = 3;


new object $mail_db: $registry, $mail_root;

var $root trusted = [$mail_list];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $db database = #[["news", $mail_list_news], ["bugs", $mail_list_bugs], ["admin", $mail_admin], ["tracebacks", $mail_list_tracebacks], ["postmaster", $mail_postmaster]];
var $root manager = $mail_db;
var $root managed = [$mail_db];

public method .valid_recipient() {
    arg recip;
    
    if (recip.has_ancestor($mail_list))
        return 1;
    return 0;
};

public method .mail_name() {
    arg obj;
    
    return "*" + (obj.name());
};

root method .core_mail_db() {
    .set_database(#[["news", $mail_list_news], ["bugs", $mail_list_bugs], ["admin", $mail_admin], ["tracebacks", $mail_list_tracebacks], ["postmaster", $mail_postmaster]]);
};


new object $place_db: $registry;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $db database = #[["void", $void], ["nowhere", $nowhere], ["Pit", $the_pit]];
var $registry stripped_characters = "!@#$%^&*()_+-=~`'{}[]|/?\",.<>;:";
var $root manager = $place_db;
var $root managed = [$place_db];

public method .place_destroyed() {
    arg @args;
    
    // called in $place.uninit_place (incase the place is in the db)
};

public method .strip_key() {
    arg key;
    
    anticipate_assignment();
    return strsed(key, "^(the|a|an) +", "").strip();
};

root method .core_place_db() {
    var p, db;
    
    db = .database();
    for p in (db.keys()) {
        if (!valid(db[p]))
            .remove(p);
    }
};


new object $user_db: $registry;

var $root trusted = [$user];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $db database = <$trie, [0, "GRNpS", [0, "e", [0, "n", [0, "e", [0, "r", [0, "i", [0, "c", [0, "GBPAU", [["uestObject", $guest], ""], [["uilder", $builder], ""], [["rogrammer", $programmer], ""], [["dmin", $admin], ""], [["serObject", $user], ""]]]]]]]], [["eaper", $reaper], ""], [["oOne", $no_one], ""], [["layer", $player], ""], [["toryteller", $storyteller], ""]]>;
var $user_db connected = [];
var $user_db invalid_chars = "$#@!^&%~:";
var $registry stripped_characters = "!@#$%^&*()_+-=~`'{}[]|/?\",.<>;: ";
var $registry reserved_names = ["user", "builder", "programmer", "admin", "housekeeper", "Reaper", "noone", "guest", "a", "i", "an", "your", "you'r", "me", "god"];
var $registry invalid_names = "(^| )(ass|cunt|fuck|shit|damn)( |$)";
var $registry min_char_len = 3;
var $registry max_char_len = 20;
var $root manager = $user_db;
var $root managed = [$user_db];
var $registry stripped = 1;

public method .users() {
    return (.database()).keys();
};

public method .connected() {
    var x;
    
    for x in (connected) {
        if ((!valid(x)) || (| !(x.connections()) |))
            connected = setremove(connected, x);
    }
    return connected;
};

public method .did_connect() {
    (> .perms(caller(), $user) <);
    connected = connected.setadd(sender());
};

public method .did_disconnect() {
    .perms(caller(), $user);
    connected = connected.setremove(sender());
};

public method .valid_name() {
    arg name;
    
    if (((name.strip(invalid_chars)).length()) < (name.length()))
        throw(~invname, ("Names cannot contain any of '" + invalid_chars) + "'.");
    return (> pass(name) <);
};

public method .match() {
    arg name;
    
    return (> .search(name) <);
};

public method .total_connected() {
    return (.connected()).length();
};

public method .clean_user_db() {
    var key, db, invalid;
    
    db = (.database()).to_dict();
    invalid = [];
    if (0) {
        // broken, not sure why, something is corrupting the trie --Brandon
        for key in (dict_keys(db)) {
            if (!valid(db[key])) {
                .remove(key);
                connected = setremove(connected, db[key]);
                invalid += [key];
            }
        }
    } else {
        for key in (dict_keys(db)) {
            if (!valid(db[key])) {
                connected = setremove(connected, db[key]);
                db = dict_del(db, key);
                invalid += [key];
            }
        }
        .set_database(db.to_trie());
    }
    return ["Invalid $user_db entries: " + (invalid.to_english())];
};

root method .core_user_db(): nooverride {
    var o;
    
    .set_database($trie.new());
    for o in (($user.descendants()) + [$user])
        .insert(o.name(), o);
};

public method .user_dbrefs() {
    var db;
    
    db = .database();
    if (type(db) != 'dictionary)
        db = db.to_dict();
    return (db.values()).compress();
};

public method .reserved_names() {
    return pass() + ((($smtp.mail_aliases()).keys()).mmap('strip));
};


new object $channel_db: $db;

var $root manager = $channel_db;
var $channel_db system_channels = ['Login, 'System, 'All];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 845244416;
var $root trusted = [$channel_ui];
var $db database = #[['all, ['All, 0, <$parent_lock_frob, [$admin]>, 0, $channel_db, [$channel_db], 0, 0]], ['admin, ['Admin, -1, <$parent_lock_frob, [$admin]>, 0, $channel_db, [$channel_db], "Administrator's Channel", 0]], ['system, ['System, 1, 0, 0, $channel_db, [$channel_db], "System wide messages like backup notifications.", 0]], ['login, ['Login, 2, 0, 0, $channel_db, [$channel_db], "User login and logout notifications.", 0]]];
var $root inited = 1;
var $root managed = [$channel_db];

protected method .clean_db() {
    var x, d;
    
    d = #[];
    for x in (.database()) {
        pause();
        if ((x[2])[2])
            d = d.add(@x);
    }
    .set_database(d);
};

public method .system_channels() {
    return system_channels;
};

root method .core_channel_db() {
    var elem, key, value, d;
    
    d = #[];
    for elem in (.database()) {
        refresh();
        [key, value] = elem;
        if (!valid(value[5]))
            continue;
        if (filter elem in (value[6]) where (!valid(elem)))
            continue;
        d = d.add(key, value);
    }
    .set_database(d);
};

public method .search() {
    arg channel;
    var key;
    
    if (type(channel) != 'symbol)
        key = .strip_key(channel);
    else
        key = channel;
    catch ~keynf, ~matchnf
        return (> .exact_match(key) <);
    with
        throw(~keynf, "Unknown channel: " + channel);
};

public method .strip_key() {
    arg channel;
    var key;
    
    anticipate_assignment();
    return lowercase(tostr(channel)).to_symbol();
};


new object $interface_registry: $db;

var $root manager = $interface_registry;
var $root managed = [$interface_registry];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858198912;
var $dmi_data descriptions = #[];
var $db database = #[['object, [$page_bin_index]], ['help, [$page_bin_index]], ['display, [$page_bin_index]], ['describe, [$page_bin_index]], ['who, [$page_bin_index]], ['read, [$note]], ['method, [$page_bin_index]], ['submit_new, [$page_set]]];
var $root inited = 1;

public method .describe() {
    arg object, method;
    var defining_object;
    
    defining_object = (> ._find_object_in_index(object, method) <);
    return (> defining_object.describe_method(method) <);
};

private method ._add_method_to_index() {
    arg object, method;
    var old_method_index, new_method_index;
    
    old_method_index = (| .exact_match(method) |) || [];
    new_method_index = ($graph.topological_sort(old_method_index.setadd(object), 'has_ancestor)).reverse();
    .insert(method, new_method_index);
};

private method ._find_object_in_index() {
    arg object, method, @second_time;
    var iter, objectlist;
    
    [(second_time ?= 0)] = second_time;
    if (second_time)
        ._sort_method_index(method);
    objectlist = (| .exact_match(method) |) || throw(~matchnf, "That method is not listed in the Interface Registry.");
    if (object in objectlist) {
        return valid(object) ? object : (> ._find_object_in_index(object, method, 1) <);
    } else {
        for iter in (objectlist) {
            if (object.has_ancestor(iter))
                return valid(iter) ? iter : (> ._find_object_in_index(object, method, 1) <);
        }
    }
    throw(~matchnf, "Object doesn't define that method in the Interface Registry");
};

public method .add_description() {
    arg object, method, description;
    
    if (!(object.is_writable_by(sender())))
        throw(~perm, (tostr(object) + " is not writable by ") + tostr(sender()));
    if (!(object.has_ancestor($dmi_data)))
        throw(~invrequest, object + " must be a child of $dmi_data.");
    (> ._add_method_to_index(object, method) <);
    (> object.add_description_to_db(method, description) <);
};

private method ._sort_method_index() {
    arg method;
    var old_method_index, new_method_index, item;
    
    old_method_index = (| .exact_match(method) |) || [];
    new_method_index = filter item in (old_method_index) where (valid(item));
    new_method_index = ($graph.topological_sort(new_method_index, 'has_ancestor)).reverse();
    .insert(method, new_method_index);
};

public method .index() {
    return .database();
};

public method .del_description() {
    arg object, method;
    
    if (~object.is_writable_by(sender()))
        throw(~perm, (tostr(object) + " is not writable by ") + tostr(sender()));
    (> ._del_method_from_index(object, method) <);
    (> object.del_description_from_db(method) <);
};

private method ._del_method_from_index() {
    arg object, method;
    var old_method_index, new_method_index;
    
    old_method_index = (| .exact_match(method) |) || [];
    new_method_index = ($graph.topological_sort(old_method_index.setremove(object), 'has_ancestor)).reverse();
    if (new_method_index)
        .insert(method, new_method_index);
    else
        .remove(method);
};

public method .where_is() {
    arg object, method;
    
    return (> ._find_object_in_index(object, method) <);
};

public method .verbal_index() {
    var index, method, objects, object, item, lines;
    
    index = .index();
    lines = ["Interface registry is tracking:{br}{br}"];
    lines += ["{table cols=50%,50%:"];
    for item in (index) {
        [method, objects] = item;
        lines += [((("{tr:{td:" + method) + "}{td:") + (objects.to_english())) + "}}"];
    }
    lines += ["}"];
    return $compiler.compile_cml(lines);
};

root method .core_interface_registry() {
    var method;
    
    for method in ((.database()).keys())
        ._sort_method_index(method);
};


new object $help_coldcore: $help_node;

var $root manager = $help_coldcore;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Cold Help System", "Cold Help System"];
var $help_node links = #[["Help", $help_help], ["General", $help_general], ["Building", $help_building], ["Programming", $help_prog], ["Reference", $help_reference], ["Administration", $help_admin], ["Server Administrators", $help_administrators], ["Credit and Copyright", $help_credit], ["Updates and Changes", $help_updates]];
var $help_node body = <$ctext_frob, [[<$format, ["img", [["plain", <$format, ["quote", [], ["\n        ___     _    _   _  _     _        ___         _\n       / __|___| |__| | | || |___| |_ __  / __|_  _ __| |_ ___ _ __\n      | (__/ _ \ / _` | | __ / -_) | '_ \ \__ \ || (_-<  _/ -_) '  \ \n       \___\___/_\__,_| |_||_\___|_| .__/ |___/\_, /__/\__\___|_|_|_|\n                                   |_|         |__/\n"], 'do_quote]>], ["src", "http://www.cold.org/coldcore/cold-help.jpg"]], [], 'do_img]>, <$format, ["p", [], [], 'do_p]>, "Welcome to ", <$generator, ["servername", [], [], 'gen_servername]>, ". This is a hypertext help system. If you are on an interactive login you can type ", <$format, ["tt", [], ["@help help"], 'do_tt]>, " for help on how to use this help system. You can also access this help system ", <$format, ["web", [["src", "/bin/help"]], ["from a web browser"], 'do_web]>, ".", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_help"]], ["Help"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How to use this help system (", <$format, ["b", [], ["READ FIRST!"], 'do_b]>, ")"], 'do_dd]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_general"]], ["General"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["General Information"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_building"]], ["Building"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Extending your Environment"], 'do_dd]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_prog"]], ["Programming"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Topics about programming"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_reference"]], ["Reference"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Core Reference Information"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_admin"]], ["Administration"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["ColdCore Administration"], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "You may also want to see the list of ", <$format, ["link", [["node", "$help_administrators"]], ["Server Administrators"], 'do_link]>, " for ", <$generator, ["servername", [], [], 'gen_servername]>, ", the ", <$format, ["link", [["node", "$help_credit"]], ["Credit and Copyright"], 'do_link]>, " Information Page, and perhaps a list of recent ", <$format, ["link", [["node", "$help_updates"]], ["Updates and Changes"], 'do_link]>, " to the documentation."], #[['links, #[["Help", "$help_help"], ["General", "$help_general"], ["Building", "$help_building"], ["Programming", "$help_prog"], ["Reference", "$help_reference"], ["Administration", "$help_admin"], ["Server Administrators", "$help_administrators"], ["Credit and Copyright", "$help_credit"], ["Updates and Changes", "$help_updates"]]]]]>;
var $root managed = [$help_coldcore];
var $help_node group = 1;
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_help: $help_coldcore;

var $root manager = $help_help;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Help|@help", "Help|@help"];
var $help_node links = #[["Help", $help_help], ["General", $help_general], ["Heirarchy", $help_help_heirarchy], ["Options", $help_help_options], ["Searching", $help_help_searching]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "This is a hypertext help system. Hypertext is a dynamic form of text, where words within a document may have special meaning, and point to other documents or portions of the document. These words are called ", <$format, ["i", [], ["hyperlinks"], 'do_i]>, ". In a windowed browser hyperlinks may be displayed differently from the regular text by colorization. Over a terminal hyperlinks are specified by enclosing them in square brackets (", <$format, ["tt", [], ["[]"], 'do_tt]>, "), such as: ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_help"]], ["Help"], 'do_link]>], 'do_tt]>, " ", <$format, ["np", [], [], 'do_np]>, "You can use the command ", <$format, ["tt", [], ["@help"], 'do_tt]>, " to navigate the ", <$generator, ["servname", [], [], 'gen_servname]>, "'s help system, when on an interactive connection. To activate a hyperlink from a page you are reading, type ", <$format, ["tt", [], ["@help"], 'do_tt]>, " and the name of the hyperlink. For instance, if the hyperlink was ", <$format, ["link", [["node", "$help_general"]], ["General"], 'do_link]>, ", typing ", <$format, ["tt", [], ["@help General"], 'do_tt]>, " would activate the link. For convenience, you can also use the command shortcut ", <$format, ["tt", [], ["?"], 'do_tt]>, " instead of ", <$format, ["tt", [], ["@help"], 'do_tt]>, ", such as: ", <$format, ["tt", [], ["?General"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "Additional Recommended Reading:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_help_heirarchy"]], ["Heirarchy"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Help heirarchy (organization)"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_help_options"]], ["Options"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Options and shortcuts to @help"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_help_searching"]], ["Searching"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Hints on searching Help"], 'do_dd]>], 'do_dl]>], #[['links, #[["Help", "$help_help"], ["General", "$help_general"], ["Heirarchy", "$help_help_heirarchy"], ["Options", "$help_help_options"], ["Searching", "$help_help_searching"]]]]]>;
var $root managed = [$help_help];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_help_heirarchy: $help_help;

var $root manager = $help_help_heirarchy;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 998869346;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Heirarchy", "Heirarchy"];
var $help_node links = #[["Help Options", $help_help_options]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The help files are not only hypertextual, but are also heirarchial. This means they are ordered in a parent/child manner (such as an outline), where general help topics are parents to specific help topics. ", <$format, ["np", [], [], 'do_np]>, "One useful result of this is a list of topics related to the current node, at the bottom of the page. These related topics are listed as links on the last line, with a series of dashes on each side (look at the bottom of this page and see if you can find them). ", <$format, ["np", [], [], 'do_np]>, "In the related topics list there are also dots. A single dot represents the current page in its order, relative to its sibling nodes. A double dot means there are more nodes, they just cannot be displayed. ", <$format, ["np", [], [], 'do_np]>, "You can also navigate up, back and forward in the help heirarchy, relative to the current help node. You can do this by using the options -up, -back and -forward; or by using the shorthand characters '", <$format, ["tt", [], ["^"], 'do_tt]>, "', '", <$format, ["tt", [], ["<"], 'do_tt]>, "' and '", <$format, ["tt", [], [">"], 'do_tt]>, "'. See the section on ", <$format, ["link", [["node", "$help_help_options"]], ["Help Options"], 'do_link]>, " for more detail on the available options and shorthand characters."], #[['links, #[["Help Options", "$help_help_options"]]]]]>;
var $root inited = 1;
var $root managed = [$help_help_heirarchy];


new object $help_help_options: $help_help;

var $root manager = $help_help_options;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847650584;
var $has_name name = ['prop, "Options", "Options"];
var $help_node links = #[["Command Matching Conventions", $help_commands_matching]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Available options for the command ", <$format, ["tt", [], ["@help"], 'do_tt]>, " are:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], ["-h?istory"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Display your help page history"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["-b?ack"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Go back one page in your history"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["-b?ack ", <$format, ["i", [], ["name"], 'do_i]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Go back to page ", <$format, ["i", [], ["name"], 'do_i]>, " in your history"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["-f?orward"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Go forward one page your history"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["-f?orward ", <$format, ["i", [], ["name"], 'do_i]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Go forward to page ", <$format, ["i", [], ["name"], 'do_i]>, " in your history"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["-u?p"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Go up to the parent node of the current node"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["-fix"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Fix your history, useful if it becomes corrupt"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["-l?inks"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["List all of the links off the current help page"], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "The question mark ", <$format, ["tt", [], ["?"], 'do_tt]>, " in the above options specifies that characters following it are optional, (following the standard ", <$format, ["link", [["node", "$help_commands_matching"]], ["Command Matching Conventions"], 'do_link]>, "). ", <$format, ["subj", [["level", "3"]], ["Option Shortcuts"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Options have shorthand equivalents, as follows:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], ["?"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-history"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["<"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-back"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["<", <$format, ["i", [], ["name"], 'do_i]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-back ", <$format, ["i", [], ["name"], 'do_i]>], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [">"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-forward"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [">", <$format, ["i", [], ["name"], 'do_i]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-forward ", <$format, ["i", [], ["name"], 'do_i]>], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["^"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-up"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["!"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-fix"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["#"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-links"], 'do_dd]>], 'do_dl]>], #[['this, $help_help_options]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_help_options];
var $help_node nolist = 0;


new object $help_help_searching: $help_help;

var $root manager = $help_help_searching;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847650599;
var $has_name name = ['prop, "Searching", "Searching"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "You may encounter conflicts of link and node names while navigating help. This may occur if you do not specify the entire link name. Make sure when you activate a link you include enough of the link name to get a precise match (you do not always need to specify the entire link name). If you are still getting a conflict you can narrow the search parameters. First, to better understand what happens when you activate a link keep in mind the following search order:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["Search in current page links"], 'do_li]>, <$format, ["li", [], ["Search in current page group"], 'do_li]>, <$format, ["li", [], ["Search in current page's index"], 'do_li]>, <$format, ["li", [], ["Search in all other help indices"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "If you are having a conflict you can prefix what you are searching for with either ", <$format, ["tt", [], ["group="], 'do_tt]>, ", ", <$format, ["tt", [], ["link="], 'do_tt]>, " or ", <$format, ["tt", [], ["index="], 'do_tt]>, " and it will search only in the respective area. For instance, if you were to type:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["?index=narf"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "It would bypass any links or group nodes to ", <$format, ["tt", [], ["narf"], 'do_tt]>, ", and only search in the current index and subsequent indices. Furthermore, if you specify a word other than the above, it will attempt to match only in the relevant index. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["?core=narf"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Would search only in the core index, assuming it existed. Furthermore, when searching a specific index if the search word you specify is simply a hash-mark ", <$format, ["tt", [], ["#"], 'do_tt]>, ", it will set the current index as the help node."], #[['this, $help_help_searching]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_help_searching];
var $help_node nolist = 0;


new object $help_general: $help_coldcore;

var $root manager = $help_general;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847218948;
var $has_name name = ['prop, "General Information", "General Information"];
var $help_node links = #[["Building and Extending", $help_building], ["@help", $help_help], ["Programming", $help_prog], ["Conventions", $help_conventions], ["Objects", $help_objects], ["Environment", $help_environment], ["Appearance", $help_appearance], ["Settings", $help_settings], ["Commands", $help_commands], ["Interaction", $help_interaction], ["Interface", $help_interface], ["Security", $help_security]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "General topics are covered in this area. If you need to know about describing and extending your Virtual Environment read about ", <$format, ["link", [["node", "$help_building"]], ["Building and Extending"], 'do_link]>, ". Help on a specific object may be obtained by typing ", <$format, ["link", [["node", "$help_help"]], ["@help"], 'do_link]>, " followed by the full object name. ", <$format, ["link", [["node", "$help_prog"]], ["Programming"], 'do_link]>, " help is also available.", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_conventions"]], ["Conventions"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Conventions used in these documents"], 'do_dd]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_objects"]], ["Objects"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Learn about Objects"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_environment"]], ["Environment"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How Objects are used in your Environment"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_appearance"]], ["Appearance"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Changing something's appearance"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_settings"]], ["Settings"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Configurable Settings"], 'do_dd]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_commands"]], ["Commands"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Learn about commands"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_interaction"]], ["Interaction"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How to interact with others"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_interface"]], ["Interface"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How to personalize your interface"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_security"]], ["Security"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How ColdCore security works"], 'do_dd]>], 'do_dl]>], #[['links, #[["Building and Extending", "$help_building"], ["@help", "$help_help"], ["Programming", "$help_prog"], ["Conventions", "$help_conventions"], ["Objects", "$help_objects"], ["Environment", "$help_environment"], ["Appearance", "$help_appearance"], ["Settings", "$help_settings"], ["Commands", "$help_commands"], ["Interaction", "$help_interaction"], ["Interface", "$help_interface"], ["Security", "$help_security"]]]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_general];
var $help_node nolist = 0;


new object $help_conventions: $help_general;

var $root manager = $help_conventions;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847225687;
var $has_name name = ['prop, "Conventions", "Conventions"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Througout these documents certain conventions are used. If a document is explaining a command to be typed, it will begin with a greater-than sign (", <$format, ["tt", [], [">"], 'do_tt]>, "), such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> command"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If a document shows the syntax for a command a few conventions are used. First, words grouped within greater-than and less-than (", <$format, ["tt", [], ["<>"], 'do_tt]>, ") signs are ", <$format, ["i", [], ["variables"], 'do_i]>, " and should be replaced with what you actually type. Second, words or ", <$format, ["i", [], ["variables"], 'do_i]>, " within square brackets (", <$format, ["tt", [], ["[]"], 'do_tt]>, ") are optional. You may also see an elipse (", <$format, ["tt", [], ["..."], 'do_tt]>, ") inside square brackets. This simply means that it will accept multiple instances of the last word or ", <$format, ["i", [], ["variable"], 'do_i]>, ". The following example shows the first ", <$format, ["i", [], ["variable"], 'do_i]>, " argument is required, and more may be added:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: @command <arg1> [<arg2> ...]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If a document is explaining how ColdC code may be evaluated when interpreted, the first line is the ColdC code and the second line begins with a text arrow pointing to the right (", <$format, ["tt", [], ["=>"], 'do_tt]>, ") and is followed by a ColdC data value. This represents what the example would evaluate to and return. For instance, calling the function ", <$format, ["tt", [], ["ctime()"], 'do_tt]>, " could return the value ", <$format, ["tt", [], ["\"Sun Feb 25 17:06:38 1996\""], 'do_tt]>, ". The function call and resulting value would be listed using this convention as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["ctime()\n=> \"Sun Feb 25 17:06:38 1996\""], 'do_quote]>], 'do_dfn]>], #[['this, $help_conventions]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_conventions];
var $help_node nolist = 0;


new object $help_objects: $help_general;

var $root manager = $help_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 846994462;
var $has_name name = ['prop, "Objects", "Objects"];
var $help_node links = #[["Object Oriented Programming", $help_coldc_oop], ["Environment", $help_environment]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Objects are the primary element of Cold. An object is an abstract concept used to aid in program design. In simple terms an object is something which contains information (data) and instructions for manipulating this information (methods or functions). ", <$format, ["np", [], [], 'do_np]>, "If you are unfamiliar with the concepts of Objects and Object Oriented Programming and you want to learn more, you may want to read about ", <$format, ["link", [["node", "$help_coldc_oop"]], ["Object Oriented Programming"], 'do_link]>, " in the ColdC Reference Manual (following this link is not for the faint of heart!) ", <$format, ["np", [], [], 'do_np]>, "Even if you do not intend to program, it is important to know about objects. If you want to specify an object that is not in your ", <$format, ["link", [["node", "$help_environment"]], ["Environment"], 'do_link]>, ", you can do it by using the object database name (sometimes called an objref or dbref). Object database names are single words (no spaces), beginning with a dollar sign ", <$format, ["tt", [], ["$"], 'do_tt]>, ". The following are all object names:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["$root, $sys, $user_joe"], 'do_dfn]>], #[['links, #[["Object Oriented Programming", "$help_coldc_oop"], ["Environment", "$help_environment"]]]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_objects];
var $help_node nolist = 0;


new object $help_environment: $help_general;

var $root manager = $help_environment;
var $root created_on = 810254707;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Environment", "Environment"];
var $help_node links = #[["@context", $help_cmd_context], ["@remember", $help_cmd_remember]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Your environment is where the system tries to find things, when you name something. It does this by first checking everything in your contents, and everything in the location you are in. ", <$format, ["subj", [["level", "2"]], ["Context"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "The system will also check your recent context. The server records the last object you named, as well as all of the last objects you named (with a gender). You can list your recent context with the command ", <$format, ["link", [["node", "$help_cmd_context"]], ["@context"], 'do_link]>, ", receiving a result similar to:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["Last thing: the Magazine Rack\nLast it:    the Magazine Rack      \nLast her:   Squeak the lemming\nLast him:   Miro"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When the system is attempting to find a named object, it first checks in your context. This allows you to name objects by their gender (if you remember it correctly). For instance:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["nobound", 1]], [<$format, ["quote", [], ["> get bottle\nYou take the bottle.\n> drop it\nYou drop the bottle."], 'do_quote]>], 'do_dfn]>, " ", <$format, ["subj", [["level", "2"]], ["Multiple Matches"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "In the case where multiple objects would match a single name, you can use ordinal references, such as ", <$format, ["tt", [], ["the 3rd bottle"], 'do_tt]>, " or ", <$format, ["tt", [], ["the second key"], 'do_tt]>, ". ", <$format, ["subj", [["level", "2"]], ["Posessive Matching"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "If something is located in something else, in your environment (either being carried by somebody, or in a box, etc), you can refer to it posessively. For instance, if the user 'Joe' is holding a note, you can look at it with the command:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["nobound", 1]], ["> look at Joe's note"], 'do_dfn]>, " ", <$format, ["subj", [["level", "2"]], ["Keywords"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "There are also two words known by the system. The first is ", <$format, ["tt", [], ["me"], 'do_tt]>, ", which is always you. The second is ", <$format, ["tt", [], ["here"], 'do_tt]>, ", which is always your location. ", <$format, ["subj", [["level", "2"]], ["Remembering"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "If you are having a hard time remembering an items object name, or typing it's full name, you can remember it as a shorter name, with the command ", <$format, ["link", [["node", "$help_cmd_remember"]], ["@remember"], 'do_link]>, "."], #[['links, #[["@context", "$help_cmd_context"], ["@remember", "$help_cmd_remember"]]]]]>;
var $root managed = [$help_environment];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_appearance: $help_general;

var $root manager = $help_appearance;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855981674;
var $root managed = [$help_appearance];
var $has_name name = ['prop, "Appearance", "Appearance"];
var $help_node links = #[["Names", $help_app_names], ["Description", $help_app_desc], ["Gender", $help_app_gender], ["Wearing", $help_app_wearing]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Anything in the virtual environment will always have some common attributes, such as name, description and gender. If you manage the item, you can change these attributes and alter its appearance (this includes yourself). Everything that can be changed is described in more detail in the following sections:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_app_names"]], ["Names"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_app_desc"]], ["Description"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_app_gender"]], ["Gender"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_app_wearing"]], ["Wearing"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['links, #[["Names", "$help_app_names"], ["Description", "$help_app_desc"], ["Gender", "$help_app_gender"], ["Wearing", "$help_app_wearing"]]]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_app_names: $help_appearance;

var $root manager = $help_app_names;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856649225;
var $root managed = [$help_app_names];
var $has_name name = ['prop, "Names", "Names"];
var $help_node links = #[["Object Names", $help_coldc_objs_ref], ["Environment", $help_environment], ["Matching Conventions", $help_commands_matching], ["@rename", $help_cmd_rename]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "An object has three different types of names, its Object Name, VR Name and Name Templates. The Object Name is unique to each object. No other object will ever have the same Object Name as another object in the database. The Object Name is formatted as a dollar sign followed by any number of alphanumeric characters (", <$format, ["tt", [], ["a-z 0-9"], 'do_tt]>, ") or the underscore (", <$format, ["tt", [], ["'_'"], 'do_tt]>, "). Additional help on ", <$format, ["link", [["node", "$help_coldc_objs_ref"]], ["Object Names"], 'do_link]>, " can be found in the Programming Help. An example of an object name is:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["$root"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The VR Name is the name the object has in its ", <$format, ["link", [["node", "$help_environment"]], ["Environment"], 'do_link]>, ". The VR Name is not unique to the object, and other objects can also have the same name. ", <$format, ["np", [], [], 'do_np]>, "VR Names are also broken into three types: Proper, Unique and Normal. The type of name will decide what articles are put with it, when formatting (You do not normally include the article in a name). Proper names have no article. Unique names use the article ", <$format, ["tt", [], ["the"], 'do_tt]>, ", and Normal names use the article ", <$format, ["tt", [], ["a"], 'do_tt]>, " or ", <$format, ["tt", [], ["an"], 'do_tt]>, ". Normally, when you set a name you can just use the article for the type of name you want. If you desire a different behaviour you can type +ignore in the name and it will override any automatic article settings. ", <$format, ["subj", [["level", "2"]], ["Name Templates"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Name Templates are additional helpful hints for the name matching system. Name Templates match differently than VR Names, so care should be given in knowing how each type of name matches before specifying a Name Template, as often times the Name Template is unecessary. ", <$format, ["np", [], [], 'do_np]>, "When the system tries to match a name to an object, it will match the beginning of any word in a name. For instance, if an object has the name ", <$format, ["tt", [], ["\"Mad Hatter\""], 'do_tt]>, " both ", <$format, ["tt", [], ["\"mad\""], 'do_tt]>, " and ", <$format, ["tt", [], ["\"hatter\""], 'do_tt]>, " would match. Furthermore, ", <$format, ["tt", [], ["\"hat\""], 'do_tt]>, " would also match, as it is the beginning of the second word. ", <$format, ["np", [], [], 'do_np]>, "To supplement matching you can add Name Templates. Name Templates use the Template Matching system. Templates are not matched like names. The most common use of templates with names would be partial matching a word. For instance, the exit ", <$format, ["tt", [], ["\"Glass Door\""], 'do_tt]>, " may have the Template ", <$format, ["tt", [], ["\"e?ast\""], 'do_tt]>, ". The Question Mark ('?') is used to specify that any character past that point is optional. For more information on Template Matching see the section ", <$format, ["link", [["node", "$help_commands_matching"]], ["Matching Conventions"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "Commands used with names are: ", <$format, ["link", [["node", "$help_cmd_rename"]], ["@rename"], 'do_link]>], #[['links, #[["Object Names", "$help_coldc_objs_ref"], ["Environment", "$help_environment"], ["Matching Conventions", "$help_commands_matching"], ["@rename", "$help_cmd_rename"]]]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_app_desc: $help_appearance;

var $root manager = $help_app_desc;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856649225;
var $root managed = [$help_app_desc];
var $has_name name = ['prop, "Description", "Description"];
var $help_node links = #[["@describe", $help_cmd_describe], ["CML", $help_cml]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "If you are the manager of an item you can change it's description with the command ", <$format, ["link", [["node", "$help_cmd_describe"]], ["@describe"], 'do_link]>, ". Descriptions are entered as ", <$format, ["link", [["node", "$help_cml"]], ["CML"], 'do_link]>, ", but you do not need to know CML to describe something--just to use its features."], #[['this, $help_app_desc]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_app_gender: $help_appearance;

var $root manager = $help_app_gender;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856649225;
var $root managed = [$help_app_gender];
var $has_name name = ['prop, "Gender", "Gender"];
var $help_node links = #[["@set", $help_cmd_set]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "If you are the manager of an item you can change it's gender. By default all genders are neuter. An item's gender is changed using the command ", <$format, ["link", [["node", "$help_cmd_set"]], ["@set"], 'do_link]>, " with the ", <$format, ["tt", [], ["gender"], 'do_tt]>, " setting, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set me:gender=male"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If you do not specify a gender, all of the possibilities will be listed."], #[['this, $help_app_gender]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_app_wearing: $help_appearance;

var $root manager = $help_app_wearing;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856649225;
var $root managed = [$help_app_wearing];
var $has_name name = ['prop, "Wearing", "Wearing"];
var $help_node links = #[["wear", $help_cmd_wear], ["shed", $help_cmd_wear]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Any virtually alive item (something which is descended from the ", <$format, ["tt", [], ["$body"], 'do_tt]>, " object) can wear things--generally clothing. Anything worn is a ", <$format, ["i", [], ["Wearable Frob"], 'do_i]>, ", and must be from the object ", <$format, ["tt", [], ["$wearable_frob"], 'do_tt]>, " or one of its descendants. A new article of clothing can be created by typing:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@new $wearable_frob named Trenchcoat"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "After it is created you will be holding it. At this point it is worn with the command ", <$format, ["link", [["node", "$help_cmd_wear"]], ["wear"], 'do_link]>, " and removed with the command ", <$format, ["link", [["node", "$help_cmd_wear"]], ["shed"], 'do_link]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["wear trenchoat"], 'do_dfn]>], #[['this, $help_app_wearing]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_security: $help_general;

var $root manager = $help_security;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853888954;
var $has_name name = ['prop, "Security", "Security"];
var $help_node links = #[["Object-Level", $help_security_levels], ["Groups", $help_security_groups]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "There are several facets to how security is handled in coldcore, both in code relationships and in the VR. From a coding point of view, ", <$format, ["link", [["node", "$help_security_levels"]], ["Object-Level"], 'do_link]>, " security and ", <$format, ["link", [["node", "$help_security_groups"]], ["Groups"], 'do_link]>, " are used to handle most of the security functionality. Additional mechanisms exist in some places, such as the command stipulation for some command methods which requires that the method is only called from the command parser. Most of the security checks are managed through the ", <$format, ["tt", [], [".perms()"], 'do_tt]>, " method. ", <$format, ["np", [], [], 'do_np]>, "VR Security primarily uses groups or logic locks in the form of a key (as would be used to lock a door or box). ", <$format, ["np", [], [], 'do_np]>, " See Also: ", <$format, ["link", [["node", "$help_security_levels"]], ["Object-Level"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_security_groups"]], ["Groups"], 'do_link]>, " Security."], #[['links, #[["Object-Level", "$help_security_levels"], ["Groups", "$help_security_groups"]]]]]>;
var $root inited = 1;
var $root managed = [$help_security];
var $help_node nolist = 0;


new object $help_security_levels: $help_security;

var $root manager = $help_security_levels;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 998881662;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Object-Levels", "Object-Levels"];
var $help_node links = #[["@mojo", $help_cmd_mojo]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Object-Level security is what managest most of the security in the database. It is a set of four levels, where each level encompasses all of the priviledges of the previous level. All access for object-levels is on a per-object basis--allowing one or more objects a certain level of privilege to another object depending upon the level it is defined in. ", <$format, ["np", [], [], 'do_np]>, "Any object or user can manage objects, be a writer on objects and a trustee on other objects. User classes (i.e. builder, programmer, admin) are not associated with any security level, they exist simply to group commands and more powerful interfaces. The levels are: ", <$format, ["subj", [["level", "2"]], ["System Level"], 'do_subj]>, " This level is the top level, encompassing administrators and system-level objects (such as ", <$format, ["tt", [], ["$root"], 'do_tt]>, " and ", <$format, ["tt", [], ["$sys"], 'do_tt]>, "). By default Administrators do not have this level enabled (it can be enabled each session with the command ", <$format, ["link", [["node", "$help_cmd_mojo"]], ["@mojo"], 'do_link]>, "). ", <$format, ["subj", [["level", "2"]], ["Manager Level"], 'do_subj]>, " Every object has a manager. The manager has full permissions on the specific object. Quota usage is also based off the object Manager. ", <$format, ["subj", [["level", "2"]], ["Writer Level"], 'do_subj]>, " An object can have any number of writers. Writer Level permissions give full access to an object, with a few exceptions:", <$format, ["ul", [], [<$format, ["li", [], ["Writers cannot change any access permissions on an object (this includes adding other writers or changing the Manager)."], 'do_li]>, <$format, ["li", [], ["Writers cannot change the object's parents."], 'do_li]>, <$format, ["li", [], ["Writers cannot destroy the object."], 'do_li]>], 'do_ul]>, <$format, ["subj", [["level", "2"]], ["Trustee Level"], 'do_subj]>, " An object trustee is simply another object that is trusted more than random objects but less than a writer. The amount of access given depends upon the subsystem. For instance, adding a user as a trustee to a location they are not a Manager or Writer of will give them the ability to extend other rooms from it."], #[['links, #[["@mojo", "$help_cmd_mojo"]]]]]>;
var $root inited = 1;
var $root managed = [$help_security_levels];


new object $help_security_groups: $help_security;

var $root manager = $help_security_groups;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 909403959;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Groups", "Groups"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The group system is an all purpose classification system which can be used for a wide array of purposes. Groups can work in one of two ways: either they are simply a list of objects, and can be tested against for permissions sake, or they use a logical expression as their condition. ", <$format, ["subj", [["level", "2"]], ["Object Groups"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Object groups are heirarchial, so for an example consider the following group heirarchy:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["$group [*-mvc]\n  $staff_group [*-mvc]\n    $building_group [*fmvc]"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If a user is added to the staff group, and something tests against the building group, the staff members are included so it will evaluate true--even though they are not in the building group. ", <$format, ["subj", [["level", "2"]], ["Groups and Security"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Groups can be specified as a writer on an object, and when testing against writer permissions for that object, it will also include anybody in the group, or evaluate against the condition of the group. This is highly useful for projects, where many objects are edited by a group of people. By using groups, people in the project only have to be added and removed from one place (the group) rather than each individual project. ", <$format, ["subj", [["level", "2"]], ["Programmer API"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "To use a group in ColdC code, simply call the method ", <$format, ["method", [["$group.includes", 1]], [".includes"], 'do_method]>, "() on the group, with a single argument of the object which is in question. ", <$format, ["subj", [["level", "2"]], ["Available Groups"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "To see a list of all available groups, use the command:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@descend $group +all +only=core"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "All groups have a setting of '", <$format, ["tt", [], ["group"], 'do_tt]>, "', which is a list of objects--except for $conditional_group and its descendants, where it is a logical expression."], #[]]>;
var $root inited = 1;
var $root managed = [$help_security_groups];


new object $help_commands: $help_general;

var $root manager = $help_commands;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $has_name name = ['prop, "Commands", "Commands"];
var $help_node links = #[["VR vs Non-VR", $help_commands_vr], ["Types", $help_commands_types], ["Matching", $help_commands_matching], ["Enhanced", $help_commands_enhanced], ["All Commands", $help_index_cmds], ["Programming", $help_prog_commands]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "This section outlines some of the basics of commands, from understanding the logic behind why they are named what they are, to using them, to programming them. (Programmer's note: Commands in the Cold Dark are handled entirely in the database, the driver is oblivious to the intent or meaning of what it is you type).", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_commands_vr"]], ["VR vs Non-VR"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["The difference between the two"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_commands_types"]], ["Types"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Local, remote, shortcuts and aliases"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_commands_matching"]], ["Matching"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Conventions used in matching commands"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_commands_enhanced"]], ["Enhanced"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["ColdCore's Enhanced Commands"], 'do_dd]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_index_cmds"]], ["All Commands"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["An index of all commands"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_prog_commands"]], ["Programming"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Programming Commands"], 'do_dd]>], 'do_dl]>], #[['links, #[["VR vs Non-VR", "$help_commands_vr"], ["Types", "$help_commands_types"], ["Matching", "$help_commands_matching"], ["Enhanced", "$help_commands_enhanced"], ["All Commands", "$help_index_cmds"], ["Programming", "$help_prog_commands"]]]]]>;
var $root managed = [$help_commands];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_commands_vr: $help_commands;

var $root manager = $help_commands_vr;
var $root created_on = 810075673;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "VR vs Non-VR", "VR vs Non-VR"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "To help classify commands, a distinction has been made. This distinction is based upon how the command is used, and what it effects. If the command is a Non-VR command (it does not follow the Virtual Environment guidelines) it begins with an at-sign ('@'). Otherwise, it does not. ", <$format, ["np", [], [], 'do_np]>, "The best way to decide if a command is VR or Non-VR is to ask yourself the question: ", <$format, ["i", [], ["Is it something I could do in real-life?"], 'do_i]>, " For instance, you do not simply declare, \"", <$format, ["i", [], ["I am wearing pink polka dotted clothes"], 'do_i]>, "\", and suddenly you are. However, in the Cold Dark you have the ability to directly change how you look from moment to moment. Therefore this command (@describe) is a Non-VR command, and begins with an at-sign."], #[['this, $help_commands_vr]]]>;
var $root managed = [$help_commands_vr];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_commands_types: $help_commands;

var $root manager = $help_commands_types;
var $root created_on = 810075676;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Types", "Types"];
var $help_node links = #[["@add-command", $help_cmd_addcmd], ["@del-command", $help_cmd_delcmd], ["@add-shortcut", $help_cmd_addshortcut], ["@del-shortcut", $help_cmd_delshortcut], ["@commands", $help_cmd_commands], ["@add-command-alias", $help_cmd_aca], ["@del-command-alias", $help_cmd_dca], ["@command-aliases", $help_cmd_ca]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Each command is associated with a specific method. When a command match is found, that method is executed with arguments depending upon what you typed. The Cold Dark recognizes three types of commands:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["b", [], ["Local Commands"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], [<$format, ["p", [], [], 'do_p]>, "Local commands are any non-directed command, or any command which does not require a target in the command template. Matching for local commands uses ColdC template matching. The parser looks for local commands on the user, the user's ancestry, and the user's location (but not anything the user is carrying or in the user's location).", <$format, ["p", [], [], 'do_p]>], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["Remote Commands"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], [<$format, ["p", [], [], 'do_p]>, "Remote commands differ from Local Commands in that they require the target of the command, in the command string. For instance, \"get button\" would be a remote command, because it requires the target of button to function correctly. Matching for Remote Commands uses ColdC template matching", <$format, ["p", [], [], 'do_p]>], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["Shortcuts"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], [<$format, ["p", [], [], 'do_p]>, "Shortcuts are intented as wrap-arounds for commands, using ColdC pattern matching instead of template matching.", <$format, ["p", [], [], 'do_p]>], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["Aliases"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], [<$format, ["p", [], [], 'do_p]>, "Command aliases are personal shortcuts added by the user. They are very similar to command shortcuts, with the primary difference being their scope. A command alias is defined on a per-user basis. To add a command alias for more than one person, use a shortcut and add it to a command-ui object."], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_addcmd"]], ["@add-command"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_delcmd"]], ["@del-command"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_addshortcut"]], ["@add-shortcut"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_delshortcut"]], ["@del-shortcut"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_commands"]], ["@commands"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_aca"]], ["@add-command-alias"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_dca"]], ["@del-command-alias"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_ca"]], ["@command-aliases"], 'do_link]>], #[['links, #[["@add-command", "$help_cmd_addcmd"], ["@del-command", "$help_cmd_delcmd"], ["@add-shortcut", "$help_cmd_addshortcut"], ["@del-shortcut", "$help_cmd_delshortcut"], ["@commands", "$help_cmd_commands"], ["@add-command-alias", "$help_cmd_aca"], ["@del-command-alias", "$help_cmd_dca"], ["@command-aliases", "$help_cmd_ca"]]]]]>;
var $root managed = [$help_commands_types];
var $help_node nolist = 0;


new object $help_commands_matching: $help_commands;

var $root manager = $help_commands_matching;
var $root created_on = 810075678;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Matching Conventions", "Matching Conventions"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Two types of general matching systems are used in Cold. The base matching system is pattern matching. The asterisk character ('*') in a pattern match is used to represent a wildcard. It can be placed anywhere in the pattern. It tells the interpreter that when matching the pattern with a string, anything can match the wildcard. This becomes useful for matching different strings. Some examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["Pattern:           \"match *\"\nString:            \"match anything after this\"\nWildcard Match:    \"anything after this\"\n\nPattern:           \"match *t not this\"\nString:            \"match only this but not this\"\nWildcard Match:    \"only this bu\""], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Template matching expands upon the basic idea of pattern matching. Template matching is a little smarter about matching. It recognizes words as anything bounded by spaces or the beginning and end of the string. In a template the wildcard must be its own word--it must have spaces around it. Templates also add two more special characters; the question mark ('?') for optional matching and the pipe character ('|') for multiple matches. ", <$format, ["np", [], [], 'do_np]>, "If a question mark is placed within a word, it means that the word must match up to the point of the question mark, but everything after that point is optional. For instance, all of the following would be valid against the specified template:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["Template:          \"th?is\"\nString:            \"th\"\nString:            \"thi\"\nString:            \"this\""], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The pipe character (", <$format, ["tt", [], ["|"], 'do_tt]>, ") is used to specify several different words that can match the place of one. For instance, the template \"this|that|there\" would match \"this\" ", <$format, ["i", [], ["OR"], 'do_i]>, " \"that\" ", <$format, ["i", [], ["OR"], 'do_i]>, " \"there\". It is easiest to logically think of the pipe character as ", <$format, ["i", [], ["OR"], 'do_i]>, ". With these elements drawn together you get a simple yet dynamic matching system. Some full template examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["\"l?ook at *\"\n\"give|put * to|in *\"\n\"@who *\"\n\"@lock * to|with *\""], 'do_quote]>], 'do_dfn]>], #[['this, $help_commands_matching]]]>;
var $root managed = [$help_commands_matching];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_interaction: $help_general;

var $root manager = $help_interaction;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Interaction", "Interaction"];
var $help_node links = #[["say", $help_cmd_say], ["emote", $help_cmd_emote], ["to", $help_cmd_tosay], ["whisper", $help_cmd_whisper], ["think", $help_cmd_think], ["spoof", $help_cmd_spoof], ["@page", $help_cmd_page], ["@paste", $help_cmd_paste], ["shortcuts", $help_cmd_shortcuts]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The following common interaction commands exist:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_say"]], ["say"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Speak and talk to others"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_emote"]], ["emote"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Do free-form actions"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_tosay"]], ["to"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Direct messages to people in the room"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_whisper"]], ["whisper"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Privately talk to somebody"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_think"]], ["think"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Thinks something out loud"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_spoof"]], ["spoof"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Similar to eval, but formatted differently"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_page"]], ["@page"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Talk to somebody not in the room"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_paste"]], ["@paste"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Paste a block of text to people"], 'do_dd]>, <$format, ["br", [], [], 'do_br]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_shortcuts"]], ["shortcuts"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Additional unnamed interaction shortcuts"], 'do_dd]>], 'do_dl]>], #[['this, $help_interaction]]]>;
var $root managed = [$help_interaction];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_interface: $help_general;

var $root manager = $help_interface;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847647924;
var $has_name name = ['prop, "Interface", "Interface"];
var $help_node links = #[["Client", $help_interface_client], ["Format", $help_interface_format], ["Settings", $help_settings]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "You can alter your interface in many ways. ", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_interface_client"]], ["Client"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Using a Client"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_interface_format"]], ["Format"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Your output format"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_interface_settings"]], ["Settings"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Configurable Settings"], 'do_dd]>], 'do_dl]>], #[['this, $help_interface]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_interface];
var $help_node nolist = 0;


new object $help_interface_client: $help_interface;

var $root manager = $help_interface_client;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847664123;
var $has_name name = ['prop, "Clients", "Clients"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "When you connect to a Virtual Environment System you use a ", <$format, ["i", [], ["client"], 'do_i]>, ". A client is simply a program you run from your machine. This program connects you with the server somewhere on the network. If you used ", <$format, ["tt", [], ["telnet"], 'do_tt]>, " to get here, your client is ", <$format, ["tt", [], ["telnet"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "This system is not designed for use with ", <$format, ["tt", [], ["telnet"], 'do_tt]>, ". It has many customized aspects for which telnet simply does not support. Because of this it is suggested for your own benefit and enjoyment that you get a more robust client. These include tinyfugue, pueblo and any other mud-specific client you can digup. Some client links:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["web", [["src", "ftp://tf.tcp.com/pub/tinyfugue"]], ["TinyFugue"], 'do_web]>, <$format, ["br", [], [], 'do_br]>, <$format, ["web", [["src", "http://www.awns.com/tkMOO-light/"]], ["tkMOO-lite"], 'do_web]>, <$format, ["br", [], [], 'do_br]>, <$format, ["web", [["src", "http://www.heynow.com/Savitar/"]], ["Savitar"], 'do_web]>], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_interface_client];
var $help_node nolist = 0;


new object $help_interface_format: $help_interface;

var $root manager = $help_interface_format;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847664131;
var $has_name name = ['prop, "Format", "Format"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "By default your output format is plaintext (text/plain). You can change this to other formats by setting your Content-Type. Currently supported alternate types are:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], ["Plain Text (text/plain)"], 'do_li]>, <$format, ["li", [], ["ANSI Text (text/ansi)"], 'do_li]>, <$format, ["li", [], ["HTML Text (text/html)"], 'do_li]>, <$format, ["li", [], ["Pueblo Browser Text (text/pueblo)"], 'do_li]>, <$format, ["li", [], ["TkMoo Text (text/tkmoo)"], 'do_li]>, <$format, ["li", [], ["Wrapped Text (text/wrapped)"], 'do_li]>], 'do_ul]>, <$format, ["np", [], [], 'do_np]>, "These formats can easilly be extended to include others. To change your output format use the command:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set content-type=type"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Where ", <$format, ["i", [], ["type"], 'do_i]>, " is one of the MIME encodings of the above types ie: text/plain. Use text/wrapped if your client doesn't wrap text automaticly."], #[]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_interface_format];
var $help_node nolist = 0;


new object $help_settings: $help_interface;

var $root manager = $help_settings;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847664220;
var $has_name name = ['prop, "Settings", "Settings"];
var $help_node links = #[["@set", $help_cmd_set]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "There are many configurable settings available for you to use in customizing your environment. The command ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_set"]], ["@set"], 'do_link]>], 'do_tt]>, " is used to make these changes. If you type ", <$format, ["tt", [], ["@set"], 'do_tt]>, " with no arguments it will list all of your current settings. To change a setting you simply type ", <$format, ["tt", [], ["@set"], 'do_tt]>, " followed by the setting name, an equals sign and the new value. If the value does not conform to the setting requirements you will be notified appropriately. For example, the following will turn on the capability to receive variable termination on messages (i.e. you can recieve text prompts that are not terminated with newlines):", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set non-terminated-tell=on"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "There may also exist ", <$format, ["i", [], ["user-info"], 'do_i]>, " settings. These define Real-Life aspects of you. They work slightly different. By default all user-info settings are private, and may not be seen by anybody else unless you include ", <$format, ["tt", [], ["+public"], 'do_tt]>, " at the beginning of the setting, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set real-name=+public Brandon Gilespie"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Read about the ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_set"]], ["@set"], 'do_link]>], 'do_tt]>, " command for more information."], #[['this, $help_settings]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_settings];
var $help_node nolist = 0;


new object $help_commands_enhanced: $help_general;

var $root manager = $help_commands_enhanced;
var $root created_on = 810075680;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Enhanced Command Templates", "Enhanced Command Templates"];
var $help_node links = #[["Programming Commands", $help_prog_commands]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The Cold Dark further expands upon the above matching systems, specifying certain types of arguments which can be accepted for a command, where the wildcard ('*') is located. These are specified within less-than and greater-than signs (", <$format, ["tt", [], ["<"], 'do_tt]>, " and ", <$format, ["tt", [], [">"], 'do_tt]>, "). These tags simply tell the parser what type of arguments to accept in that location on the command line. An example would be:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["push <user>"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Where <user> must be a valid user of the system, some more examples follow.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["\"l?ook at <thing>\"\n\"get|take <any> from <thing>\"\n\"@who <user>\"\n\"@show <object>\""], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "More information on Enhanced Command Templates can be found in the section ", <$format, ["link", [["node", "$help_prog_commands"]], ["Programming Commands"], 'do_link]>, "."], #[['this, $help_commands_enhanced]]]>;
var $root managed = [$help_commands_enhanced];
var $help_node nolist = 0;


new object $help_building: $help_coldcore;

var $root manager = $help_building;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847060847;
var $has_name name = ['prop, "Building", "Building"];
var $help_node links = #[["Theme", $help_theme], ["Dynamic Text", $help_cml], ["Places", $help_build_places], ["Messages", $help_sys_message], ["Commands", $help_building_commands]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Building in ColdCore is considered anything from describing yourself or an object you carry, to designing and creating full areas.", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_theme"]], ["Theme"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["The VR Theme"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_cml"]], ["Dynamic Text"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["The Cold text Markup Language"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_build_places"]], ["Places"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How Places work"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_sys_message"]], ["Messages"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Dynamic Messages"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_building_commands"]], ["Commands"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Overview of Building Commands"], 'do_dd]>], 'do_dl]>], #[['links, #[["Theme", "$help_theme"], ["Dynamic Text", "$help_cml"], ["Places", "$help_build_places"], ["Messages", "$help_sys_message"], ["Commands", "$help_building_commands"]]]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_building];
var $help_node nolist = 0;


new object $help_cml: $help_building;

var $root manager = $help_cml;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $root managed = [$help_cml];
var $has_name name = ['prop, "CML|Cold Markup Language", "CML|Cold Markup Language"];
var $help_node links = #[["Formatters", $help_cml_formatters], ["Generators", $help_cml_generators], ["Customizing", $help_cml_customizing]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "CML is used to markup text for dynamic generation and formatting. CML text is compiled to an internal abstraction called Ctext which can be easilly decompiled to plain text, HTML or any other format that may be desired. Ctext is also dynamically interpreted for each interface receiving the text. This gives extreme power in the final result, and is much faster than older MUD systems which use %x replacements in strings to achieve the same result. ", <$format, ["np", [], [], 'do_np]>, "The CML syntax is made of tags embedded within the text. Tags can be formatted one of two ways depending upon if they are for dynamic text generation (Generator) or as a formatting or other directive (Formatter): ", <$format, ["dfn", [["nobound", 1]], [<$format, ["table", [["cols", "30%,50%"]], [<$format, ["tr", [], [<$format, ["td", [], ["Generator Format:"], 'do_td]>, <$format, ["td", [], ["[<name> <options>:<arguments>]"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["Directive Format:"], 'do_td]>, <$format, ["td", [], ["{<name> <options>:<arguments>}"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Specific tag names may vary depending upon the system. For more information on the specific tags for this system see help on ", <$format, ["link", [["node", "$help_cml_formatters"]], ["Formatters"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_cml_generators"]], ["Generators"], 'do_link]>, ".", <$format, ["p", [], [], 'do_p]>, "The exact behaviour of a tag may be controlled using options (sometimes called flags). Options can be in any order, and are specified in one of two ways: ", <$format, ["dfn", [["nobound", 1]], [<$format, ["table", [["cols", "20%,50%"]], [<$format, ["tr", [], [<$format, ["td", [], ["key=value"], 'do_td]>, <$format, ["td", [], ["sets the option named key to value"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["key"], 'do_td]>, <$format, ["td", [], ["sets the option named key to true (if unspecified it will be false)."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "NOTE: If you need it include more than one word as the value, you have to backslash-escape the spaces, you cannot include the value in quotes. ", <$format, ["np", [], [], 'do_np]>, "Arguments (anything following the colon) Are optional, and depend upon the tag. How Arguments Are handled depends on whether the tag is a Generator or a Formatter. A Generator will treat it's Arguments as a space seperated list. A formatter will treat it's Argument as a single string, stArting at the first non-space chAracter following the colon. Arguments may contain other tags. ", <$format, ["np", [], [], 'do_np]>, "All tags with the exception of ", <$format, ["tt", [], ["quote"], 'do_tt]>, " follow this syntax. ", <$format, ["tt", [], ["quote"], 'do_tt]>, " can be used to include literal unparsed text in a document. It is similar to HTML's <pre> in that it includes any literal formatting of white space. However, it does ", <$format, ["i", [], ["NOT"], 'do_i]>, " parse any formatters or generators within it's body. ", <$format, ["tt", [], ["quote"], 'do_tt]>, " is formatted as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["{quote <text>}"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Where <text> is anything, including curly braces. Note: there is no colon following ", <$format, ["tt", [], ["quote"], 'do_tt]>, ", and there are no options for ", <$format, ["tt", [], ["quote"], 'do_tt]>, ". Further information on CML and Ctext can be found at:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["link", [["node", "$help_cml_formatters"]], ["Formatters"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["About CML Formatters"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cml_generators"]], ["Generators"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["About CML Generators"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cml_customizing"]], ["Customizing"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Customizing Ctext"], 'do_dd]>], 'do_dl]>], #[['links, #[["Formatters", "$help_cml_formatters"], ["Generators", "$help_cml_generators"], ["Customizing", "$help_cml_customizing"]]]]]>;
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_cml_formatters: $help_cml;

var $root manager = $help_cml_formatters;
var $root created_on = 809737729;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Formatters", "Formatters"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The standard formatter tags are loosely based on HTML 3.0: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "11%,89%"]], [<$format, ["tr", [], [<$format, ["td", [], ["action"], 'do_td]>, <$format, ["td", [], ["One flag of ", <$format, ["tt", [], ["cmd"], 'do_tt]>, ", which is run if the action is triggered (either by clicking on it, or using the action-trigger command ", <$format, ["tt", [], ["'>'."], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["b"], 'do_td]>, <$format, ["td", [], ["Bold or strong."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["br"], 'do_td]>, <$format, ["td", [], ["Line Break. Differs from {p} in that it can be stacked multiple times, for multiple breaks. Use of {p} is preferred."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dd"], 'do_td]>, <$format, ["td", [], ["Dictionary Definition, must be an argument to a Dictionary List (", <$format, ["tt", [], ["dl"], 'do_tt]>, ")."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["detail"], 'do_td]>, <$format, ["td", [], ["Generate a description detail. One required option of ", <$format, ["tt", [], ["name"], 'do_tt]>, " which is unique to this detail througout the entire description. Details may be nested."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dfn"], 'do_td]>, <$format, ["td", [], ["Definition. Used to indent a block of text. Arguments can be ", <$format, ["tt", [], ["ind"], 'do_tt]>, ", which is an integer representing the spaces to indent (in plaintext this defaults to eight); and ", <$format, ["tt", [], ["nobound"], 'do_tt]>, ", which effects the line breaks after the definition."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dl"], 'do_td]>, <$format, ["td", [], ["Dictionary list. Arguments can contain tags dt (dictionary title) and dd (dictionary definition)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dt"], 'do_td]>, <$format, ["td", [], ["Dictionary Title, must be an argument to a Dictionary List (", <$format, ["tt", [], ["dl"], 'do_tt]>, ")"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["i"], 'do_td]>, <$format, ["td", [], ["Italics or Emphasis."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["img"], 'do_td]>, <$format, ["td", [], ["Place image in description. Image is only visible in HTML formats."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["lh"], 'do_td]>, <$format, ["td", [], ["List Header, must be an argument for ", <$format, ["tt", [], ["ol"], 'do_tt]>, " or ", <$format, ["tt", [], ["ul."], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["li"], 'do_td]>, <$format, ["td", [], ["List Element, must be an argument for ", <$format, ["tt", [], ["ol"], 'do_tt]>, " or ", <$format, ["tt", [], ["ul."], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["link"], 'do_td]>, <$format, ["td", [], ["Creates a hypertext link to the help node (as an objname) specified with the option ", <$format, ["tt", [], ["node."], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["np"], 'do_td]>, <$format, ["td", [], ["New Paragraph, similar to {p}, but in plaintext it breaks with two lines rather than one."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["ol"], 'do_td]>, <$format, ["td", [], ["Ordered list. Within arguments use tags lh (list header) and li (list element)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["p"], 'do_td]>, <$format, ["td", [], ["Paragraph Break, similar to {np}, but in plaintext it only breaks with one line."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["subj"], 'do_td]>, <$format, ["td", [], ["Rougly equivalent to HTML's header <h?> tags. Argument ", <$format, ["tt", [], ["level"], 'do_tt]>, " specifies which level of subject to use (1-4) and defaults to a value of 4."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["table"], 'do_td]>, <$format, ["td", [], ["Similar to tables in HTML. Options are ", <$format, ["tt", [], ["ind"], 'do_tt]>, " (how many spaces to indent the table before formatting) and ", <$format, ["tt", [], ["cols"], 'do_tt]>, " (column definition). ", <$format, ["tt", [], ["cols"], 'do_tt]>, " must be defined. It is a comma seperated list of column specs, which can either be in specific character units or percentages (the whole list must be either one or the other). Arguments consist of ", <$format, ["tt", [], ["tr"], 'do_tt]>, " (table row) tags."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["td"], 'do_td]>, <$format, ["td", [], ["Table Cell, options include ", <$format, ["tt", [], ["colspan"], 'do_tt]>, " and ", <$format, ["tt", [], ["rowspan"], 'do_tt]>, " which can be used to span columns and rows with the Table Cell."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["tr"], 'do_td]>, <$format, ["td", [], ["Table Row, arguments consist of ", <$format, ["tt", [], ["td"], 'do_tt]>, " tags for each table cell in the row."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["tt"], 'do_td]>, <$format, ["td", [], ["Fixed-width font (typewriter), also used for literal text."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["ul"], 'do_td]>, <$format, ["td", [], ["Unordered list. Within arguments use tags lh (list header) and li (list element)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["web"], 'do_td]>, <$format, ["td", [], ["Creates a www hypertext link. This tag requires ", <$format, ["tt", [], ["src"], 'do_tt]>, " and ", <$format, ["tt", [], ["name"], 'do_tt]>, " options. The ", <$format, ["tt", [], ["src"], 'do_tt]>, " should have a valid URL as the value and the ", <$format, ["tt", [], ["name"], 'do_tt]>, " should have the name of the URL to be displayed."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[]]>;
var $root managed = [$help_cml_formatters];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_cml_generators: $help_cml;

var $root manager = $help_cml_generators;
var $root created_on = 809736951;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Generators", "Generators"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "16%,84%"]], [<$format, ["tr", [], [<$format, ["td", [], ["columnize"], 'do_td]>, <$format, ["td", [], ["Generates a list of columnized strings taken from the argument list. Option ", <$format, ["tt", [], ["cols"], 'do_tt]>, " defines column information."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["def"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["var"], 'do_tt]>, " which is the name of a variable. Creates a new variable generator with that name, which has the value of the first argument. Will ", <$format, ["i", [], ["not"], 'do_i]>, " evaluate arguments, instead stores the unparsed first argument. Similar to ", <$format, ["tt", [], ["set"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["english"], 'do_td]>, <$format, ["td", [], ["Generates an english-formatted list from the arguments. Options can include ", <$format, ["tt", [], ["sep"], 'do_tt]>, " (element seperator, defaulting to \",\"), ", <$format, ["tt", [], ["empty"], 'do_tt]>, " (what to print if the argument list is empty, defaulting to \"nothing\"), ", <$format, ["tt", [], ["and"], 'do_tt]>, " (what to print as a seperator before the last element, defaulting to \"and\")"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["foreach"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["list"], 'do_tt]>, ". Will iterate over body for each element in list. Additional option ", <$format, ["tt", [], ["var"], 'do_tt]>, " may be defined for iteration variable, defaults to ", <$format, ["tt", [], ["iterator"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["join"], 'do_td]>, <$format, ["td", [], ["Joins arguments. Options can include ", <$format, ["tt", [], ["seperator"], 'do_tt]>, " which is either ", <$format, ["tt", [], ["none"], 'do_tt]>, ", ", <$format, ["tt", [], ["english"], 'do_tt]>, " or a string literal. If ", <$format, ["tt", [], ["none"], 'do_tt]>, " the list is forwarded to the caller, rather than joined to a string"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["name"], 'do_td]>, <$format, ["td", [], ["Generates the names of the objects in the arguments list. Options can include ", <$format, ["tt", [], ["seperator"], 'do_tt]>, " which is either ", <$format, ["tt", [], ["none"], 'do_tt]>, ", ", <$format, ["tt", [], ["english"], 'do_tt]>, " or a string literal. If ", <$format, ["tt", [], ["none"], 'do_tt]>, " is given a list is generated, otherwise a string is generated"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["pro"], 'do_td]>, <$format, ["td", [], ["Generates a pronoun. Required option is ", <$format, ["tt", [], ["obj"], 'do_tt]>, " which defines the object for the pronoun generation. First argument is taken as the type of pronoun to use, as defined on $gender"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["random"], 'do_td]>, <$format, ["td", [], ["Returns a random number ranging from ", <$format, ["tt", [], ["low"], 'do_tt]>, " to ", <$format, ["tt", [], ["high"], 'do_tt]>, " which are given as options. Low can be omitted, one is used then instead."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["servname"], 'do_td]>, <$format, ["td", [], ["The name of the server, as is set on ", <$format, ["tt", [], ["@set $motd:server-name"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["set"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["var"], 'do_tt]>, " which is the name of a variable. Creates a new variable generator with that name, which has the value of the first argument. Will evaluate arguments and store results. Similar to ", <$format, ["tt", [], ["def"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["switch"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["value"], 'do_tt]>, " which is evaluated. The resulting value is then used to select a result. Currently switch uses every other item in the argument list as a case/value pair (use the ", <$format, ["tt", [], ["join"], 'do_tt]>, " generator for arguments with spaces). If there is a remaining odd element is is considered the default result"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["time"], 'do_td]>, <$format, ["td", [], ["Arguments are sent to the native method $time.format()"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["vars"], 'do_td]>, <$format, ["td", [], ["Returns the names of variables available. Option ", <$format, ["tt", [], ["separator"], 'do_tt]>, " is the same as in ", <$format, ["tt", [], ["name"], 'do_tt]>, " generator"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, " ", <$format, ["subj", [["level", "4"]], ["Other tags"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Each cml processor can also create extra generators. Also, caller to the cml can create extra variables that are available for generators."], #[]]>;
var $root managed = [$help_cml_generators];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_cml_customizing: $help_cml;

var $root manager = $help_cml_customizing;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837752811;
var $has_name name = ['prop, "Customizing Ctext", "Customizing Ctext"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["subj", [["level", "3"]], ["Interface"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Ctext frobs are created by calling the .", <$format, ["method", [["compiler.compile_cml", 1]], ["compile_cml"], 'do_method]>, "() method off the cml compiler object. On a ctext frob, you may call .", <$format, ["method", [["ctext_frob.uncompile", 1]], ["uncompile"], 'do_method]>, "() to return the original text. A call to .", <$format, ["method", [["ctext_frob.eval_ctext", 1]], ["eval_ctext"], 'do_method]>, "() evaluates the generators, but will not touch the formatters. This is used to speed up message dispatching. Calling ", <$format, ["method", [["ctext_frob.format", 1]], ["format"], 'do_method]>, "() provides the final formatting of the ctext, evaluating everything, including the formatters. You can add/modify variables on a ctext frob by calling .", <$format, ["method", [["ctext_frob.set_var", 1]], ["set_var"], 'do_method]>, "(", <$format, ["var", [], ["variable"], 'do_var]>, ", ", <$format, ["var", [], ["value"], 'do_var]>, "), or .", <$format, ["method", [["ctext_frob.set_vars", 1]], ["set_vars"], 'do_method]>, "(", <$format, ["var", [], ["dict"], 'do_var]>, "), which does the same, but assigning multiple variables at once. ", <$format, ["subj", [["level", "3"]], ["Adding new evaluators"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "An evaluator is an object which contains methods for generation or formatting. An evaluation object that is descended from a vanilla evaluator (like $bs_eval) will try to store the evaluation results in a list, and is therefore most suitable for adding new generators. On the other hand, evaluators descended from a formatter object create a string, and try to evaluate and concatenate lists until a string is obtained. Hence, they should be used for formatting. To add a new generator or formatter, simply add a do_format or gen_generator method on the object, where 'format' or 'generator' is the name of the new tag that you wish to add. Make sure that the object is in the evaluation path (by explicitly adding an 'evaluator, 'formatter or even an 'uncompiler field to the ctext frob.)"], #[]]>;
var $root inited = 1;
var $root managed = [$help_cml_customizing];
var $help_node nolist = 0;


new object $help_build_places: $help_building;

var $root manager = $help_build_places;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855981673;
var $root managed = [$help_build_places];
var $has_name name = ['prop, "Places", "Places"];
var $help_node links = #[["Pathways", $help_places_paths], ["Realms", $help_places_realms], ["environment conditions", $help_places_env], ["Permissions", $help_places_env], ["Environmental Conditions", $help_places_env], ["Weather", $help_weather_system]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Places are a form of location in the Virtual Environment. Locations are the key factor of a Virtual Reality--everything must exist somewhere. It is possible for a location to be a location itself, such as a box which can hold something and also be located in a room or on a patio. ", <$format, ["np", [], [], 'do_np]>, "Places have more information than the rudimentary Location. They are generally not located Locations, but instead represent a physical area in the Virtual Environment, such as a room in a building or a sidewalk outside of a building. They also define ", <$format, ["link", [["node", "$help_places_paths"]], ["Pathways"], 'do_link]>, " to other Places, ", <$format, ["link", [["node", "$help_places_realms"]], ["Realms"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_places_env"]], ["environment conditions"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "Realms are a form of meta-place. Multiple places can be grouped into a single realm. Realms can be defined heirarchially, so you can have a building in a realm which is a district of a city, which is in the city's realm, which is in the country's realm, and so forth. The realm defines broad aspects of the Virtual Environment, such as ", <$format, ["link", [["node", "$help_places_env"]], ["Permissions"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_places_env"]], ["Environmental Conditions"], 'do_link]>, " like ", <$format, ["link", [["node", "$help_weather_system"]], ["Weather"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, " See Also: ", <$format, ["link", [["node", "$help_places_realms"]], ["Realms"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_places_paths"]], ["Pathways"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_places_env"]], ["Environmental Conditions"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_places_env"]], ["Permissions"], 'do_link]>], #[['links, #[["Pathways", "$help_places_paths"], ["Realms", "$help_places_realms"], ["environment conditions", "$help_places_env"], ["Permissions", "$help_places_env"], ["Environmental Conditions", "$help_places_env"], ["Weather", "$help_weather_system"]]]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_places_realms: $help_build_places;

var $root manager = $help_places_realms;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856037606;
var $root managed = [$help_places_realms];
var $has_name name = ['prop, "Realms", "Realms"];
var $help_node links = #[["@spawn", $help_cmd_spawn], ["setting", $help_settings], ["@def-setting", $help_cmd_defsetting]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Realms are used to group places, and can exist in a heirarchy structure. For instance, all rooms within a building would exist within one realm for that building, and that realm would exist within a realm for that sector of the city, which exists within a realm for the entire city. Realms are useful not only for grouping, but also for events and searching. When an event occurs it can be broadcast to the entire realm, rather than just to the local room. ", <$format, ["np", [], [], 'do_np]>, "New realms are created with the command ", <$format, ["link", [["node", "$help_cmd_spawn"]], ["@spawn"], 'do_link]>, ", such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@spawn $realm named the Clocktower"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When creating a realm make sure to create it from the right parent, so as to keep the heirarchy intact. For instance, the above realm might be better spawned from a realm for the city. ", <$format, ["np", [], [], 'do_np]>, "Realms keep track of all the rooms they contain. When room is created or destroyed, its realm is updated accordingly. You can change the room's realm using its :realm ", <$format, ["link", [["node", "$help_interface_settings"]], ["setting"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "Realms also keep track of realm properties. You can add your own realm property as you would add any other setting, but make sure that +get method is set to get_realm_setting (read ", <$format, ["link", [["node", "$help_cmd_defsetting"]], ["@def-setting"], 'do_link]>, " helpnode for information about this). Realm properties have special inheritance scheme: rooms inherit them from their realm, and realms inherit it from their parents. There are two default realm properties: propagate, which controls propagation mask from the parent realm, and weather-time, which sets the weather and time for the realm. ", <$format, ["np", [], [], 'do_np]>, "You can announce a message to all the players in a realm using realm_announce method on the realm object. Note that it will be propagated using the propagation masks."], #[['links, #[["@spawn", "$help_cmd_spawn"], ["setting", "$help_interface_settings"], ["@def-setting", "$help_cmd_defsetting"]]]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_places_paths: $help_build_places;

var $root manager = $help_places_paths;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856037607;
var $root managed = [$help_places_paths];
var $has_name name = ['prop, "Pathways|paths|exits|entrances", "Pathways|paths|exits|entrances"];
var $help_node links = #[["places", $help_build_places], ["@build", $help_cmd_build], ["@dig", $help_cmd_dig], ["Building Permissions", $help_places_perms]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Paths connect ", <$format, ["link", [["node", "$help_build_places"]], ["places"], 'do_link]>, " to each other. A path can have one or more ways, but usually only have two ways (i.e. down the path and up the path). When you build a place you have the option to specify the exit, or in other words, one way for the path. You can use either the command ", <$format, ["link", [["node", "$help_cmd_build"]], ["@build"], 'do_link]>, ", or the command ", <$format, ["link", [["node", "$help_cmd_dig"]], ["@dig"], 'do_link]>, ", depending upon if you want an interactive or passive user interface. ", <$format, ["np", [], [], 'do_np]>, "Before you can link paths from a place you have to be able to build from it. For more information in this regard, see the section ", <$format, ["link", [["node", "$help_places_perms"]], ["Building Permissions"], 'do_link]>, ". You can create a place disconnected from the rest of the Virtual Environment with the command:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@dig My New Room"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Which will create a new place with the name ", <$format, ["tt", [], ["\"My New Room\""], 'do_tt]>, ", which is in the realm of Creation (no realm)."], #[['links, #[["places", "$help_build_places"], ["@build", "$help_cmd_build"], ["@dig", "$help_cmd_dig"], ["Building Permissions", "$help_places_perms"]]]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_places_env: $help_build_places;

var $root manager = $help_places_env;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856037607;
var $root managed = [$help_places_env];
var $has_name name = ['prop, "Environment Conditions", "Environment Conditions"];
var $help_node links = #[["weather", $help_weather_system], ["@set", $help_cmd_set], ["Realms", $help_places_realms]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Environment Conditions in a room include how light or dark it is (which can effect how visible things are) and if the place is outside this also includes the ", <$format, ["link", [["node", "$help_weather_system"]], ["weather"], 'do_link]>, " and other atmospheric conditions. ", <$format, ["np", [], [], 'do_np]>, "The core place has a few common settings. To see the current settings, type ''", <$format, ["tt", [], ["@set YOURPLACE:"], 'do_tt]>, "'' or ''", <$format, ["tt", [], ["@set here:"], 'do_tt]>, "'' if you are currently in the location. Use the command ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_set"]], ["@set"], 'do_link]>], 'do_tt]>, " to change settings. ", <$format, ["subj", [["level", "2"]], ["Visibility and Darkness"], 'do_subj]>, " All objects in the Virtual Environment have a visibility setting. This is a number from +10 to -10, representing the object's relative visibility. Numbers above zero are highly visible (such as a neon sign) and those below zero are less visible (such as a black key sitting on a cluttered table). ", <$format, ["np", [], [], 'do_np]>, "Visibility is relative to the room's Darkness rating. Darkness is rated on the same scale as Visibility. Numbers above zero increase the light in a room, where numbers below zero decrease the light in a room (to -10 being pitch-dark). The darkness rating can be changed by VR actions such as turning on a light switch or bringing a torch into the room. ", <$format, ["np", [], [], 'do_np]>, "When determining if an object is visible in the room, its visibility rating must be greater than or equal to the location's darkness rating. ", <$format, ["subj", [["level", "2"]], ["Realm"], 'do_subj]>, " The realm setting defines what realm the place is a part of. See the ", <$format, ["link", [["node", "$help_places_realms"]], ["Realms"], 'do_link]>, " section for more information. ", <$format, ["subj", [["level", "2"]], ["Public-Home"], 'do_subj]>, " If this is true, other builders can build from this room and any user can make it be their home with ''", <$format, ["tt", [], ["@set me:home=here"], 'do_tt]>, "''. ", <$format, ["subj", [["level", "2"]], ["Restrict-Entry"], 'do_subj]>, " Not currently setup. ", <$format, ["subj", [["level", "2"]], ["Other"], 'do_subj]>, " Additional settings are defined which need to be documented, such as mapping and sound propagation."], #[['links, #[["weather", "$help_weather_system"], ["@set", "$help_cmd_set"], ["Realms", "$help_places_realms"]]]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_places_perms: $help_build_places;

var $root manager = $help_places_perms;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 1010724353;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Permissions|Builder Permissions|perms", "Permissions|Builder Permissions|perms"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Building Permissions are those which allow you to build pathways from one location to another. There are a few ways to allow people to build: adding them as a writer or trustee to a room (this only allows them to build from the current room), set the room as a public home (same as adding them as a writer), or add them as a trustee to the realm or one of the realms in the heirarchy of realms above the current room. The latter option is the most preferrable for wide-spread building. ", <$format, ["np", [], [], 'do_np]>, "For example. Consider a room with the name of Broom Closet. This room is defined as a member of the $realm_of_the_inn, which is also in the $realm_of_the_city. If somebody were to be added as a trustee to the $realm_of_the_city, they would be able to build a pathway from the Broom Closet (because the city is an ancestral realm of the Broom Closet). They would also be able to write to any other place defined within the realm of the city. For more granularity, somebody could only be added to the $realm_of_the_inn, which would restrict them to building within the Inn. ", <$format, ["np", [], [], 'do_np]>, "To add a trustee type: ''", <$format, ["tt", [], ["@chown REALM +trustee=WHO"], 'do_tt]>, "'', such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@chown $realm_of_the_city +t=Levi"], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_places_perms];


new object $help_building_commands: $help_building;

var $root manager = $help_building_commands;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 889749160;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Commands|Building|Builder", "Commands|Building|Builder"];
var $help_node links = #[["@attach", $help_cmd_attach], ["@build", $help_cmd_build], ["@child?ren", $help_cmd_children], ["@def-msg", $help_cmd_defmsg], ["@destroy", $help_cmd_destroy], ["@dig", $help_cmd_dig], ["@msg?s", $help_cmd_msg], ["@move", $help_cmd_move], ["@new", $help_cmd_new], ["@par?ents", $help_cmd_parents], ["@realm?s", $help_cmd_realms], ["@teleport or @go", $help_cmd_teleport], ["@undef-msg", $help_cmd_defmsg]];
var $help_node body = <$ctext_frob, [[<$format, ["b", [], ["Builder Commands Listing"], 'do_b]>, " ", <$format, ["np", [], [], 'do_np]>, "The following commands are available to builders: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "30%,70%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_attach"]], ["@attach"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Attaches an exit to a $place"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_build"]], ["@build"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["A script-like interface to simplify the building process."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_children"]], ["@child?ren"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Lists the object's children and shows some brief information about them."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_defmsg"]], ["@def-msg"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Used to define messages on an object"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_destroy"]], ["@destroy"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Destroys an object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_dig"]], ["@dig"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Makes a new place and can attach exits with a single command."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_msg"]], ["@msg?s"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Used to view and set messages on objects."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_move"]], ["@move"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Moves an object to another location."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_new"]], ["@new"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Creates a new object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_parents"]], ["@par?ents"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Lists parents of the object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_realms"]], ["@realm?s"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Shows all known realms."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_teleport"]], ["@teleport or @go"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Moves you a specified location."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_defmsg"]], ["@undef-msg"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Removes a message from an object."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["@attach", "$help_cmd_attach"], ["@build", "$help_cmd_build"], ["@child?ren", "$help_cmd_children"], ["@def-msg", "$help_cmd_defmsg"], ["@destroy", "$help_cmd_destroy"], ["@dig", "$help_cmd_dig"], ["@msg?s", "$help_cmd_msg"], ["@move", "$help_cmd_move"], ["@new", "$help_cmd_new"], ["@par?ents", "$help_cmd_parents"], ["@realm?s", "$help_cmd_realms"], ["@teleport or @go", "$help_cmd_teleport"], ["@undef-msg", "$help_cmd_defmsg"]]]]]>;
var $root inited = 1;
var $has_name templates = ["Builder commands"];
var $root managed = [$help_building_commands];


new object $help_prog: $help_coldcore;

var $root manager = $help_prog;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 846999513;
var $has_name name = ['prop, "Programming", "Programming"];
var $help_node links = #[["OOP", $help_coldc_oop], ["ColdC", $help_coldc], ["Commands", $help_prog_commands]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Be warned: anything from this section down is not complete.", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["link", [["node", "$help_coldc_oop"]], ["OOP"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Object Oriented Programming"], 'do_dd]>, <$format, ["dt", [], ["Programming a Method"], 'do_dt]>, <$format, ["dd", [], ["Overview on creating a method"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_coldc"]], ["ColdC"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["ColdC Reference Manual"], 'do_dd]>, <$format, ["dt", [], ["Functions"], 'do_dt]>, <$format, ["dd", [], ["Function Reference"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_prog_commands"]], ["Commands"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Overview of Programming Commands"], 'do_dd]>], 'do_dl]>], #[['this, $help_prog]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_prog];
var $help_node nolist = 0;


new object $help_prog_commands: $help_prog;

var $root manager = $help_prog_commands;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 846999554;
var $has_name name = ['prop, "Programming Commands", "Programming Commands"];
var $help_node links = #[["@add-command", $help_cmd_addcmd], ["@add-parent", $help_cmd_addparent], ["@add-shortcut", $help_cmd_addshortcut], ["@add-variable", $help_cmd_addvariable], ["@ancestors", $help_cmd_ancestors], ["@chp?arents", $help_cmd_chparent], ["@chmod", $help_cmd_chmod], ["@config-set?ting", $help_cmd_configsetting], ["@d?isplay", $help_cmd_display], ["@def-set?ting", $help_cmd_defsetting], ["@del-c?ommand", $help_cmd_delcmd], ["@del-m?ethod", $help_cmd_delmethod], ["@del-p?arent", $help_cmd_delparent], ["@del-s?hortcut", $help_cmd_delshortcut], ["@del-v?ariable", $help_cmd_delvariable], ["@descend?ants", $help_cmd_descendants], ["@dump", $help_cmd_dump], ["@eval", $help_cmd_eval], ["@grep", $help_cmd_grep], ["@hl?ist", $help_cmd_hlist], ["@hw?rite", $help_cmd_hwrite], ["@id", $help_cmd_id], ["@join", $help_cmd_join], ["@list", $help_cmd_list], ["@move", $help_cmd_move], ["@copy", $help_cmd_move], ["@new-help-node", $help_cmd_nh], ["@program", $help_cmd_program], ["@rehash", $help_cmd_rehash], ["@show", $help_cmd_show], ["@spawn", $help_cmd_spawn], ["@trace", $help_cmd_trace], ["@undef-set?ting", $help_cmd_undefsetting], ["@which", $help_cmd_which]];
var $help_node body = <$ctext_frob, [[<$format, ["b", [], ["Programmer Commands Listing"], 'do_b]>, " ", <$format, ["np", [], [], 'do_np]>, "The following commands are available to programmers: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "30%,70%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_addcmd"]], ["@add-command"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Adds a command to a specific method."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_addparent"]], ["@add-parent"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Adds a parent to the target object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_addshortcut"]], ["@add-shortcut"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Adds a shortcut to a specified command."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_addvariable"]], ["@add-variable"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Adds a variable to the object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_ancestors"]], ["@ancestors"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Shows the objects \"tree\" of parents."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_chparent"]], ["@chp?arents"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Changes parents of object"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_chmod"]], ["@chmod"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Modifies the access flags on the object or method."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_configsetting"]], ["@config-set?ting"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Allows you to modify the options set when the setting was created."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_display"]], ["@d?isplay"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Displays general information about an object, and optionally shows methods."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_defsetting"]], ["@def-set?ting"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Creates new settings on objects."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_delcmd"]], ["@del-c?ommand"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Removes a command from the object"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_delmethod"]], ["@del-m?ethod"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Deletes a method from an object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_delparent"]], ["@del-p?arent"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Removes a parent from an object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_delshortcut"]], ["@del-s?hortcut"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Removes a defined shortcut to a command."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_delvariable"]], ["@del-v?ariable"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Removes a variable from the object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_descendants"]], ["@descend?ants"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Lists the objects the have that object as an ancestor."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_dump"]], ["@dump"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["gives a complete textdump of an object"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_eval"]], ["@eval"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Used to test methods without programing them."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_grep"]], ["@grep"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Used to search methods on an object for specific text."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_hlist"]], ["@hl?ist"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Shows a help node in CML text."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_hwrite"]], ["@hw?rite"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["A one chance input to enter CML text for a help node."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_id"]], ["@id"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Summary information similar to @display"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_join"]], ["@join"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Teleports you to a user."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_list"]], ["@list"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Lists source code for the method."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_move"]], ["@move"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Moves methods or objects to another location"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_move"]], ["@copy"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Copies methods to another location"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_nh"]], ["@new-help-node"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Creates a new help node."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_program"]], ["@program"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Allows user to input data and then save and compile the text with a \".\" on a blank line."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_rehash"]], ["@rehash"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Updates your command cache."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_show"]], ["@show"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Displays methods, variables, messages, and other information about an object or method"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_spawn"]], ["@spawn"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Creates a new object"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_trace"]], ["@trace"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Returns where and object receives an inherited method."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_undefsetting"]], ["@undef-set?ting"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Removes a setting from an object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_which"]], ["@which"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Tells you where the method behind the command is."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["@add-command", "$help_cmd_addcmd"], ["@add-parent", "$help_cmd_addparent"], ["@add-shortcut", "$help_cmd_addshortcut"], ["@add-variable", "$help_cmd_addvariable"], ["@ancestors", "$help_cmd_ancestors"], ["@chp?arents", "$help_cmd_chparent"], ["@chmod", "$help_cmd_chmod"], ["@config-set?ting", "$help_cmd_configsetting"], ["@d?isplay", "$help_cmd_display"], ["@def-set?ting", "$help_cmd_defsetting"], ["@del-c?ommand", "$help_cmd_delcmd"], ["@del-m?ethod", "$help_cmd_delmethod"], ["@del-p?arent", "$help_cmd_delparent"], ["@del-s?hortcut", "$help_cmd_delshortcut"], ["@del-v?ariable", "$help_cmd_delvariable"], ["@descend?ants", "$help_cmd_descendants"], ["@dump", "$help_cmd_dump"], ["@eval", "$help_cmd_eval"], ["@grep", "$help_cmd_grep"], ["@hl?ist", "$help_cmd_hlist"], ["@hw?rite", "$help_cmd_hwrite"], ["@id", "$help_cmd_id"], ["@join", "$help_cmd_join"], ["@list", "$help_cmd_list"], ["@move", "$help_cmd_move"], ["@copy", "$help_cmd_move"], ["@new-help-node", "$help_cmd_nh"], ["@program", "$help_cmd_program"], ["@rehash", "$help_cmd_rehash"], ["@show", "$help_cmd_show"], ["@spawn", "$help_cmd_spawn"], ["@trace", "$help_cmd_trace"], ["@undef-set?ting", "$help_cmd_undefsetting"], ["@which", "$help_cmd_which"]]]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_prog_commands];
var $help_node nolist = 0;


new object $help_coldc: $help_prog;

var $root manager = $help_coldc;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853692931;
var $has_name name = ['prop, "ColdC Reference Manual", "ColdC Reference Manual"];
var $help_node links = #[["Object Oriented Programming", $help_coldc_oop], ["Conventions used in this Document", $help_conventions], ["ColdC Objects", $help_coldc_objs], ["Referencing Objects", $help_coldc_objs_ref], ["Methods", $help_coldc_methods], ["Variables", $help_coldc_objs_vars], ["Special Objects", $help_coldc_objs_special], ["Tokens", $help_coldc_tokens], ["Data Types", $help_coldc_types], ["Expressions", $help_coldc_expr], ["Statements", $help_coldc_stmts], ["Frames and Tasks", $help_coldc_tasks], ["Errors", $help_coldc_errors], ["Security", $help_coldc_security], ["Networking", $help_coldc_net], ["Regular Expressions", $help_coldc_regexp], ["Files", $help_coldc_files], ["Textdump Structure", $help_coldc_textdump], ["Function Reference", $help_coldc_func], ["Native Method Reference", $help_coldc_native]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdC was initially created by Greg Hudson with ColdMUD, and was later developed and evolved by many enterprising individuals. ColdC is a low-profile object oriented database language. It is intended for network servers which require run-time morphism (such as Virtual/Interactive Environment Servers). ", <$format, ["np", [], [], 'do_np]>, "This reference manual is written by Brandon Gillespie, with portions being taken from the ColdMUD Reference manual written by Greg Hudson and additions by various Cold contributors. ", <$format, ["np", [], [], 'do_np]>, "For the most part, this manual specifies the language definition for ColdC 1.1. Some sections may be in addition to this specification (such as Native Methods).", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_oop"]], ["Object Oriented Programming"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_conventions"]], ["Conventions used in this Document"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs"]], ["ColdC Objects"], 'do_link]>], 'do_li]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_ref"]], ["Referencing Objects"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_methods"]], ["Methods"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_vars"]], ["Variables"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_special"]], ["Special Objects"], 'do_link]>], 'do_li]>], 'do_ul]>, <$format, ["li", [], ["Language Structure"], 'do_li]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_tokens"]], ["Tokens"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_types"]], ["Data Types"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_expr"]], ["Expressions"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_stmts"]], ["Statements"], 'do_link]>], 'do_li]>], 'do_ul]>, <$format, ["li", [], ["Implementation Reference"], 'do_li]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_methods"]], ["Methods"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_tasks"]], ["Frames and Tasks"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_errors"]], ["Errors"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_security"]], ["Security"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_net"]], ["Networking"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_regexp"]], ["Regular Expressions"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_files"]], ["Files"], 'do_link]>], 'do_li]>], 'do_ul]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_textdump"]], ["Textdump Structure"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_func"]], ["Function Reference"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_native"]], ["Native Method Reference"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['links, #[["Object Oriented Programming", "$help_coldc_oop"], ["Conventions used in this Document", "$help_conventions"], ["ColdC Objects", "$help_coldc_objs"], ["Referencing Objects", "$help_coldc_objs_ref"], ["Methods", "$help_coldc_methods"], ["Variables", "$help_coldc_objs_vars"], ["Special Objects", "$help_coldc_objs_special"], ["Tokens", "$help_coldc_tokens"], ["Data Types", "$help_coldc_types"], ["Expressions", "$help_coldc_expr"], ["Statements", "$help_coldc_stmts"], ["Frames and Tasks", "$help_coldc_tasks"], ["Errors", "$help_coldc_errors"], ["Security", "$help_coldc_security"], ["Networking", "$help_coldc_net"], ["Regular Expressions", "$help_coldc_regexp"], ["Files", "$help_coldc_files"], ["Textdump Structure", "$help_coldc_textdump"], ["Function Reference", "$help_coldc_func"], ["Native Method Reference", "$help_coldc_native"]]]]]>;
var $root inited = 1;
var $root managed = [$help_coldc];
var $help_node nolist = 0;


new object $help_coldc_oop: $help_coldc;

var $root manager = $help_coldc_oop;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853694227;
var $has_name name = ['prop, "Object Oriented Programming|OOP", "Object Oriented Programming|OOP"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Object Oriented Programming (OOP) is a style of programming which not only groups procedures and data by functionality but which also applies a few common rules to how this grouping occurs. In OOP designers group procedures and data into ", <$format, ["i", [], ["modules"], 'do_i]>, ". By doing this it helps to define the purpose of the program, and also gives the added benefit of portability (porting a modular segment of code to another program is much easier than porting an integrated segment of code). ", <$format, ["np", [], [], 'do_np]>, "These modules (or ", <$format, ["i", [], ["objects"], 'do_i]>, ") will generally follow a few guidelines:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["Abstraction and Encapsulation of Data"], 'do_li]>, <$format, ["li", [], ["Inheritance"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "Because data and procedures are grouped together, all procedures which handle the specific data should be included within the module. ", <$format, ["i", [], ["Abstraction and Encapsulation"], 'do_i]>, " occurs when the module abstracts and controls access to the data it manipulates. The internal representation of data used by a module is most likely irrelevant to external sources (with the interface being the primary concern). ", <$format, ["np", [], [], 'do_np]>, "An example of ", <$format, ["i", [], ["Abstraction and Encapsulation"], 'do_i]>, " would be a table of people and their pets. The 'People and Pets' module has several procedures:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["i", [], ["Add Person"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Add a Person to the table. This procedure is passed the person, and their pet."], 'do_dd]>, <$format, ["dt", [], [<$format, ["i", [], ["Remove Person"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Remove a Person from the table. This procedure is passed the person to be removed."], 'do_dd]>, <$format, ["dt", [], [<$format, ["i", [], ["Get Pet"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["This procedure finds the pet for a given person. It is passed the person and returns the Pet associated with that person."], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "In the People and Pets module the table can be internalized in any form. The form is irrelevant to external programs which may use it. ", <$format, ["np", [], [], 'do_np]>, <$format, ["i", [], ["Inheritance"], 'do_i]>, " is the ability of another module to take on the functionality an existing module and further expand upon it. For instance, a 'People, Pets and their Names' module could be created which takes on the functionality of 'People and Pets', but expands it to include the names of the pets. ", <$format, ["np", [], [], 'do_np]>, "Inheritance is extremely useful because code becomes reusable and extendable without having to re-create each portion or module for different functionality. ", <$format, ["np", [], [], 'do_np]>, "In inheritance a module taking on the functionality of another object is called ", <$format, ["i", [], ["deriving"], 'do_i]>, " from that object. For instance, 'People, Pets and their Names' is derived from 'People and Pets'. The module 'People, Pets and their Names' is a ", <$format, ["i", [], ["child"], 'do_i]>, " of 'People and Pets', with 'People and Pets' being the ", <$format, ["i", [], ["parent"], 'do_i]>, " of 'People, Pets and their Names'."], #[['this, $help_coldc_oop]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_oop];
var $help_node nolist = 0;


new object $help_coldc_objs: $help_coldc;

var $root manager = $help_coldc_objs;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853696071;
var $has_name name = ['prop, "Objects", "Objects"];
var $help_node links = #[["parents", $help_coldc_oop], ["children", $help_coldc_oop], ["methods", $help_coldc_objs_methods], ["variables", $help_coldc_objs_vars], ["Referencing Objects", $help_coldc_objs_ref], ["Special Objects", $help_coldc_objs_special]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "An object in ColdC is both a data type and a database record. Objects are structured with ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_oop"]], ["parents"], 'do_link]>], 'do_i]>, " and ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_oop"]], ["children"], 'do_link]>], 'do_i]>, " in a tree (geneology-style) heirarchy known as the ", <$format, ["i", [], ["object heirarchy"], 'do_i]>, ". An object has both ColdC procedures (", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_objs_methods"]], ["methods"], 'do_link]>], 'do_i]>, ") and ColdC Data (", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_objs_vars"]], ["variables"], 'do_link]>], 'do_i]>, ") bound to it. The object variables are accessed and modified by the methods defined on the object. ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_ref"]], ["Referencing Objects"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_methods"]], ["Methods"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_vars"]], ["Variables"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_special"]], ["Special Objects"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_objs]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_objs];
var $help_node nolist = 0;


new object $help_coldc_objs_ref: $help_coldc_objs;

var $root manager = $help_coldc_objs_ref;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853696071;
var $has_name name = ['prop, "Referencing Objects", "Referencing Objects"];
var $help_node links = #[["identifier", $help_coldc_tokens]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Objects exist within the database, and are referenced with a unique number or ", <$format, ["i", [], ["Object Number"], 'do_i]>, " (", <$format, ["i", [], ["objnum"], 'do_i]>, "), which is assigned to the object upon its creation in the database. ", <$format, ["i", [], ["Object numbers"], 'do_i]>, " cannot be changed after an object is created. When an object is destroyed, it's ", <$format, ["i", [], ["objnum"], 'do_i]>, " is not re-used by the driver unless the database is decompiled to text and recompiled. ", <$format, ["np", [], [], 'do_np]>, "An object can also have an ", <$format, ["i", [], ["Object Name"], 'do_i]>, " assigned to it, which can be changed througout the life of the object. Object Name's are only unique to that object, while the object has the name. Once the name is changed the old name can be taken by another object. Object Names exist for practical functionality, as it is easier to remember references which consist of alphabetic and numeric characters, compared to references which are simply numeric. ", <$format, ["np", [], [], 'do_np]>, "In ColdC an object number is designated with a hash mark ('#') followed by the object's number. For instance ", <$format, ["tt", [], ["#23"], 'do_tt]>, " refers to ", <$format, ["i", [], ["object number"], 'do_i]>, " ", <$format, ["tt", [], ["23"], 'do_tt]>, ". An object name is designated as an ", <$format, ["link", [["node", "$help_coldc_tokens"]], ["identifier"], 'do_link]>, " beginning with a dollar sign (", <$format, ["tt", [], ["$"], 'do_tt]>, "). For instance, if the object ", <$format, ["tt", [], ["#23"], 'do_tt]>, " has the name ", <$format, ["i", [], ["object_23"], 'do_i]>, " assigned to it, it would be formatted in ColdC as: ", <$format, ["tt", [], ["$object_23"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "A negative object number will appear if there is no object in the database with the given object number--i.e. if it is an invalid object number. This is true for all cases, except ", <$format, ["tt", [], ["#-1"], 'do_tt]>, ", which is the generic ", <$format, ["i", [], ["Invalid Object Number"], 'do_i]>, ". ", <$format, ["np", [], [], 'do_np]>, "Both the object number and object name are generically called ", <$format, ["i", [], ["database references"], 'do_i]>, " (", <$format, ["i", [], ["dbrefs"], 'do_i]>, "). When the driver formats a database reference the Object Name will take precedence over an Object Number, because the name is generally easier to remember and comprehend. ", <$format, ["np", [], [], 'do_np]>, "When the interpreter encounters an object name, it looks up the number associated with that name in a table. If no object has been assigned to that name, a ", <$format, ["tt", [], ["~namenf"], 'do_tt]>, " error is thrown; otherwise the object name is equivalent to the object number when executing."], #[['links, #[["identifier", "$help_coldc_tokens"]]]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_objs_ref];
var $help_node nolist = 0;


new object $help_coldc_objs_methods: $help_coldc_objs;

var $root manager = $help_coldc_objs_methods;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853696071;
var $has_name name = ['prop, "Methods", "Methods"];
var $help_node links = #[["Defining Methods", $help_coldc_methods], ["descendants", $help_coldc_oop]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A method is a series of ColdC statements which are grouped together as a procedure, to perform a task. Method's are given a name and bound to a specific object. Methods determine the object's behavior.", <$format, ["p", [], [], 'do_p]>, "Methods have a specific structure to them. The number of arguments they will accept is defined at the beginning of the method, followed by the definition all of the variables used within the method. Subsequent lines compose the actual method (See ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, " for more information on method structure).", <$format, ["p", [], [], 'do_p]>, "When ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_oop"]], ["descendants"], 'do_link]>], 'do_i]>, " of an object wish to change their behavior, they may define their own methods, or ", <$format, ["i", [], ["override"], 'do_i]>, " a method defined on an ", <$format, ["i", [], ["ancestor"], 'do_i]>, ". A method is overriden by simply naming it the same as an existing method on an ancestor of the object. When a method is called, the interpreter looks for it first on the object, then on the object's ancestors. If this occurs, it is possible for a method overriding another to stop executing and pass back to the method on its ancestor, and then resume executing when the overriden method completes executing.", <$format, ["p", [], [], 'do_p]>, "It is possible for a method to disallow descendants to override a method, see ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, "."], #[['this, $help_coldc_objs_methods]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_objs_methods];
var $help_node nolist = 0;


new object $help_coldc_objs_vars: $help_coldc_objs;

var $root manager = $help_coldc_objs_vars;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853696071;
var $has_name name = ['prop, "Variables", "Variables"];
var $help_node links = #[["encapsulation", $help_coldc_oop]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "In ColdC there are two types of variables, ", <$format, ["i", [], ["local variables"], 'do_i]>, " and ", <$format, ["i", [], ["object variables"], 'do_i]>, ". An object variable is defined on the object, and can be accessed by any method defined on the same object. Object variables exist outside of the scope of methods. Local variables are defined within a method, with their scope being limited to that method. Object variables will always exist until they are explicitly removed. Local variables only exist while the method defining them is executing. ", <$format, ["p", [], [], 'do_p]>, "If a variable is used within the body of a method, but it is not defined as an argument or a local variable (at the top of the method), it is assumed to be an object variable. When the method is executed the interpreter looks on the object for the variable. If the interpreter cannot find the variable on the object, the error ", <$format, ["tt", [], ["~varnf"], 'do_tt]>, " is thrown. ", <$format, ["p", [], [], 'do_p]>, "It is important to remember that object variables may only be accessed by methods ", <$format, ["i", [], ["defined by same object defining the variable"], 'do_i]>, ". No other method may reference that variable. For instance, assume two objects exist as ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, " and ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, ", where ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, " is a child of ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, ". ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, " defines the variable ", <$format, ["tt", [], ["text"], 'do_tt]>, " and the methods ", <$format, ["tt", [], ["set_text"], 'do_tt]>, " and ", <$format, ["tt", [], ["get_text"], 'do_tt]>, ": ", <$format, ["dfn", [], [<$format, ["quote", [], ["\nobject $obj_a: $root;\nvar $obj_a text;\n\npublic method $obj_a.get_text {\n    return text;\n};\n\npublic method $obj_a.set_text {\n    arg new_text;\n\n    text = new_text;\n};"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Calling ", <$format, ["tt", [], ["$obj_a.set_text(\"text\")"], 'do_tt]>, " will set $obj_a's instance of the object variable ", <$format, ["tt", [], ["text"], 'do_tt]>, " to \"text\". ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, " does inherit the ability to use and write to it's own instance of ", <$format, ["tt", [], ["text"], 'do_tt]>, " (using methods defined on ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, "), but it does not inherit values assigned to the same object variable on it's ancestors. For instance, calling ", <$format, ["tt", [], ["$obj_b.get_text()"], 'do_tt]>, " will currently return ", <$format, ["tt", [], ["0"], 'do_tt]>, " (the default unset value), as it's instance of ", <$format, ["tt", [], ["text"], 'do_tt]>, " has not yet been defined, even though ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, "'s instance of ", <$format, ["tt", [], ["text"], 'do_tt]>, " has been defined. This is called ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_oop"]], ["encapsulation"], 'do_link]>], 'do_i]>, ". ", <$format, ["p", [], [], 'do_p]>, "Calling ", <$format, ["tt", [], ["$obj_b.set_text(\"more\")"], 'do_tt]>, " would set ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, "'s instance of ", <$format, ["tt", [], ["text"], 'do_tt]>, " to \"more\". If, following this, ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, " were to override the method ", <$format, ["tt", [], ["get_text"], 'do_tt]>, " defined on ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, " as: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\npublic method $obj_b.get_text {\n    return \"more text: \" + text;\n};"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Calling ", <$format, ["tt", [], ["$obj_b.get_text()"], 'do_tt]>, " would cause the error ", <$format, ["tt", [], ["~varnf"], 'do_tt]>, " to be thrown, rather than having \"more text: more\" returned. This is because the object variable ", <$format, ["tt", [], ["text"], 'do_tt]>, " is not defined by $obj_b (where the new ", <$format, ["tt", [], ["get_text"], 'do_tt]>, " is defined), even though it has it's own instance from $obj_a. ", <$format, ["p", [], [], 'do_p]>, "Another way to look at this is from a ", <$format, ["i", [], ["C++"], 'do_i]>, " perspective. All object variables in ColdC are equivalent to being private object variables in C++."], #[['this, $help_coldc_objs_vars]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_objs_vars];
var $help_node nolist = 0;


new object $help_coldc_objs_special: $help_coldc_objs;

var $root manager = $help_coldc_objs_special;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853696071;
var $has_name name = ['prop, "Special Object Status", "Special Object Status"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "There are always two objects which exists within a ColdC database. The first object is ", <$format, ["tt", [], ["$root"], 'do_tt]>, " (", <$format, ["tt", [], ["#1"], 'do_tt]>, "). The root object has no parents, and is the base for all other objects. This is a requirement in order to allow for a secure database to be created. ", <$format, ["p", [], [], 'do_p]>, "The second object is ", <$format, ["tt", [], ["$sys"], 'do_tt]>, " (", <$format, ["tt", [], ["#0"], 'do_tt]>, "). The system object is the only object the driver directly calls methods on, with without previously setting up with the driver (i.e. connections). These methods include ", <$format, ["tt", [], ["$sys.startup()"], 'do_tt]>, ", ", <$format, ["tt", [], ["$sys.heartbeat()"], 'do_tt]>, " and ", <$format, ["tt", [], ["$sys.signal()"], 'do_tt]>, ". ", <$format, ["p", [], [], 'do_p]>, "The root and system objects are automatically created by the database compiler."], #[['this, $help_coldc_objs_special]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_objs_special];
var $help_node nolist = 0;


new object $help_coldc_lang: $help_coldc;

var $root manager = $help_coldc_lang;
var $help_node holder = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853707985;
var $has_name name = ['prop, "Language Structure", "Language Structure"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[['this, $help_coldc_lang]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_lang];
var $help_node nolist = 0;


new object $help_coldc_tokens: $help_coldc_lang;

var $root manager = $help_coldc_tokens;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698065;
var $has_name name = ['prop, "Tokens", "Tokens"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Tokens are the base elements of ColdC. Tokens are simply abstract groupings of text imbued with a specific meaning. There are many different types of tokens ranging from single characters to long words. The following characters and pairs of characters are tokens in ColdC: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\n{   }   [   ]   #[  ]   `[  ]   (   )   (|  |)  (>  <)\n,   ;   =   +=  -=  *=  /=  !   -   +   *   /   %   ..\n==  !=  >   >=  <   <=  .   ||  &&  ?   |   @   --  ++"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "The above tokens are used as operators and punctuation in ColdC expressions and statements. ", <$format, ["subj", [["level", "3"]], ["Identifier"], 'do_subj]>, " ", <$format, ["p", [], [], 'do_p]>, "An ", <$format, ["i", [], ["identifier"], 'do_i]>, " is another type of ColdC token which is a sequence of alphabetic and numeric characters or underlines not beginning with a number. Identifiers in ColdC are case-sensitive, so the identifiers ", <$format, ["tt", [], ["Car"], 'do_tt]>, " and ", <$format, ["tt", [], ["car"], 'do_tt]>, " are not equivalent. The following are all valid identifiers: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\nwe_3_kings\nobj\na"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Without additional tokens, identifiers usually represent variables. However, certain identifiers have special meanings to the parser. These reserved words are used in writing certain kinds of statements and expressions. They are: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\nvar, if, else, while, for, switch, case, default,\nbreak, continue, return, catch, any, with handler,\npass, to, in"], 'do_quote]>], 'do_dfn]>], #[['this, $help_coldc_tokens]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_tokens];
var $help_node nolist = 0;


new object $help_coldc_types: $help_coldc_lang;

var $root manager = $help_coldc_types;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Data Types", "Data Types"];
var $help_node links = #[["expression", $help_coldc_expr], ["Integer", $help_coldc_types_ints], ["Float", $help_coldc_types_floats], ["String", $help_coldc_types_strings], ["Buffer", $help_coldc_types_buffers], ["Symbol", $help_coldc_types_symbols], ["List", $help_coldc_types_lists], ["Object Number", $help_coldc_types_dbref], ["Object Name", $help_coldc_types_dbref], ["Dictionary", $help_coldc_types_dicts], ["Error Code", $help_coldc_types_errors], ["Frob", $help_coldc_types_frobs], ["type()", $help_func_type]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "All ColdC data has a type and a logical truth value it will return when evaluated as an ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_expr"]], ["expression"], 'do_link]>], 'do_i]>, ". The following is a list of ColdC data types along with their names and literal representation in ColdC: ", <$format, ["dfn", [], [<$format, ["table", [["cols", "25%,25%,40%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["Type"], 'do_b]>], 'do_td]>, <$format, ["td", [], [<$format, ["b", [], ["Name"], 'do_b]>], 'do_td]>, <$format, ["td", [], [<$format, ["b", [], ["Representation"], 'do_b]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_ints"]], ["Integer"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'integer"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["42"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_floats"]], ["Float"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'float"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["1.0"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_strings"]], ["String"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'string"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["\"This String\""], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_buffers"]], ["Buffer"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'buffer"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["`[]"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_symbols"]], ["Symbol"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'symbol"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["'identifier"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_lists"]], ["List"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'list"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["[1, 2, 3, 4]"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_dbref"]], ["Object Number"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'objnum"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["#1234"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_dbref"]], ["Object Name"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'objname"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["$identifier"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_dicts"]], ["Dictionary"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'dictionary"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["#[[\"key\", $value]]"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_errors"]], ["Error Code"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'error"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["~identifier"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_frobs"]], ["Frob"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'frob"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["<object, value>"], 'do_tt]>], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The type of data being manipulated can be determined using the ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_type"]], ["type()"], 'do_link]>], 'do_tt]>, " function."], #[['this, $help_coldc_types]]]>;
var $root inited = 1;
var $help_node nolist = 1;
var $root managed = [$help_coldc_types];


new object $help_coldc_types_ints: $help_coldc_types;

var $root manager = $help_coldc_types_ints;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Integer|Number", "Integer|Number"];
var $help_node links = #[["Numeric Functions", $help_funcs_num]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "An ", <$format, ["i", [], ["integer"], 'do_i]>, " is a rational number (in mathematical terms). Integers can reliably be from 2147483647 to -2147483647 (unless the driver has been compiled with BIG_NUMBERS, in which case they are larger). An integer is logically true if it is not zero (negative numbers are logically true). Integers are denoted in ColdC with a series of digits, optionally preceded with a plus (", <$format, ["tt", [], ["+"], 'do_tt]>, ") or minus (", <$format, ["tt", [], ["-"], 'do_tt]>, ") sign. ", <$format, ["np", [], [], 'do_np]>, "See also: ", <$format, ["link", [["node", "$help_funcs_num"]], ["Numeric Functions"], 'do_link]>], #[['links, #[["Numeric Functions", "$help_funcs_num"]]]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_ints];
var $help_node nolist = 0;


new object $help_coldc_types_floats: $help_coldc_types;

var $root manager = $help_coldc_types_floats;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Float", "Float"];
var $help_node links = #[["Numeric Functions", $help_funcs_num]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A ", <$format, ["i", [], ["float"], 'do_i]>, " is a real number (in mathematical terms). A float is logically true if it is not zero. Floats are denoted in ColdC with two numbers seperated by a period and optionally preceded with a plus (", <$format, ["tt", [], ["+"], 'do_tt]>, ") or minus (", <$format, ["tt", [], ["-"], 'do_tt]>, ") sign. Floats may be printed in scientific notation--both forms are acceptable. The interpreter will print floats in whichever format will give the greatest precision with the least amount of space. ", <$format, ["np", [], [], 'do_np]>, "See also: ", <$format, ["link", [["node", "$help_funcs_num"]], ["Numeric Functions"], 'do_link]>], #[['links, #[["Numeric Functions", "$help_funcs_num"]]]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_floats];
var $help_node nolist = 0;


new object $help_coldc_types_strings: $help_coldc_types;

var $root manager = $help_coldc_types_strings;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "String", "String"];
var $help_node links = #[["String Functions", $help_funcs_str]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A ", <$format, ["i", [], ["string"], 'do_i]>, " is a sequence of printable characters. A string is logically true if it is not empty. A string is denoted in ColdC by enclosing the printable characters within double quote characters (", <$format, ["tt", [], ["\""], 'do_tt]>, "). To include a double quote inside a string precede it with a backslash. Any other occurance of a backslash in a string has no special meaning, unless it follows another backslash (at which point it is assumed to be escaping itself, and reduces as appropriate). The following are some examples of strings: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\n\"foo\"\n\"\\\"foo\\\" is a metasyntactic variable.\"\n\"The backslash (`\') is a much-abused character in many languages.\""], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "See Also: ", <$format, ["link", [["node", "$help_funcs_str"]], ["String Functions"], 'do_link]>], #[['links, #[["String Functions", "$help_funcs_str"]]]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_strings];
var $help_node nolist = 0;


new object $help_coldc_types_symbols: $help_coldc_types;

var $root manager = $help_coldc_types_symbols;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Symbol", "Symbol"];
var $help_node links = #[["ColdC identifier", $help_coldc_tokens]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A ", <$format, ["i", [], ["symbol"], 'do_i]>, " is similar to a string, but it has been abstracted into a ", <$format, ["link", [["node", "$help_coldc_tokens"]], ["ColdC identifier"], 'do_link]>, ". This makes comparisons between symbols much faster than with strings, as when comparing a string each character in the string must be compared, but when comparing a symbol only one comparison occurs. ", <$format, ["p", [], [], 'do_p]>, "Symbols are denoted in ColdC by preceding the identifier with an apostrophe (", <$format, ["tt", [], ["'"], 'do_tt]>, "). Symbols are not terminated with an apostrophe. Symbols are always logically true."], #[['this, $help_coldc_types_symbols]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_symbols];
var $help_node nolist = 0;


new object $help_coldc_types_lists: $help_coldc_types;

var $root manager = $help_coldc_types_lists;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "List", "List"];
var $help_node links = #[["List Functions", $help_funcs_list]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A ", <$format, ["i", [], ["list"], 'do_i]>, " is an ordered grouping of data. The data contained within a list can be of any type, and does not have to be the same type througout the list. Lists are useful for grouping different data elements together. A list is logically true if it contains one or more elements, and is logically false if it is empty. A list is constructed by enclosing a comma-separated series of data elements within square brackets. For example both of the following are both valid lists:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["[1, 2, 3] ", <$format, ["br", [], [], 'do_br]>, "[1, [\"foo\", 'bar], $sys]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "See Also: ", <$format, ["link", [["node", "$help_funcs_list"]], ["List Functions"], 'do_link]>], #[['links, #[["List Functions", "$help_funcs_list"]]]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_lists];
var $help_node nolist = 0;


new object $help_coldc_types_dbref: $help_coldc_types;

var $root manager = $help_coldc_types_dbref;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Object Number|objnum|Object Name|objname|dbref", "Object Number|objnum|Object Name|objname|dbref"];
var $help_node links = #[["Referencing Objects", $help_coldc_objs_ref]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["i", [], ["Object numbers"], 'do_i]>, " and ", <$format, ["i", [], ["object names"], 'do_i]>, " are explained in detail in the section ", <$format, ["link", [["node", "$help_coldc_objs_ref"]], ["Referencing Objects"], 'do_link]>, ". Object numbers and names are always logically true."], #[['this, $help_coldc_types_dbref]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_dbref];
var $help_node nolist = 0;


new object $help_coldc_types_dicts: $help_coldc_types;

var $root manager = $help_coldc_types_dicts;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Dictionary", "Dictionary"];
var $help_node links = #[["Dictionary Functions", $help_funcs_dict]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A ", <$format, ["i", [], ["dictionary"], 'do_i]>, " is a collection of data associations, each of which has a key and a value. Dictionaries are similar to lists, however, lookup in a dictionary is with the key (returning the value), rather than with the location in the list. Dictionaries generally take up more storage space in memory than lists, and are slightly slower to add to and remove from than lists, but searching for items in dictionaries is much faster than searching for items in a list.", <$format, ["np", [], [], 'do_np]>, "Dictionaries are denoted by a list of two-element lists, preceded with a hash mark (", <$format, ["tt", [], ["#"], 'do_tt]>, "). Each of the two-element lists is an association, where the first element is the key and the second element is the value. Dictionaries are logically true unless empty. The following are all valid dictionaries:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["#[[\"foo\", 3], ['bar, 'baz]]", <$format, ["br", [], [], 'do_br]>, "#[[\"something\", 'blue], [\"one\", 1], [\"two\", 2]]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When evaluating the key for the value in the dictionary is indexed, rather than the position as in a list, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["dict=#[[\"foo\", 3], ['bar, 'baz]];", <$format, ["br", [], [], 'do_br]>, "dict['bar];", <$format, ["br", [], [], 'do_br]>, "=> 'baz"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "See Also: ", <$format, ["link", [["node", "$help_funcs_dict"]], ["Dictionary Functions"], 'do_link]>], #[['links, #[["Dictionary Functions", "$help_funcs_dict"]]]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_dicts];
var $help_node nolist = 0;


new object $help_coldc_types_errors: $help_coldc_types;

var $root manager = $help_coldc_types_errors;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Error Codes|errors", "Error Codes|errors"];
var $help_node links = #[["Errors", $help_coldc_errors]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "An ", <$format, ["i", [], ["error code"], 'do_i]>, " identifies an error. Both the ColdC interpreter and ColdC methods use error codes to identify types of errors when they occur. See section ", <$format, ["link", [["node", "$help_coldc_errors"]], ["Errors"], 'do_link]>, " for information about how errors in ColdC are handled. Errors are denoted in ColdC by preceding an identifier with a tilde (", <$format, ["tt", [], ["~"], 'do_tt]>, "). Error codes are always logically false."], #[['this, $help_coldc_types_errors]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_errors];
var $help_node nolist = 0;


new object $help_coldc_types_frobs: $help_coldc_types;

var $root manager = $help_coldc_types_frobs;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Frob", "Frob"];
var $help_node links = #[["method-call", $help_coldc_mcall], ["Defining Methods", $help_coldc_methods], ["frob_class()", $help_func_class], ["frob_value()", $help_func_frob_value], ["frob_handler()", $help_func_frob_handler]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["i", [], ["Frobs"], 'do_i]>, " are an abstract data type used for dynamically handling data when using it as the receiver of a ", <$format, ["link", [["node", "$help_coldc_mcall"]], ["method-call"], 'do_link]>, " expression. Normally, when data is used as the receiver for a method call, the interpreter will actually lookup and use an object with an object name that is the same as the type of data being used (such as an object named ", <$format, ["tt", [], ["$string"], 'do_tt]>, " if the data is a ", <$format, ["tt", [], ["'string"], 'do_tt]>, "). In the case of a frob, the receiver is specified within the frob, as the ", <$format, ["i", [], ["Frob Class"], 'do_i]>, ". Frobs also give the ability to specify special method to handle the call with. ", <$format, ["np", [], [], 'do_np]>, " Frobs are useful for grouping, abstracting and encapsulating a set of similar data by associating it with a handler object. Frobs are constructed by enclosing the class and representation within a less-than sign (", <$format, ["tt", [], ["<"], 'do_tt]>, ") and a greater-than sign (", <$format, ["tt", [], [">"], 'do_tt]>, "), seperated by a comma. All of the following are valid frobs: ", <$format, ["dfn", [], ["<$thing_frob, #[['desc, \"worthless\"], ['name, \"coin\"]]>", <$format, ["br", [], [], 'do_br]>, "<$coins, [923]>", <$format, ["br", [], [], 'do_br]>, "<#73, [1, 2]>"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The usefullness of a frob becomes apparent when used as the recipient in a ", <$format, ["link", [["node", "$help_coldc_mcall"]], ["method-call"], 'do_link]>, " expression. In this instance the ", <$format, ["i", [], ["frob class"], 'do_i]>, " becomes the recipient and the ", <$format, ["i", [], ["frob value"], 'do_i]>, " becomes the first argument sent to the method. For instance, the following two method calls are equivalent:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["(<$list, [1, 2, 3]>).reverse('do_this)", <$format, ["br", [], [], 'do_br]>, "$list.reverse([1, 2, 3], 'do_this)"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Furthermore, if a handler is used, the handler is called as the method, and the expected method is sent as a symbol argument. The following two method calls are equivalent:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["(<$obj, #[], 'handle_it>).tell(\"foof\")", <$format, ["br", [], [], 'do_br]>, "$obj.handle_it(#[], 'tell, \"foof\")"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Because of the difference in how a frob method is called, it is possible to define a method as a frob-only method. If a method is defined as a frob-only method it is ", <$format, ["i", [], ["only"], 'do_i]>, " called when called by a frob. Calling it in the standard syntax would not retrieve the frob-only method, but would instead look for the same method further up the ancestor heirarchy. For more information see ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "Frobs are always logically true. ", <$format, ["np", [], [], 'do_np]>, "See Also: ", <$format, ["link", [["node", "$help_func_class"]], ["frob_class()"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_func_frob_value"]], ["frob_value()"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_func_frob_handler"]], ["frob_handler()"], 'do_link]>], #[['links, #[["method-call", "$help_coldc_mcall"], ["Defining Methods", "$help_coldc_methods"], ["frob_class()", "$help_func_class"], ["frob_value()", "$help_func_frob_value"], ["frob_handler()", "$help_func_frob_handler"]]]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_frobs];
var $help_node nolist = 0;


new object $help_coldc_types_buffers: $help_coldc_types;

var $root manager = $help_coldc_types_buffers;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Buffer", "Buffer"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A ", <$format, ["i", [], ["buffer"], 'do_i]>, " is an array of integers which are interpreted to unsigned eight-bit values. Keep this in mind, as the range of an integer in a buffer is only 0 through 255, any other number will be cast to an eight bit unsigned value. ", <$format, ["np", [], [], 'do_np]>, "Buffers are intended for handling character values outside of the normal printable range used by ColdC strings. A buffer is constructed by prefixing a list of integers with an accent mark (", <$format, ["tt", [], ["`"], 'do_tt]>, "), where each integer is the decimal value of the respective character. Buffers are logically true if not empty. The following buffer and string are equivalent:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["`[98, 117, 102, 102, 101, 114]", <$format, ["br", [], [], 'do_br]>, "\"buffer\""], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_buffers];
var $help_node nolist = 0;


new object $help_coldc_expr: $help_coldc_lang;

var $root manager = $help_coldc_expr;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853826333;
var $has_name name = ['prop, "Expressions", "Expressions"];
var $help_node links = #[["tokens", $help_coldc_tokens], ["operators", $help_coldc_ops], ["Data", $help_coldc_data], ["Variable", $help_coldc_vars], ["Function Call", $help_coldc_fcall], ["Method Call", $help_coldc_mcall], ["Error Handling", $help_coldc_err_expr], ["Looping", $help_coldc_loop_expr]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Expressions are ColdC ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_tokens"]], ["tokens"], 'do_link]>], 'do_i]>, " and ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_expr_ops"]], ["operators"], 'do_link]>], 'do_i]>, " which--when evaluated--perform their defined behavior and take on a value after completion (also known as the ", <$format, ["i", [], ["return value"], 'do_i]>, "). If they evaluated without error, the return value is a standard ColdC data type. If an error occured, the return value is an error data type, and execution of the method is halted. ", <$format, ["np", [], [], 'do_np]>, "There are many different types of expressions:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_data"]], ["Data"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_ops"]], ["Operators"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_vars"]], ["Variable"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_fcall"]], ["Function Call"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_mcall"]], ["Method Call"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_err_expr"]], ["Error Handling"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_loop_expr"]], ["Looping"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_expr]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_expr];
var $help_node nolist = 0;


new object $help_coldc_data: $help_coldc_expr;

var $root manager = $help_coldc_data;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853827083;
var $has_name name = ['prop, "Data", "Data"];
var $help_node links = #[["expression", $help_coldc_expr], ["Data Types", $help_coldc_types]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "All ColdC data has a type and a logical truth value it will take on when evaluated as an ", <$format, ["link", [["node", "$help_coldc_expr"]], ["expression"], 'do_link]>, ". Each data type is explained in the section ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_types"]], ["Data Types"], 'do_link]>], 'do_i]>, "."], #[['this, $help_coldc_data]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_data];
var $help_node nolist = 0;


new object $help_coldc_ops: $help_coldc_expr;

var $root manager = $help_coldc_ops;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853827084;
var $has_name name = ['prop, "Operators", "Operators"];
var $help_node links = #[["Operator Precedence", $help_coldc_prec], ["Index Operators", $help_coldc_index], ["Arithmetic Operators", $help_coldc_arith], ["Assignment Operators", $help_coldc_assign], ["Logical Operators", $help_coldc_logical], ["Conditional Operators", $help_coldc_cond], ["List Splice Operator", $help_coldc_splice]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Operators are tokens used to perform simple operations on expression values, such as adding two values together. ", <$format, ["tt", [], ["ColdC"], 'do_tt]>, " provides a variety of operators to perform arithmetic and logical operations on data. Most of these operators fall into two categories: ", <$format, ["i", [], ["unary operators"], 'do_i]>, " and ", <$format, ["i", [], ["binary operators"], 'do_i]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["i", [], ["Unary operators"], 'do_i]>, " act on a single expression value. In ", <$format, ["tt", [], ["ColdC"], 'do_tt]>, ", all unary operators are single characters which precede expressions. For example, ", <$format, ["tt", [], ["!str"], 'do_tt]>, " is the logical negation of the variable ", <$format, ["tt", [], ["str"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["i", [], ["Binary operators"], 'do_i]>, " act on two expression values. For example, ", <$format, ["tt", [], ["a + b"], 'do_tt]>, " is the sum of the variables ", <$format, ["tt", [], ["a"], 'do_tt]>, " and ", <$format, ["tt", [], ["b"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "Some operators are neither unary nor binary. More information on these operators can be found in each sub section:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_prec"]], ["Operator Precedence"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_index"]], ["Index Operators"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_arith"]], ["Arithmetic Operators"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_assign"]], ["Assignment Operators"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_logical"]], ["Logical Operators"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_cond"]], ["Conditional Operators"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_splice"]], ["List Splice Operator"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_ops]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_ops];
var $help_node nolist = 0;


new object $help_coldc_prec: $help_coldc_ops;

var $root manager = $help_coldc_prec;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853827084;
var $has_name name = ['prop, "Operator Precedence", "Operator Precedence"];
var $help_node links = #[["Logical Operators", $help_coldc_logical]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "When the interpreter executes an expression it evaluates each operator it in a certain order. It is easy to write an expression which has an unclear order of evaluation. For instance, the expression ", <$format, ["tt", [], ["A - B + C"], 'do_tt]>, " could be parsed as ", <$format, ["tt", [], ["A - B"], 'do_tt]>, " followed by the result plus ", <$format, ["tt", [], ["C"], 'do_tt]>, " or as ", <$format, ["tt", [], ["A"], 'do_tt]>, " minus ", <$format, ["tt", [], ["B + C"], 'do_tt]>, ". To resolve these ambiguities, each operator has two properties when interpreted: ", <$format, ["i", [], ["precedence"], 'do_i]>, " and ", <$format, ["i", [], ["association"], 'do_i]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["i", [], ["Precedence"], 'do_i]>, " determines whether an operator is more important than another operator; for instance, ", <$format, ["tt", [], ["A + B * C"], 'do_tt]>, " is equivalent to ", <$format, ["tt", [], ["A + (B * C)"], 'do_tt]>, " because multiplication has higher precedence (is more important) than addition. ", <$format, ["np", [], [], 'do_np]>, <$format, ["i", [], ["Association"], 'do_i]>, " determines whether operators at the same precedence level associate left to right or right to left; ", <$format, ["tt", [], ["A - B - C"], 'do_tt]>, " is equivalent to ", <$format, ["tt", [], ["(A - B) - C"], 'do_tt]>, " because subtraction associates left to right. ", <$format, ["np", [], [], 'do_np]>, "Here is a list of operators grouped by precedence, in order from highest to lowest: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\n[]\n.\n-- ++\n! - (unary)\n* / %\n+ - (binary)\n== != > >= < <=\nin\n&&\n||\n?:\n= += -= /= *= ?="], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "All operators associate from left to right except the ", <$format, ["link", [["node", "$help_coldc_logical"]], ["Logical Operators"], 'do_link]>, " (", <$format, ["tt", [], ["&&"], 'do_tt]>, ", ", <$format, ["tt", [], ["||"], 'do_tt]>, ", and ", <$format, ["tt", [], ["?|"], 'do_tt]>, "), which associate from right to left. Parentheses may be used to group expressions and clarify evaluation."], #[['this, $help_coldc_prec]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_prec];
var $help_node nolist = 0;


new object $help_coldc_index: $help_coldc_ops;

var $root manager = $help_coldc_index;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854138336;
var $has_name name = ['prop, "Index Operators", "Index Operators"];
var $help_node links = #[["find", $help_coldc_find]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Indexing involves lookup in either a string, list, buffer and in some instances a dictionary. Depending upon the specific operator used indexing can return either the position of a desired element, or it can return the element at the specified position. There are two indexing operators, each performing one of these roles:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["[]", <$format, ["br", [], [], 'do_br]>, "in"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The binary operator index-lookup (", <$format, ["tt", [], ["in"], 'do_tt]>, ") is used to find the position of an element. It may only be used with strings, lists and buffers. When used this operator will return an integer representing the position within the right side data where the left side specified element exists. If the specified element does not exist, a zero (", <$format, ["tt", [], ["0"], 'do_tt]>, ") is returned. Indexing is case-insensitive, when using strings. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["\"C\" in \"abcdefg\"", <$format, ["br", [], [], 'do_br]>, "=> 3"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The expression ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_coldc_find"]], ["find"], 'do_link]>], 'do_tt]>, " and the functions ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_stridx"]], ["stridx()"], 'do_link]>], 'do_tt]>, ", ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_listidx"]], ["listidx()"], 'do_link]>], 'do_tt]>, " and ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_bufidx"]], ["bufidx()"], 'do_link]>], 'do_tt]>, " may also be used in finding the positional index of an element. ", <$format, ["np", [], [], 'do_np]>, "The index-retrieve operator ([]) is used to retrieve an element found within the data. It may be used with strings, lists, buffers and dictionaries. It is a binary operator, although its syntax is not as standard as others:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["i", [], ["data expression"], 'do_i]>, "[", <$format, ["i", [], ["data expression"], 'do_i]>, "]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The right data expression is used as the key to lookup within the left data expression. In all but the dictionary the right data expression must result in an integer, which represents the position in the right data expression to retrieve from. With a dictionary the right data expression may be any data type (see ", <$format, ["link", [["node", "$help_coldc_types_dicts"]], ["Dictionaries"], 'do_link]>, ")."], #[['this, $help_coldc_index]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_index];
var $help_node nolist = 0;


new object $help_coldc_arith: $help_coldc_ops;

var $root manager = $help_coldc_arith;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853827084;
var $has_name name = ['prop, "Arithmetic Operators", "Arithmetic Operators"];
var $help_node links = #[["Increment / Decrement Operators", $help_coldc_incdec], ["Non-Numeric Use", $help_coldc_non_arith]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdC provides several operators for performing arithmetic operations. These operators apply primarily to integers and floats, but some of them may be used with non-integer data for easier formatting and manipulation. If any arithmetic operator is used with inappropriate data the error ", <$format, ["tt", [], ["~type"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "If both sides of a binary arithmetic expression are integers, the result will always be an integer, even if the result would have floating precision. If one side of the expression is a float, the result will always be a float. For instance, ", <$format, ["tt", [], ["3 / 2"], 'do_tt]>, " (both integers) would result in ", <$format, ["tt", [], ["1"], 'do_tt]>, ", whereas ", <$format, ["tt", [], ["3 / 2.0"], 'do_tt]>, " would result in ", <$format, ["tt", [], ["1.500000"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "The arithmetic operators are: ", <$format, ["dfn", [], [<$format, ["table", [["cols", "10%,20%,15%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["ignored"], 'do_td]>, <$format, ["td", [], ["(unary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["-"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["negate"], 'do_td]>, <$format, ["td", [], ["(unary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["addition"], 'do_td]>, <$format, ["td", [], ["(binary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["-"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["subtraction"], 'do_td]>, <$format, ["td", [], ["(binary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["*"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["multiply"], 'do_td]>, <$format, ["td", [], ["(binary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["/"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["divide"], 'do_td]>, <$format, ["td", [], ["(binary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["%"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["modulo"], 'do_td]>, <$format, ["td", [], ["(binary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["++"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["increment"], 'do_td]>, <$format, ["td", [], ["(unary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["--"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["decrement"], 'do_td]>, <$format, ["td", [], ["(unary)"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The unary ", <$format, ["tt", [], ["-"], 'do_tt]>, " operator negates the numeric value (reverses its positive/negative value). The unary ", <$format, ["tt", [], ["+"], 'do_tt]>, " operator has no effect on its argument, and is provided simply for completeness. The binary operators ", <$format, ["tt", [], ["+"], 'do_tt]>, " and ", <$format, ["tt", [], ["-"], 'do_tt]>, " add and subtract their arguments. ", <$format, ["np", [], [], 'do_np]>, "The binary multiplication operator ", <$format, ["tt", [], ["*"], 'do_tt]>, " multiplies the left argument by the right argument. The binary division operator ", <$format, ["tt", [], ["/"], 'do_tt]>, " divides the left argument by the right argument, returning the whole result. The binary modulus operator ", <$format, ["tt", [], ["%"], 'do_tt]>, " divides the left argument by the right argument and returns the remainder result. ", <$format, ["np", [], [], 'do_np]>, "The unary Increment and Decrement operators serve a dual function, and are explained further in their own section.", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_incdec"]], ["Increment / Decrement Operators"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_non_arith"]], ["Non-Numeric Use"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_arith]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_arith];
var $help_node nolist = 0;


new object $help_coldc_incdec: $help_coldc_arith;

var $root manager = $help_coldc_incdec;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854136779;
var $has_name name = ['prop, "Increment|Decrement", "Increment|Decrement"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The unary Increment (", <$format, ["tt", [], ["++"], 'do_tt]>, ") and Decrement (", <$format, ["tt", [], ["--"], 'do_tt]>, ") operators perform a dual purpose. They either add or subtract one from a numeric variable (respectively), assigning the result back to the variable. They must be used directly on a variable. All of the following are equivalent:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["i = i + 1", <$format, ["br", [], [], 'do_br]>, "i++", <$format, ["br", [], [], 'do_br]>, "i = i - 1", <$format, ["br", [], [], 'do_br]>, "i--"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The result returned from an increment or decrement expression will will depend upon what side of the variable it is placed. If the operator is on the left side of the variable, the value of the variable is modified before it is returned. If the operator is on the right side of the variable, the value of the variable is returned first and then the variable is incremented or decremented. ", <$format, ["np", [], [], 'do_np]>, "In the examples below assume ", <$format, ["tt", [], ["i"], 'do_tt]>, " is 10. Assuming this, in the first example ", <$format, ["tt", [], ["x"], 'do_tt]>, " is assigned the value ", <$format, ["tt", [], ["10"], 'do_tt]>, " where in the second example it is assigned the value ", <$format, ["tt", [], ["11"], 'do_tt]>, ".", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["x = i++", <$format, ["br", [], [], 'do_br]>, "x=++i"], 'do_tt]>], 'do_dfn]>], #[['this, $help_coldc_incdec]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_incdec];
var $help_node nolist = 0;


new object $help_coldc_non_arith: $help_coldc_arith;

var $root manager = $help_coldc_non_arith;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854136779;
var $has_name name = ['prop, "Non-Numeric Use", "Non-Numeric Use"];
var $help_node links = #[["Dual Role Assignment", $help_coldc_dual_assign]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The binary ", <$format, ["tt", [], ["+"], 'do_tt]>, " operator can also be applied to strings, lists and buffers. Using it in this way will cause it to concatenate the two values. For instance, the expression ", <$format, ["tt", [], ["(\"foo\" + \"bar\")"], 'do_tt]>, " would evaluate to ", <$format, ["tt", [], ["\"foobar\""], 'do_tt]>, ", and the expression ", <$format, ["tt", [], ["([\"foo\", \"bar\"] + [\"baz\"])"], 'do_tt]>, " would result in the list ", <$format, ["tt", [], ["[\"foo\", \"bar\", \"baz\"]"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "As long as both sides of the operator are the same data type (which is restricted to strings, lists and buffers) no error will be raised. If one side of the operator is a string (either side), and the other side is not a string, it will be converted to its literal representation and joined with the string. For example, the expression ", <$format, ["tt", [], ["(\"list: \" + [1, 2, 3])"], 'do_tt]>, " would evaluate to ", <$format, ["tt", [], ["\"list: [1, 2, 3]\""], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "The binary ", <$format, ["tt", [], ["*"], 'do_tt]>, " may be applied with a string on the left side and an integer on the right side. In this situation the left side string is duplicated by the number of times specified by the right side integer. Example: ", <$format, ["tt", [], ["(\"-\" * 5)"], 'do_tt]>, " would result in ", <$format, ["tt", [], ["\"-----\""], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["link", [["node", "$help_coldc_dual_assign"]], ["Dual Role Assignment"], 'do_link]>, " operators also behave in the same way, as is applicable. For instance, the dual role arithmetic operator ", <$format, ["tt", [], ["+="], 'do_tt]>, " would behave the same as the standard arithmetic operator ", <$format, ["tt", [], ["+"], 'do_tt]>, " when evaluating the addition expression."], #[['this, $help_coldc_non_arith]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_non_arith];
var $help_node nolist = 0;


new object $help_coldc_assign: $help_coldc_ops;

var $root manager = $help_coldc_assign;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853827084;
var $has_name name = ['prop, "Assignments", "Assignments"];
var $help_node links = #[["variable", $help_coldc_vars], ["Simple Assignments", $help_coldc_simple_assign], ["Scatter Assignments", $help_coldc_scatter_assign], ["Dual Role Assignments", $help_coldc_dual_assign], ["Default Assignments", $help_coldc_default_assign]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Data is stored in a ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_vars"]], ["variable"], 'do_link]>], 'do_i]>, " through an assignment. Assignments can either be ", <$format, ["i", [], ["Simple"], 'do_i]>, ", ", <$format, ["i", [], ["Scattered"], 'do_i]>, ", ", <$format, ["i", [], ["Dual Role"], 'do_i]>, " or ", <$format, ["i", [], ["Default"], 'do_i]>, ". Simple Assignments store the result of an expression to a single variable. A Scatter Assignment stores each element in the result of a list expression across multiple variables. Dual Role Assignments join another operator and the simple assignment operator into one for the purpose of simplicity and optimizing, such as ", <$format, ["tt", [], ["+="], 'do_tt]>, " which is both the the addition operator and the assignment operator. Default assignments only assign the value if the current value of the variable is false. More information can be found in each section:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_simple_assign"]], ["Simple Assignments"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_scatter_assign"]], ["Scatter Assignments"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_dual_assign"]], ["Dual Role Assignments"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_default_assign"]], ["Default Assignments"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_assign]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_assign];
var $help_node nolist = 0;


new object $help_coldc_simple_assign: $help_coldc_assign;

var $root manager = $help_coldc_simple_assign;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854128989;
var $has_name name = ['prop, "Simple", "Simple"];
var $help_node links = #[["set_var()", $help_func_set_var], ["Variables", $help_coldc_vars]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Both simple and scatter assignments use the the same equals sign ", <$format, ["tt", [], ["="], 'do_tt]>, " operator. A simple assignment stores the result of the expression on the right into the variable on the left, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["variable"], 'do_i]>, " = ", <$format, ["i", [], ["expression"], 'do_i]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_set_var"]], ["set_var()"], 'do_link]>], 'do_tt]>, " may also be used for the same purpose, but only on an object variable (see ", <$format, ["link", [["node", "$help_coldc_vars"]], ["Variables"], 'do_link]>, ")."], #[['this, $help_coldc_simple_assign]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_simple_assign];
var $help_node nolist = 0;


new object $help_coldc_scatter_assign: $help_coldc_assign;

var $root manager = $help_coldc_scatter_assign;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854129007;
var $has_name name = ['prop, "Scatter", "Scatter"];
var $help_node links = #[["List Splice", $help_coldc_splice]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "In a scatter assignment multiple variables are specified within a square brackets on the left, and each element from the list expression on the right is assigned to the respective variable on the left, with any remaining elements in the list being discarded. For example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["[var1, var2, var3] = [\"this\", [\"for\"], 1, 'that]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In this example ", <$format, ["tt", [], ["var1"], 'do_tt]>, " is assigned the string ", <$format, ["tt", [], ["\"this\""], 'do_tt]>, ", ", <$format, ["tt", [], ["var2"], 'do_tt]>, " is assigned the list ", <$format, ["tt", [], ["[\"for\"]"], 'do_tt]>, ", ", <$format, ["tt", [], ["var3"], 'do_tt]>, " is assigned the integer ", <$format, ["tt", [], ["1"], 'do_tt]>, " and the remaining symbol ", <$format, ["tt", [], ["'that"], 'do_tt]>, " is discarded. ", <$format, ["np", [], [], 'do_np]>, "The remaining elements may all be grouped in a new list which is stored in the last variable by using the ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_splice"]], ["List Splice"], 'do_link]>], 'do_i]>, " operator on the last variable in the scatter list, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["[var1, var2, @var3] = [\"this\", [\"for\"], 1, 'that]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In this example ", <$format, ["tt", [], ["var3"], 'do_tt]>, " would have the value ", <$format, ["tt", [], ["[1, 'that]"], 'do_tt]>, ". The List Splice operator may only be used this way on the last variable in the scatter list. ", <$format, ["np", [], [], 'do_np]>, "Scatter Assignments may also be nested, assuming the list expression is a nested list in the same order as the scatter list. For example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["[var1, [var2, @var3], var4] = [\"this\", [\"for\", 1, 2, 3], 'that]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In this example ", <$format, ["tt", [], ["var1"], 'do_tt]>, " is assigned ", <$format, ["tt", [], ["\"this\""], 'do_tt]>, ", ", <$format, ["tt", [], ["var2"], 'do_tt]>, " is assigned ", <$format, ["tt", [], ["\"for\""], 'do_tt]>, ", ", <$format, ["tt", [], ["var3"], 'do_tt]>, " is assigned the new list ", <$format, ["tt", [], ["[1, 2, 3]"], 'do_tt]>, " and ", <$format, ["tt", [], ["var4"], 'do_tt]>, " is assigned the remaining symbol ", <$format, ["tt", [], ["'that"], 'do_tt]>, "."], #[['this, $help_coldc_scatter_assign]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_scatter_assign];
var $help_node nolist = 0;


new object $help_coldc_dual_assign: $help_coldc_assign;

var $root manager = $help_coldc_dual_assign;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854129007;
var $has_name name = ['prop, "Dual", "Dual"];
var $help_node links = #[["Arithmetic Operator", $help_coldc_arith], ["Non-Arithmetic Behaviour", $help_coldc_non_arith]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Dual Role Assignment operators join an arithmetic operator and the simple assignment operator into one for the purpose of simplicity and optimization. The Dual Role Assignment operators are:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["+=", <$format, ["br", [], [], 'do_br]>, "-=", <$format, ["br", [], [], 'do_br]>, "*=", <$format, ["br", [], [], 'do_br]>, "/="], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "These operators must have a variable as the left argument. When used, the arithmetic expression is evaluated as normal, and the result is assigned back into the variable on the left. The following examples are equivalent:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["x = x + 5", <$format, ["br", [], [], 'do_br]>, "x += 5"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When evaluating the arithmetic expression the operator behaves the same as the equivalent ", <$format, ["link", [["node", "$help_coldc_arith"]], ["Arithmetic Operator"], 'do_link]>, ", including any ", <$format, ["link", [["node", "$help_coldc_non_arith"]], ["Non-Arithmetic Behaviour"], 'do_link]>, "."], #[['this, $help_coldc_dual_assign]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_dual_assign];
var $help_node nolist = 0;


new object $help_coldc_default_assign: $help_coldc_assign;

var $root manager = $help_coldc_default_assign;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 857847069;
var $root managed = [$help_coldc_default_assign];
var $has_name name = ['prop, "Default", "Default"];
var $help_node links = #[["Simple Assignment", $help_coldc_simple_assign], ["if-else Conditional Expression", $help_coldc_cond]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The default assignment is used to assign a value to a variable if the current value of the variable is logically false. The default assignment operator is:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["?="], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "And the syntax is:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["i", [], ["variable"], 'do_i]>, " ?= ", <$format, ["i", [], ["value expression"], 'do_i]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When executed the driver tests the logical value of ", <$format, ["i", [], ["variable"], 'do_i]>, ". If it is false, it assigns the result of ", <$format, ["i", [], ["value expression"], 'do_i]>, ", otherwise it is untouched. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["len ?= 79;"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Will assign ", <$format, ["i", [], ["79"], 'do_i]>, " to ", <$format, ["i", [], ["len"], 'do_i]>, " if it is false (for instance, if it is zero). This operator is equivalent to a combination of the ", <$format, ["link", [["node", "$help_coldc_simple_assign"]], ["Simple Assignment"], 'do_link]>, " and the ", <$format, ["link", [["node", "$help_coldc_cond"]], ["if-else Conditional Expression"], 'do_link]>, ":", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["len = len ? len : 79;"], 'do_dfn]>], #[['this, $help_coldc_default_assign]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_coldc_logical: $help_coldc_ops;

var $root manager = $help_coldc_logical;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853827084;
var $has_name name = ['prop, "Logical Operators", "Logical Operators"];
var $help_node links = #[["strcmp()", $help_func_strcmp]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["tt", [], ["ColdC"], 'do_tt]>, " provides a number of relational and logical operators. These operators are primarily useful for expressing conditions, since they return either true or false, represented by the integers ", <$format, ["tt", [], ["1"], 'do_tt]>, " and ", <$format, ["tt", [], ["0"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "The binary operators ", <$format, ["tt", [], ["=="], 'do_tt]>, " and ", <$format, ["tt", [], ["!="], 'do_tt]>, " test the left and right arguments for equality and inequality, respectively. The arguments are equal if each side has the same data type and contains the same value. Equality of strings is not case-sensitive, but equality of symbols is, so ", <$format, ["tt", [], ["(\"foo\" == \"fOo\")"], 'do_tt]>, " is true, but ", <$format, ["tt", [], ["('car == 'CAr)"], 'do_tt]>, " is false. Lists are equal if all of the elements in each list are equal and are in the same order. ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["tt", [], ["<"], 'do_tt]>, ", ", <$format, ["tt", [], ["<="], 'do_tt]>, ", ", <$format, ["tt", [], [">="], 'do_tt]>, ", and ", <$format, ["tt", [], [">"], 'do_tt]>, " operators test whether their left-hand arguments are less than, less than or equal to, greater than or equal to, or greater than their right-hand arguments, respectively. Arguments to these operators must both be of the same type, and must be either numeric or a string. String comparison is not case-sensitive, so ", <$format, ["tt", [], ["(\"fooa\" < \"fooB\")"], 'do_tt]>, " is true, even though the ASCII value of ", <$format, ["tt", [], ["`a'"], 'do_tt]>, " is greater than that of ", <$format, ["tt", [], ["`B'"], 'do_tt]>, " (the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_strcmp"]], ["strcmp()"], 'do_link]>], 'do_tt]>, " may be used for a true lexical case-sensitive comparison of strings). ", <$format, ["np", [], [], 'do_np]>, "The unary ", <$format, ["tt", [], ["!"], 'do_tt]>, " operator tests whether its argument is false, thus acting as a logical ", <$format, ["i", [], ["NOT"], 'do_i]>, " operation."], #[['this, $help_coldc_logical]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_logical];
var $help_node nolist = 0;


new object $help_coldc_cond: $help_coldc_ops;

var $root manager = $help_coldc_cond;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853827084;
var $has_name name = ['prop, "Conditional", "Conditional"];
var $help_node links = #[["critical expression", $help_coldc_err_expr], ["Conditional if-else Statement", $help_coldc_cond_ifelse]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["tt", [], ["||"], 'do_tt]>, " and ", <$format, ["tt", [], ["&&"], 'do_tt]>, " operators act as logical ", <$format, ["i", [], ["OR"], 'do_i]>, " and ", <$format, ["i", [], ["AND"], 'do_i]>, " operators, respectively. The expression ", <$format, ["tt", [], ["(this || that)"], 'do_tt]>, " is equivalent to ", <$format, ["i", [], ["this OR that"], 'do_i]>, ", where the return value of the expression is ", <$format, ["i", [], ["this"], 'do_i]>, " if ", <$format, ["i", [], ["this"], 'do_i]>, " is logically true. If ", <$format, ["i", [], ["this"], 'do_i]>, " is not logically true then the return value of the expression is ", <$format, ["i", [], ["that"], 'do_i]>, ". ", <$format, ["np", [], [], 'do_np]>, "The expression ", <$format, ["tt", [], ["(this && that)"], 'do_tt]>, " is equivalent to ", <$format, ["i", [], ["this AND that"], 'do_i]>, ", where the return value of the expression is logically true when both ", <$format, ["i", [], ["this"], 'do_i]>, " and ", <$format, ["i", [], ["that"], 'do_i]>, " are also logically true. If either ", <$format, ["i", [], ["this"], 'do_i]>, " or ", <$format, ["i", [], ["that"], 'do_i]>, " are not logically true then the return value is false. ", <$format, ["np", [], [], 'do_np]>, <$format, ["tt", [], ["ColdC"], 'do_tt]>, "'s conditional operators are ", <$format, ["i", [], ["short-circuit operators"], 'do_i]>, ", meaning that the right-hand argument is never evaluated if the left-hand argument is sufficient to determine the value of the expression. This is important if the right-hand argument has side-effects or could cause an error. For instance, because of this it is possible to have the following expression:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["(| dict[key] |) || throw(~nope, \"Nope, doesn't exist\");"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "With this expression if ", <$format, ["i", [], ["key"], 'do_i]>, " is in the dictionary ", <$format, ["i", [], ["dict"], 'do_i]>, " then the return value is the related value to ", <$format, ["i", [], ["key"], 'do_i]>, ". If it is not, the error ", <$format, ["tt", [], ["~keynf"], 'do_tt]>, " is thrown by the index operator (", <$format, ["tt", [], ["[]"], 'do_tt]>, "). However, the expression is a ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_err_expr"]], ["critical expression"], 'do_link]>], 'do_i]>, ". Because of this the left value becomes ", <$format, ["i", [], ["~keynf"], 'do_i]>, ", which is logically false, and the interpreter moves onto the throw function. ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["tt", [], ["? :"], 'do_tt]>, " operator is a trinary operator, with the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["condition"], 'do_i]>, " ? ", <$format, ["i", [], ["true-expr"], 'do_i]>, " : ", <$format, ["i", [], ["false-expr"], 'do_i]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The result of this expression is the result of ", <$format, ["i", [], ["true-expr"], 'do_i]>, " if ", <$format, ["i", [], ["condition"], 'do_i]>, " is true, or the result of ", <$format, ["i", [], ["false-expr"], 'do_i]>, " if ", <$format, ["i", [], ["condition"], 'do_i]>, " is false. This is similar to the ", <$format, ["link", [["node", "$help_coldc_cond_ifelse"]], ["Conditional if-else Statement"], 'do_link]>, "."], #[['this, $help_coldc_cond]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_cond];
var $help_node nolist = 0;


new object $help_coldc_splice: $help_coldc_ops;

var $root manager = $help_coldc_splice;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058343;
var $has_name name = ['prop, "List Splice Operator", "List Splice Operator"];
var $help_node links = #[["listgraft()", $help_func_listgraft], ["Precedence", $help_coldc_prec]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Splicing is used to either expand a list or in scatter assignments and method calls to group remaining arguments into a list. The splice operator is an at sign (", <$format, ["tt", [], ["@"], 'do_tt]>, "). ", <$format, ["np", [], [], 'do_np]>, "Splice can be used to expand a list in three situations: within a method call, within a function call or within another list When expanding, elements within the list to be spliced are placed starting at the appropriate position within the spliced list. For example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["[1, @['a, 'b, 'c], 2, 3]", <$format, ["br", [], [], 'do_br]>, "[1, 'a, 'b, 'c, 2, 3]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Note: the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_listgraft"]], ["listgraft()"], 'do_link]>], 'do_tt]>, " behaves in the same manner. When using splice to expand a list as arguments to a function it looks similar:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["others = [1, \"this\"];", <$format, ["br", [], [], 'do_br]>, "$string.do_something(this, that, @others);"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When the method ", <$format, ["tt", [], ["do_something"], 'do_tt]>, " is called it would be called with four arguments, and the last two arguments would have a value of ", <$format, ["tt", [], ["1"], 'do_tt]>, " and ", <$format, ["tt", [], ["\"this\""], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "The splicing operator is always evaluated last, and is not listed in the operator precedence list (see section ", <$format, ["link", [["node", "$help_coldc_prec"]], ["Precedence"], 'do_link]>, "). Because of its restricted nature the splicing operator never causes ambiguity."], #[['this, $help_coldc_splice]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_splice];
var $help_node nolist = 0;


new object $help_coldc_vars: $help_coldc_expr;

var $root manager = $help_coldc_vars;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854057942;
var $has_name name = ['prop, "Variable Expression", "Variable Expression"];
var $help_node links = #[["Defining Methods", $help_coldc_methods], ["Objects and Variables", $help_coldc_objs_vars], ["assignment expression", $help_coldc_assign]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdC provides two kinds of variables, ", <$format, ["i", [], ["local variables"], 'do_i]>, " and ", <$format, ["i", [], ["object variables"], 'do_i]>, ". ", <$format, ["i", [], ["Local variables"], 'do_i]>, " are used within methods to temporarily store data. In order for a local variable to be used it must first be declared at the top of the method in a ", <$format, ["tt", [], ["var"], 'do_tt]>, " declaration (see section ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, "). ", <$format, ["i", [], ["Object variables"], 'do_i]>, " are defined on an object, and can be used to store data for an indefinite period of time (at least until the object is destroyed). More information on Variables can be found in the section ", <$format, ["link", [["node", "$help_coldc_objs_vars"]], ["Objects and Variables"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "When a variable is evaluated as an expression, its value is that of its contents (the data stored in the variable name). Initially variables will contain the integer data value of zero (", <$format, ["tt", [], ["0"], 'do_tt]>, "). To set the contents of a variable, use the ", <$format, ["link", [["node", "$help_coldc_assign"]], ["assignment expression"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "The value of a local variable is specific to the currently executing method frame. When the method is invoked at another time all of the local variables begin again with the value of zero (", <$format, ["tt", [], ["0"], 'do_tt]>, "). ", <$format, ["np", [], [], 'do_np]>, "If the variable is a local variable, it must be declared as a local variable at the top of the method (see ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, "). If it is not declared at the top of the method, the interpreter will assume it is an object variable. In the case that both a local variable and an object variable have the same name, the local variable will take precedence. ", <$format, ["np", [], [], 'do_np]>, "It is possible to indirectly access and set data on an object variable using the functions ", <$format, ["link", [["node", "$help_func_get_var"]], ["get_var()"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_func_set_var"]], ["set_var()"], 'do_link]>, ". Normally, an object variable is accessed and set just as if it were a local variable. These functions are useful for indirectly setting or accessing the variable, or for when there is a possible conflict with a local variable. If the variable is not declared in the method, the interpreter will always assume it is an object variable."], #[['this, $help_coldc_vars]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_vars];
var $help_node nolist = 0;


new object $help_coldc_fcall: $help_coldc_expr;

var $root manager = $help_coldc_fcall;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854057965;
var $has_name name = ['prop, "Function Call Expression", "Function Call Expression"];
var $help_node links = #[["Function Reference", $help_coldc_func]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Functions are driver-defined procedures which perform a certain action which ColdC is incapable of (such as opening a network connection), or which the driver can handle more efficiently. A function is called using the ", <$format, ["i", [], ["function call expression"], 'do_i]>, ", which has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["function"], 'do_i]>, "(", <$format, ["i", [], ["arg1"], 'do_i]>, ", ", <$format, ["i", [], ["arg2"], 'do_i]>, ", ", <$format, ["i", [], ["..."], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In this example ", <$format, ["i", [], ["function"], 'do_i]>, " is an identifier naming the function, and ", <$format, ["i", [], ["arg1"], 'do_i]>, ", ", <$format, ["i", [], ["arg2"], 'do_i]>, " are expressions. There are no limits to the amount of arguments a function can accept. However, even if there are no arguments the parentheses must be present. Arguments are evaluated from left to right. ", <$format, ["np", [], [], 'do_np]>, "As an example, the ", <$format, ["tt", [], ["pad()"], 'do_tt]>, " function pads a string argument with spaces to a certain length. When evaluated with the string \"foo\" and a length of six characters:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["pad(\"foo\", 6)", <$format, ["br", [], [], 'do_br]>, "=> \"foo \""], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "There are driver functions available for a variety of tasks. A comprehensive explanation of the available functions is available in the section ", <$format, ["link", [["node", "$help_coldc_func"]], ["Function Reference"], 'do_link]>, "."], #[['this, $help_coldc_fcall]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_fcall];
var $help_node nolist = 0;


new object $help_coldc_mcall: $help_coldc_expr;

var $root manager = $help_coldc_mcall;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854057972;
var $has_name name = ['prop, "Method Call Expression", "Method Call Expression"];
var $help_node links = #[["Defining Methods", $help_coldc_methods], ["Calling Overridden Methods", $help_coldc_mcall_over]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Methods defined on an object can be executed with the ", <$format, ["i", [], ["method-call expression"], 'do_i]>, ", which has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["receiver"], 'do_i]>, ".", <$format, ["i", [], ["method"], 'do_i]>, "(", <$format, ["i", [], ["arg1"], 'do_i]>, ", ", <$format, ["i", [], ["arg2"], 'do_i]>, ", ", <$format, ["i", [], ["..."], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In this example ", <$format, ["i", [], ["receiver"], 'do_i]>, " is the object where ", <$format, ["i", [], ["method"], 'do_i]>, " may be called, and ", <$format, ["i", [], ["arg1"], 'do_i]>, ", ", <$format, ["i", [], ["arg2"], 'do_i]>, " are expressions. There are is no limit to the number of arguments sent, although even if there are no arguments the parenthesis must exist. Arguments are evaluated from left to right. ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["i", [], ["receiver"], 'do_i]>, " may be omitted, in which case it is assumed to be the current object. If ", <$format, ["i", [], ["receiver"], 'do_i]>, " does not exist in the database, the error ", <$format, ["tt", [], ["~objnf"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "Any ColdC Data (with the exception of Frobs) may be used in place of the object as the ", <$format, ["i", [], ["receiver"], 'do_i]>, ". If a method is called in this manner, the interpreter will lookup an object with an object name that is the same as the type of data being used (such as an object named ", <$format, ["tt", [], ["$string"], 'do_tt]>, " if the data is a ", <$format, ["tt", [], ["'string"], 'do_tt]>, "). If an object is found in the database with this name, the method is called on that object and the data is sent as the first argument (subsequent arguments will still be sent). If not, the error ", <$format, ["tt", [], ["~objnf"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "If a Frob is used in place of ", <$format, ["i", [], ["receiver"], 'do_i]>, ", the class object for the frob becomes the ", <$format, ["i", [], ["receiver"], 'do_i]>, " and the representation of the frob is sent as the first argument. Because of this difference it is possible to have a special method that only a frob may call. For more information on frobbed methods see ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["i", [], ["method"], 'do_i]>, " must be either the name of the method, or an expression which results in a symbol for the name of the method. If ", <$format, ["i", [], ["method"], 'do_i]>, " cannot be found on ", <$format, ["i", [], ["receiver"], 'do_i]>, " or any of ", <$format, ["i", [], ["receiver"], 'do_i]>, "'s ancestors, then the error ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "The result from a method-call expression is the value returned by the method. If the method does not return a value, the result is ", <$format, ["i", [], ["receiver"], 'do_i]>, ". If ", <$format, ["i", [], ["receiver"], 'do_i]>, " is a frob, then the method is called on the frob's class object, with the frob's representation inserted as the first argument (other arguments are placed after the representation). ", <$format, ["np", [], [], 'do_np]>, "Here are some examples of method-call expressions:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [".tell(\"I don't see that here.\");", <$format, ["br", [], [], 'do_br]>, "=> $brandon"], 'do_dfn]>, " ", <$format, ["dfn", [], ["$sys.admins();", <$format, ["br", [], [], 'do_br]>, "=> [$lynx, $dancer, $jenner]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["([1, 2, 3]).reverse()", <$format, ["br", [], [], 'do_br]>, "=> [3, 2, 1]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["$parser.(tosym(what + \"_mesg\"))(messages)", <$format, ["br", [], [], 'do_br]>, "=> $parser"], 'do_dfn]>, " ", <$format, ["dfn", [], ["(<$thing_frob, #[['myname, \"coins\"], ['amount, 300]]>).name()", <$format, ["br", [], [], 'do_br]>, "=> \"300 coins\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In order to prevent incidents of infinite recursion, there is a maximum calling depth for methods. If calling a method would exceed the maximum calling depth, the error ", <$format, ["tt", [], ["~maxdepth"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "If a method is overridden it is still possible for it to be called. For more information see the section ", <$format, ["link", [["node", "$help_coldc_mcall_over"]], ["Calling Overridden Methods"], 'do_link]>, "."], #[['this, $help_coldc_mcall]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_mcall];
var $help_node nolist = 0;


new object $help_coldc_mcall_over: $help_coldc_mcall;

var $root manager = $help_coldc_mcall_over;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058039;
var $has_name name = ['prop, "Overridden Methods|override", "Overridden Methods|override"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "If a method overrides another method defined on an ancestor, the overriding method can call the overridden method using the function ", <$format, ["tt", [], ["pass()"], 'do_tt]>, ". Arguments to ", <$format, ["tt", [], ["pass()"], 'do_tt]>, " are sent to the overridden method as if the method were called normally. The return value of ", <$format, ["tt", [], ["pass()"], 'do_tt]>, " is the normal return value of the overridden method. ", <$format, ["np", [], [], 'do_np]>, "For instance, passing to an overridden method with:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["pass(\"this arg\", 2);"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Would be rougly equivalent to calling the same method, if it was not overridden, with:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["obj.method(\"this arg\", 2);"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When executed in this manner, the overridden method sees the same object, sender, and caller as the current method. ", <$format, ["np", [], [], 'do_np]>, "In the situation where a descendant overrides a method defined on two of its ancestors, you can determine which method is passed to using the function ", <$format, ["i", [], [<$format, ["link", [["node", "$help_func_find_next_method"]], ["find_next_method()"], 'do_link]>], 'do_i]>, ". The following method (assuming a ColdCore database) can also be of use:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["arg obj, method;\nvar trace, current;\n\ncurrent = (> obj.find_method(method) <);\ntrace = [];\nwhile (current) {\n    trace += [current];\n    current = (| obj.find_next_method(method, current) |);\n}\nreturn trace;"], 'do_quote]>], 'do_dfn]>], #[['this, $help_coldc_mcall_over]]]>;
var $root inited = 1;
var $help_node group = 1;
var $root managed = [$help_coldc_mcall_over];
var $help_node nolist = 0;


new object $help_coldc_err_expr: $help_coldc_expr;

var $root manager = $help_coldc_err_expr;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854057983;
var $has_name name = ['prop, "Error Handling Expression", "Error Handling Expression"];
var $help_node links = #[["Errors", $help_coldc_errors]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Two mechanisms exist for handling errors in expressions. These are the ", <$format, ["i", [], ["critical expression"], 'do_i]>, " and the ", <$format, ["i", [], ["propagation expression"], 'do_i]>, ". The ", <$format, ["i", [], ["critical expression"], 'do_i]>, " is used to ignore any errors thrown from inside the expression. It has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["(| expression |)"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If an error occurs in ", <$format, ["i", [], ["expression"], 'do_i]>, " the interpreter will stop evaluating ", <$format, ["i", [], ["expression"], 'do_i]>, " and continue to execute the current method as if it had succeeded evaluating ", <$format, ["i", [], ["expression"], 'do_i]>, ". The value of ", <$format, ["i", [], ["expression"], 'do_i]>, " will be the error code for the error which occurred. ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["i", [], ["propagation expression"], 'do_i]>, " causes any error thrown by a method call within the expression to be thrown as if the current method threw it. It has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["(> expression <)"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "If an error occurs in ", <$format, ["i", [], ["expression"], 'do_i]>, " it will propagate to the calling method as if the error had originated in the calling method and not in the current method. Otherwise, the calling method will receive the error as ", <$format, ["tt", [], ["~methoderr"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "Critical expressions override the behavior of catch statements so that errors which occur within critical expressions do not trigger catch error handlers. Propagation expressions do not override critical expressions or catch statements, however. They do not prevent errors from being caught; they only determine how errors propagate if they are not caught. ", <$format, ["np", [], [], 'do_np]>, "For more information on handling errors, see section ", <$format, ["link", [["node", "$help_coldc_errors"]], ["Errors"], 'do_link]>, "."], #[['this, $help_coldc_err_expr]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_err_expr];
var $help_node nolist = 0;


new object $help_coldc_loop_expr: $help_coldc_expr;

var $root manager = $help_coldc_loop_expr;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854057996;
var $has_name name = ['prop, "Looping Expressions", "Looping Expressions"];
var $help_node links = #[["map", $help_coldc_map], ["hash", $help_coldc_hash], ["find", $help_coldc_find], ["filter", $help_coldc_filter]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Cold offers several expressions that enable looping through lists, dictionaries or integer ranges. Their main advantages over looping statements are brevity and preallocating of lists/dictionaries they return (for greater speed). The loop expressions are:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_map"]], ["map"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_hash"]], ["hash"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_find"]], ["find"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_filter"]], ["filter"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_loop_expr]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_loop_expr];
var $help_node nolist = 0;


new object $help_coldc_map: $help_coldc_loop_expr;

var $root manager = $help_coldc_map;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854330811;
var $has_name name = ['prop, "map", "map"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["tt", [], ["map"], 'do_tt]>, " expression loops a variable through a list, dictionary or integer range, evaluating an expression for each iteration. Results from each iteration are collected into a list and returned when the loop is completed. The syntax for map can be either of the following:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["map ", <$format, ["i", [], ["var"], 'do_i]>, " in (", <$format, ["i", [], ["what expr"], 'do_i]>, ") to (", <$format, ["i", [], ["iteration expr"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, "map ", <$format, ["i", [], ["var"], 'do_i]>, " in [", <$format, ["i", [], ["lower expr"], 'do_i]>, " .. ", <$format, ["i", [], ["upper expr"], 'do_i]>, "] to (", <$format, ["i", [], ["iteration expr"], 'do_i]>, ")"], 'do_tt]>, " "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["map x in ([1, 2, 3]) to (tostr(x))", <$format, ["br", [], [], 'do_br]>, "=> [\"1\", \"2\", \"3\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["map x in [5 .. 15] to (x)", <$format, ["br", [], [], 'do_br]>, "=> [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]"], 'do_dfn]>], #[['this, $help_coldc_map]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_map];
var $help_node nolist = 0;


new object $help_coldc_hash: $help_coldc_loop_expr;

var $root manager = $help_coldc_hash;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854330811;
var $has_name name = ['prop, "hash", "hash"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["tt", [], ["hash"], 'do_tt]>, " expression loops a variable through a list, dictionary or integer range, evaluating an expression for each iteration. Results from each iteration must be contained within a two element list. The list is inserted as the key/value pair into a dictionary. After the loop completes the final dictionary is returned. The syntax for hash can be either of the following:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["hash x in ([1, 2, 3]) to ([toobjnum(x).name(), x])", <$format, ["br", [], [], 'do_br]>, "=> #[[\"$root\", 1], [\"Brandon\", 2], [\"Dancer\", 3]]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["hash x in [1 .. 3] to (.random_pair())", <$format, ["br", [], [], 'do_br]>, "=> #[[\"Dancer\", 1], [\"Miro\", 7], [\"$root\", 1]]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In the above example the method ", <$format, ["tt", [], [".random_pair()"], 'do_tt]>, " returns a random two element key/value pair."], #[['this, $help_coldc_hash]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_hash];
var $help_node nolist = 0;


new object $help_coldc_find: $help_coldc_loop_expr;

var $root manager = $help_coldc_find;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854330811;
var $has_name name = ['prop, "find", "find"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The find expression is used to find the position of something in a list or dictionary. It does this by looping through the given list or dictionary and testing the iteration expression. When the iteration expression evaluates true it stops and returns the given position. The syntax of find is:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["find var in (what expr) where (iteration expr)", <$format, ["br", [], [], 'do_br]>, "find var in [lower expr .. upper expr] where (iteration expr)"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If iteration expression never evaluated true, find returns a zero. The following examples assume the variable ", <$format, ["i", [], ["list"], 'do_i]>, " is set as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["[\"First line\",\"second line\",\"3rd line\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["list[find x in (list) where (x.match_regexp(\"co\"))]", <$format, ["br", [], [], 'do_br]>, "=> \"second line\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["find x in [1 .. listlen(list)] where (list[x].match_regexp(\"co\"))", <$format, ["br", [], [], 'do_br]>, "=> 2"], 'do_dfn]>], #[['this, $help_coldc_find]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_find];
var $help_node nolist = 0;


new object $help_coldc_filter: $help_coldc_loop_expr;

var $root manager = $help_coldc_filter;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854330811;
var $has_name name = ['prop, "filter", "filter"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["tt", [], ["filter"], 'do_tt]>, " expression is used to selectively pull elements from a list or dictionary. It loops through the given list or dictionary and adds each element to a new list if the iteration expression tests true. The final list is returned after filter finishes looping. The syntax of filter is:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["filter var in (what expr) where (iteration expr)", <$format, ["br", [], [], 'do_br]>, "filter var in [lower expr .. upper expr] where (iteration expr)"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The following examples assume the variable ", <$format, ["i", [], ["list"], 'do_i]>, " is set as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["[\"First line\", \"second line\", \"3rd line\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["filter x in (list) where (x.match_regexp(\"co\"))", <$format, ["br", [], [], 'do_br]>, "=> [\"second line\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["filter x in [1 .. list.length()] where (list[x].match_regexp(\"co\"));", <$format, ["br", [], [], 'do_br]>, "=> [2]"], 'do_dfn]>], #[['this, $help_coldc_filter]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_filter];
var $help_node nolist = 0;


new object $help_coldc_stmts: $help_coldc_lang;

var $root manager = $help_coldc_stmts;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058207;
var $has_name name = ['prop, "Statements", "Statements"];
var $help_node links = #[["expressions", $help_coldc_expr], ["Simple", $help_coldc_simple_stmts], ["Conditional", $help_coldc_cond_stmts], ["Error Handling", $help_coldc_err_stmts], ["Looping", $help_coldc_loop_stmts]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A ", <$format, ["i", [], ["statement"], 'do_i]>, " is a complete instruction to the interpreter. Statements are composed of ", <$format, ["link", [["node", "$help_coldc_expr"]], ["expressions"], 'do_link]>, " or constructs. Statements can be simple (such as comments), or they can be complex (such as loops and conditionals). Most statement types in ColdC have simple structures. Because statements can include other statements (using a compound statement) they can be used to build complex directives for the interpreter. Statements are grouped into four categories:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_simple_stmts"]], ["Simple"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_cond_stmts"]], ["Conditional"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_err_stmts"]], ["Error Handling"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_loop_stmts"]], ["Looping"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_stmts]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_stmts];
var $help_node nolist = 0;


new object $help_coldc_simple_stmts: $help_coldc_stmts;

var $root manager = $help_coldc_simple_stmts;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058235;
var $has_name name = ['prop, "Simple", "Simple"];
var $help_node links = #[["Comment", $help_coldc_comment_stmt], ["Expression", $help_coldc_expr_stmt], ["Compound", $help_coldc_compound_stmt], ["Return", $help_coldc_return_stmt]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Simple statements evaluate one instruction, once. There are four different simple statements in ColdC:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_comment_stmt"]], ["Comment"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_expr_stmt"]], ["Expression"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_compound_stmt"]], ["Compound"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_return_stmt"]], ["Return"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_simple_stmts]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_simple_stmts];
var $help_node nolist = 0;


new object $help_coldc_comment_stmt: $help_coldc_simple_stmts;

var $root manager = $help_coldc_comment_stmt;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854343841;
var $has_name name = ['prop, "Comment", "Comment"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["comment statement"], 'do_i]>, " does nothing. A comment statement is used for including notes within ColdC code. It is formatted as two forward slashes followed by any characters up to the end of the line, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["// This is a comment."], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The interpreter ignores comment statements completely; they are for the benefit of human readers. Note that comments in ColdC are actual statements, unlike comments in other languages, which are usually discarded by the preprocessor."], #[['this, $help_coldc_comment_stmt]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_comment_stmt];
var $help_node nolist = 0;


new object $help_coldc_expr_stmt: $help_coldc_simple_stmts;

var $root manager = $help_coldc_expr_stmt;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854390331;
var $has_name name = ['prop, "Expression", "Expression"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["expression statement"], 'do_i]>, " evaluates a complete expression, discarding the result. The syntax of an expression statement is an expression followed by a semi colon, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["expression"], 'do_i]>, ";"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["\"this\";", <$format, ["br", [], [], 'do_br]>, "y = x + 50;"], 'do_tt]>], 'do_dfn]>], #[['this, $help_coldc_expr_stmt]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_expr_stmt];
var $help_node nolist = 0;


new object $help_coldc_compound_stmt: $help_coldc_simple_stmts;

var $root manager = $help_coldc_compound_stmt;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854390331;
var $has_name name = ['prop, "Compound", "Compound"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The compound statement is used to group one or more statements as a single statement. The compound statement is formatted as any number of statements contained within left and right curly braces, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["{", <$format, ["dfn", [], [<$format, ["i", [], ["statement1", <$format, ["br", [], [], 'do_br]>, "statement2", <$format, ["br", [], [], 'do_br]>, "..", <$format, ["br", [], [], 'do_br]>, "..", <$format, ["br", [], [], 'do_br]>, ".."], 'do_i]>], 'do_dfn]>, "}"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The interpreter evaluates each statement in the compound block in turn."], #[['this, $help_coldc_compound_stmt]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_compound_stmt];
var $help_node nolist = 0;


new object $help_coldc_return_stmt: $help_coldc_simple_stmts;

var $root manager = $help_coldc_return_stmt;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854390331;
var $has_name name = ['prop, "Return", "Return"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["return statement"], 'do_i]>, " stops executing the current method and (optionally) returns a specific value. The return statement can have either of the following two forms:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["return ", <$format, ["i", [], ["expression"], 'do_i]>, ";", <$format, ["br", [], [], 'do_br]>, "return;"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If ", <$format, ["i", [], ["expression"], 'do_i]>, " exists the interpreter evaluates and returns its result from the method. Otherwise, if no expression is given the current object is returned."], #[['this, $help_coldc_return_stmt]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_return_stmt];
var $help_node nolist = 0;


new object $help_coldc_cond_stmts: $help_coldc_stmts;

var $root manager = $help_coldc_cond_stmts;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058244;
var $has_name name = ['prop, "Conditional", "Conditional"];
var $help_node links = #[["if", $help_coldc_cond_if], ["if-else", $help_coldc_cond_ifelse], ["switch", $help_coldc_cond_switch]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Conditional statements execute other statements if a test condition evaluates true. There are three types of conditional statements in ColdC:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_cond_if"]], ["if"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_cond_ifelse"]], ["if-else"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_cond_switch"]], ["switch"], 'do_link]>], 'do_li]>], 'do_ul]>, <$format, ["np", [], [], 'do_np]>, "Because the if statement and the if-else statement are similar, they can sometimes be ambiguous. The following code will produce unexpected results:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["if (a)\n    if (b) c;\nelse\n    d;"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The indentation suggests that the ", <$format, ["tt", [], ["else"], 'do_tt]>, " clause should apply to the first ", <$format, ["tt", [], ["if"], 'do_tt]>, " clause, but in fact it applies to the more recent one. Ambiguities like this can be avoided by using braces to create compound statements out of conditional and looping statements, even if there is only one statement. A less ambiguous way to write the above is:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["if (a) {\n    if (b)\n        c;\n} else {  \n    d;\n}"], 'do_quote]>], 'do_dfn]>], #[['this, $help_coldc_cond_stmts]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_cond_stmts];
var $help_node nolist = 0;


new object $help_coldc_cond_if: $help_coldc_cond_stmts;

var $root manager = $help_coldc_cond_if;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854395476;
var $has_name name = ['prop, "if", "if"];
var $help_node links = #[["compound statement", $help_coldc_compound_stmt]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["if statement"], 'do_i]>, " is used to selectively execute code. It will only execute the code if the ", <$format, ["i", [], ["condition expression"], 'do_i]>, " evaluates true. It has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["if (", <$format, ["i", [], ["condition expression"], 'do_i]>, ") ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["i", [], ["statement"], 'do_i]>], 'do_dfn]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When the interpreter encounters the ", <$format, ["i", [], ["if statement"], 'do_i]>, " it will first evaluate the ", <$format, ["i", [], ["condition expression"], 'do_i]>, ". If the value of the ", <$format, ["i", [], ["condition expression"], 'do_i]>, " is true then it will evaluate the ", <$format, ["i", [], ["statement"], 'do_i]>, ". If it is not true it will skip the ", <$format, ["i", [], ["statement"], 'do_i]>, ". The ", <$format, ["link", [["node", "$help_coldc_compound_stmt"]], ["compound statement"], 'do_link]>, " can be used to group multiple statements."], #[['this, $help_coldc_cond_if]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_cond_if];
var $help_node nolist = 0;


new object $help_coldc_cond_ifelse: $help_coldc_cond_stmts;

var $root manager = $help_coldc_cond_ifelse;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854395484;
var $has_name name = ['prop, "if-else|else", "if-else|else"];
var $help_node links = #[["if statement", $help_coldc_cond_if], ["compound statement", $help_coldc_compound_stmt]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["if-else statement"], 'do_i]>, " is similar to the ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_cond_if"]], ["if statement"], 'do_link]>], 'do_i]>, ". It further extends the ", <$format, ["i", [], ["if statement"], 'do_i]>, "'s syntax to include a second statement for when the ", <$format, ["i", [], ["condition expression"], 'do_i]>, " evaluates false. It has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["if (", <$format, ["i", [], ["condition expression"], 'do_i]>, ") ", <$format, ["dfn", [["ind", "4"]], [<$format, ["i", [], ["true statement"], 'do_i]>], 'do_dfn]>, "else ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["i", [], ["false statement"], 'do_i]>], 'do_dfn]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When the interpreter encounters the ", <$format, ["i", [], ["if-else statement"], 'do_i]>, " it will first evaluate the ", <$format, ["i", [], ["condition expression"], 'do_i]>, ". If the value of the ", <$format, ["i", [], ["condition expression"], 'do_i]>, " is true, it will execute the ", <$format, ["i", [], ["true expression"], 'do_i]>, ", otherwise it will execute the ", <$format, ["i", [], ["false expression"], 'do_i]>, ". The ", <$format, ["link", [["node", "$help_coldc_compound_stmt"]], ["compound statement"], 'do_link]>, " can be used to group multiple statements."], #[['this, $help_coldc_cond_ifelse]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_cond_ifelse];
var $help_node nolist = 0;


new object $help_coldc_cond_switch: $help_coldc_cond_stmts;

var $root manager = $help_coldc_cond_switch;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854395484;
var $has_name name = ['prop, "switch", "switch"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["switch statement"], 'do_i]>, " is used to compare one value against a series of other values. The switch statement is the most complicated statement in ColdC, and does vary from it's counterpart in C, so rather than using abstract explanations we will start with an example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["switch (val) {\n    case 0:\n        cwrite(\"The value is zero.\");\n    case 1 .. 10:\n        cwrite(\"The value is between one and ten inclusive.\");\n    case 11 .. a:\n        cwrite(\"The value is between eleven and a inclusive.\");\n    case \"foo\", \"bar\"..\"baz\":\n        cwrite(\"The value is \\\"foo\\\" or between \\\"bar\\\" and \\\"baz\\\"\");\n    case a .. b, c .. d, 42:\n        count = count + 1;\n        cwrite(\"The value is in the counted area.\");\n    case ~perm:\n        cwrite(\"Permission denied while getting the value.\");\n    default:\n        cwrite(\"Did not recognize value.\");\n}"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This example illustrates all of the capabilities of the switch statement. The expression given by ", <$format, ["tt", [], ["val"], 'do_tt]>, " in the example is the ", <$format, ["i", [], ["controlling expression"], 'do_i]>, ", and is compared against each of the cases inside the switch body until a match is found. Each ", <$format, ["tt", [], ["case"], 'do_tt]>, " has a value or list of values to compare against. The values can be of any type, and need not be constant expressions. Ranges are specified using two dots (", <$format, ["tt", [], [".."], 'do_tt]>, ") to separate the lower and upper bounds. The keyword ", <$format, ["tt", [], ["default"], 'do_tt]>, " specifies an action to perform if no cases were matched by the controlling expression. ", <$format, ["np", [], [], 'do_np]>, "Here is a more formal description of the syntax of the switch statement:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["switch (", <$format, ["i", [], ["controlling-expression"], 'do_i]>, ") { ", <$format, ["dfn", [["ind", "4"]], ["case ", <$format, ["i", [], ["expr-or-range"], 'do_i]>, ", ", <$format, ["i", [], ["expr-or-range"], 'do_i]>, ", ", <$format, ["i", [], [".."], 'do_i]>, ": ", <$format, ["dfn", [["ind", "4"]], ["statement"], 'do_dfn]>, "case ", <$format, ["i", [], ["expr-or-range"], 'do_i]>, ", ", <$format, ["i", [], ["expr-or-range"], 'do_i]>, ", ", <$format, ["i", [], [".."], 'do_i]>, ": ", <$format, ["dfn", [["ind", "4"]], ["statement"], 'do_dfn]>, <$format, ["i", [], [".."], 'do_i]>, <$format, ["br", [], [], 'do_br]>, "default: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["i", [], ["default-statement"], 'do_i]>], 'do_dfn]>], 'do_dfn]>, "}"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When executing a switch statement, the interpreter scans through the list of cases and compares the ", <$format, ["i", [], ["controlling-expression"], 'do_i]>, " against each of the cases, evaluating the case from left to right until there is a match. When using a range, the lower and upper bounds must be of the same type and must be either integers or strings. If they are not the error ", <$format, ["tt", [], ["~type"], 'do_tt]>, " is thrown. When the interpreter finds a match, it will execute the statement for that case. The interpreter will not continue checking cases after a match. ", <$format, ["np", [], [], 'do_np]>, "If the interpreter does not find a match, it will execute instead execute the ", <$format, ["i", [], ["default-statement"], 'do_i]>, ". A default statement does not need to be defined. If a default is not defined nothing in the switch is executed. ", <$format, ["np", [], [], 'do_np]>, <$format, ["tt", [], ["C"], 'do_tt]>, " programmers should note that switch statements in ColdC differ from switch statements in ", <$format, ["tt", [], ["C"], 'do_tt]>, " in several respects. Because case values do not have to be constants, they may conflict, in which case the first match will take precedence. Also, there is no fall-through in ColdC switch statements; only the statements corresponding to the matching case will be executed. Because there is no fall-through, the ", <$format, ["tt", [], ["break"], 'do_tt]>, " statement does not apply to switch statements. Finally, the default case must be placed last in the list of cases if it is given."], #[]]>;
var $root inited = 1;
var $root managed = [$help_coldc_cond_switch];
var $help_node nolist = 0;


new object $help_coldc_err_stmts: $help_coldc_stmts;

var $root manager = $help_coldc_err_stmts;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058264;
var $has_name name = ['prop, "Error-Handling|catch", "Error-Handling|catch"];
var $help_node links = #[["error()", $help_func_error], ["traceback()", $help_func_traceback], ["rethrow()", $help_func_rethrow], ["throw()", $help_func_throw], ["critical expressions", $help_coldc_err_expr]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["catch statement"], 'do_i]>, " is used to catch and recuperate from errors. The catch statement has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["catch ", <$format, ["i", [], ["error code"], 'do_i]>, ", ", <$format, ["i", [], ["error code"], 'do_i]>, ", ", <$format, ["i", [], [".."], 'do_i]>, " ", <$format, ["dfn", [["ind", "4"]], [<$format, ["i", [], ["body-statement"], 'do_i]>], 'do_dfn]>, "with ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["i", [], ["handler-statement"], 'do_i]>], 'do_dfn]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The keyword ", <$format, ["tt", [], ["any"], 'do_tt]>, " can be substituded for the list of errors to to catch all errors. The handler statement is optional, and does not need to be defined. ", <$format, ["np", [], [], 'do_np]>, "If an error listed in the error list is thrown inside the ", <$format, ["i", [], ["body-statement"], 'do_i]>, ", the interpreter will catch the error and start executing ", <$format, ["i", [], ["handler-statement"], 'do_i]>, " rather than aborting the method. After the handler is done, the interpreter continues executing after the end of the catch statement, as if ", <$format, ["i", [], ["body-statement"], 'do_i]>, " had completed with no errors. ", <$format, ["np", [], [], 'do_np]>, "Inside the handler statement, the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_error"]], ["error()"], 'do_link]>], 'do_tt]>, " can be used to retrieve the error code which triggered the handler and the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_traceback"]], ["traceback()"], 'do_link]>], 'do_tt]>, " can be used to retrieve the propagated error stack. The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_rethrow"]], ["rethrow()"], 'do_link]>], 'do_tt]>, " is used to continue propagating an error. The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_throw"]], ["throw()"], 'do_link]>], 'do_tt]>, " can be used at any time to throw an error. ", <$format, ["np", [], [], 'do_np]>, "Here is an example of how a catch statement could intelligently handle a ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " error thrown from the ", <$format, ["tt", [], ["list_method()"], 'do_tt]>, " function:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["catch ~methodnf\n    code = list_method(method_name);\nwith\n    .tell(\"There is no method named \" + tostr(method_name) + \".\");"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Note that ", <$format, ["link", [["node", "$help_coldc_err_expr"]], ["critical expressions"], 'do_link]>, " inside ", <$format, ["i", [], ["body-statement"], 'do_i]>, " will override the behavior of the catch statement."], #[['this, $help_coldc_err_stmts]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_err_stmts];
var $help_node nolist = 0;


new object $help_coldc_loop_stmts: $help_coldc_stmts;

var $root manager = $help_coldc_loop_stmts;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058280;
var $has_name name = ['prop, "Looping Statements", "Looping Statements"];
var $help_node links = #[["for-list", $help_coldc_forlist], ["for-range", $help_coldc_forrange], ["while", $help_coldc_while], ["break", $help_coldc_break], ["continue", $help_coldc_continue]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdC provides three kinds of looping statements. These statements are used to traverse a list or a range of numbers, or to execute a statement as long as a certain condition is true. ColdC also provides two kinds of jump statements which are used to prematurely exit from a loop or continue onto the next iteration of a loop.", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_forlist"]], ["for-list"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_forrange"]], ["for-range"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_while"]], ["while"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_break"]], ["break"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_continue"]], ["continue"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_loop_stmts]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_loop_stmts];
var $help_node nolist = 0;


new object $help_coldc_forlist: $help_coldc_loop_stmts;

var $root manager = $help_coldc_forlist;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854403194;
var $has_name name = ['prop, "for-list", "for-list"];
var $help_node links = #[["Dictionaries", $help_coldc_types]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["for-list statement"], 'do_i]>, " is used to traverse a list. It has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["for ", <$format, ["i", [], ["iteration-variable"], 'do_i]>, " in (", <$format, ["i", [], ["what expr"], 'do_i]>, ") ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["i", [], ["statement"], 'do_i]>], 'do_dfn]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, <$format, ["i", [], ["iteration-variable"], 'do_i]>, " must be a local variable (it cannot be an object variable), and ", <$format, ["i", [], ["what expr"], 'do_i]>, " must be an expression resulting in a list or dictionary type. The interpreter executes ", <$format, ["i", [], ["statement"], 'do_i]>, " once for each element in ", <$format, ["i", [], ["what"], 'do_i]>, ", assigning the current element to the ", <$format, ["i", [], ["iteration-variable"], 'do_i]>, " for the iteration. Here is an example of using a for-list statement on a list:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["for s in ([\"foo\", \"bar\", \"baz\"])\n    .tell(s);"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When executed, the method ", <$format, ["i", [], ["tell"], 'do_i]>, " is called three times, the first time with an argument of ", <$format, ["tt", [], ["\"foo\""], 'do_tt]>, " (the first element in the list), the second time with ", <$format, ["tt", [], ["\"bar\""], 'do_tt]>, " (the second element in the list), and the third time with ", <$format, ["tt", [], ["\"baz\""], 'do_tt]>, " (the last element in the list). ", <$format, ["np", [], [], 'do_np]>, "When using a dictionary as ", <$format, ["i", [], ["what expr"], 'do_i]>, ", the interpreter assigns each association in the dictionary to the ", <$format, ["i", [], ["iteration variable"], 'do_i]>, " (see ", <$format, ["link", [["node", "$help_coldc_types"]], ["Dictionaries"], 'do_link]>, "). For example, if the dictionary ", <$format, ["tt", [], ["#[['count, 21], ['name, \"foo\"]]"], 'do_tt]>, " were to be used as the ", <$format, ["i", [], ["what expr"], 'do_i]>, ", the first iteration would set ", <$format, ["i", [], ["iteration variable"], 'do_i]>, " to ", <$format, ["tt", [], ["['count, 21]"], 'do_tt]>, ", and the second iteration would set it to ", <$format, ["tt", [], ["['name, \"foo\"]"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "Assigning to the ", <$format, ["i", [], ["iteration variable"], 'do_i]>, " within a for-list statement will not change the status of the loop; the interpreter remembers where it is at in ", <$format, ["i", [], ["what"], 'do_i]>, " and will continue as normal."], #[['links, #[["Dictionaries", "$help_coldc_types"]]]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_forlist];
var $help_node nolist = 0;


new object $help_coldc_forrange: $help_coldc_loop_stmts;

var $root manager = $help_coldc_forrange;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854403194;
var $has_name name = ['prop, "for-range", "for-range"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["for-range statement"], 'do_i]>, " is used to traverse a range of integers. The range is specified by seperating the lower and upper bounds of the range with the range operator (", <$format, ["tt", [], [".."], 'do_tt]>, "), contained within the left and right square brackets (", <$format, ["tt", [], ["["], 'do_tt]>, " and ", <$format, ["tt", [], ["]"], 'do_tt]>, "). A for-list statement of this nature would look like:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["for ", <$format, ["i", [], ["variable"], 'do_i]>, " in [", <$format, ["i", [], ["lower"], 'do_i]>, " .. ", <$format, ["i", [], ["upper"], 'do_i]>, "] ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["i", [], ["statement"], 'do_i]>], 'do_dfn]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, <$format, ["i", [], ["lower"], 'do_i]>, " and ", <$format, ["i", [], ["upper"], 'do_i]>, " must be expressions resulting in an integer type (unlike a range in a switch). The interpreter executes ", <$format, ["i", [], ["statement"], 'do_i]>, " once for each number from ", <$format, ["i", [], ["lower"], 'do_i]>, " to ", <$format, ["i", [], ["upper"], 'do_i]>, ", with ", <$format, ["i", [], ["variable"], 'do_i]>, " being assigned the current number in the range. An example of using a range in a list is: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\nfor i in [1 .. 10]\n    .tell(\"iteration \" + i);"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Assigning to ", <$format, ["i", [], ["variable"], 'do_i]>, " within a for-list statement will not change the status of the loop; the interpreter remembers where it is at in ", <$format, ["i", [], ["what"], 'do_i]>, " and will continue as normal."], #[['this, $help_coldc_forrange]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_forrange];
var $help_node nolist = 0;


new object $help_coldc_while: $help_coldc_loop_stmts;

var $root manager = $help_coldc_while;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854403194;
var $has_name name = ['prop, "while", "while"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["while statement"], 'do_i]>, " is used to execute code as long as the condition expression is true. The while statement has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["while (", <$format, ["i", [], ["condition expression"], 'do_i]>, ") ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["i", [], ["statement"], 'do_i]>], 'do_dfn]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The interpreter continually evaluates ", <$format, ["i", [], ["expression"], 'do_i]>, " and executes ", <$format, ["i", [], ["statement"], 'do_i]>, " until the return value of ", <$format, ["i", [], ["expression"], 'do_i]>, " is false. Here is an example using a while statement: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\na = 1;\nwhile (a < 35)\n    a *= 2;   \n.tell(\"total: \" + a);"], 'do_quote]>], 'do_dfn]>], #[['this, $help_coldc_while]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_while];
var $help_node nolist = 0;


new object $help_coldc_break: $help_coldc_loop_stmts;

var $root manager = $help_coldc_break;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854403194;
var $has_name name = ['prop, "break", "break"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["break statement"], 'do_i]>, " is used to exit a looping statement prematurely. The break statement has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["break;"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The interpreter jumps to the end of the ", <$format, ["i", [], ["innermost"], 'do_i]>, " for-list, for-range, or while statement and continues executing. It is important to note this, as when executing multiple nested looping statements the the ", <$format, ["i", [], ["break statement"], 'do_i]>, " will only break out of the innermost loop."], #[['this, $help_coldc_break]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_break];
var $help_node nolist = 0;


new object $help_coldc_continue: $help_coldc_loop_stmts;

var $root manager = $help_coldc_continue;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854403194;
var $has_name name = ['prop, "continue", "continue"];
var $help_node links = #[["break statement", $help_coldc_break]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["continue statement"], 'do_i]>, " is used to jump to the next iteration of a loop. The continue statement has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["continue;"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The interpreter skips the remainder of the loop body and begins another iteration of the innermost looping statement. As with the ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_break"]], ["break statement"], 'do_link]>], 'do_i]>, " the ", <$format, ["i", [], ["continue statement"], 'do_i]>, " only is relevant to the innermost looping statement."], #[['this, $help_coldc_continue]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_continue];
var $help_node nolist = 0;


new object $help_coldc_imp: $help_coldc;

var $root manager = $help_coldc_imp;
var $help_node holder = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854662991;
var $has_name name = ['prop, "Implementation", "Implementation"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[['this, $help_coldc_imp]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_imp];
var $help_node nolist = 0;


new object $help_coldc_methods: $help_coldc_imp;

var $root manager = $help_coldc_methods;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058074;
var $has_name name = ['prop, "Methods", "Methods"];
var $help_node links = #[["Method Code", $help_coldc_methods_code], ["Method Flags", $help_coldc_methods_flags], ["Method Access", $help_coldc_methods_access]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A method consists of five different aspects: Arguments, Variables, ColdC Code, Access and Flags. Arguments, Variables and ColdC Code are all defined within the Method Code. Access and Flags are set and changed outside the method definition. Arguments define how the method can be called. Variables define any local variables used in the method. Code consists of the rest of the method instructions. Access defines how the method may be called and Flags define any other functionality and behaviour of the method.", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_methods_code"]], ["Method Code"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_methods_flags"]], ["Method Flags"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_methods_access"]], ["Method Access"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_methods]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_methods];
var $help_node nolist = 0;


new object $help_coldc_methods_code: $help_coldc_methods;

var $root manager = $help_coldc_methods_code;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854665860;
var $has_name name = ['prop, "Code", "Code"];
var $help_node links = #[["splice operator", $help_coldc_splice], ["add_method()", $help_func_add_method], ["Textdump", $help_coldc_textdump]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Arguments, Local Variables and the ColdC Code for a method are defined all at once, within one block of text formatted as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["arg ", <$format, ["i", [], ["arg1"], 'do_i]>, ", ", <$format, ["i", [], ["arg2"], 'do_i]>, ", ", <$format, ["i", [], [".."], 'do_i]>, ", @", <$format, ["i", [], ["rest"], 'do_i]>, ";", <$format, ["br", [], [], 'do_br]>, "var ", <$format, ["i", [], ["var1"], 'do_i]>, ", ", <$format, ["i", [], ["var2"], 'do_i]>, ", ", <$format, ["i", [], [".."], 'do_i]>, ";", <$format, ["br", [], [], 'do_br]>, <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["statement1"], 'do_i]>, <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["statement2"], 'do_i]>, <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], [".."], 'do_i]>, <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], [".."], 'do_i]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The first line is the Argument Declaration. The second line is the Local Variable Declaration. Any remaining lines are standard ColdC statements, also known generically as ColdC Code. ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["tt", [], ["arg"], 'do_tt]>, " declaration gives a list of argument variables, whose values will correspond to the arguments passed with the message. The ", <$format, ["tt", [], ["arg"], 'do_tt]>, " declaration may be omitted if the method does not take any arguments. If the final argument variable is preceeded with the ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_splice"]], ["splice operator"], 'do_link]>], 'do_i]>, " (an at-sign `", <$format, ["tt", [], ["@"], 'do_tt]>, "`), then the method can accept any number of argments; the variable ", <$format, ["i", [], ["rest"], 'do_i]>, " will contain a list of the remaining arguments. If the final argument is not defined in this way, the method can only accept the defined number of arguments, and sending any more will cause a ", <$format, ["tt", [], ["~numargs"], 'do_tt]>, " error to be thrown. ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["tt", [], ["var"], 'do_tt]>, " declaration is used to define local variables. Any variable given in the list will exist during the execution of the method. In the case of conflicts with object variables, the local variable is used first. The ", <$format, ["tt", [], ["var"], 'do_tt]>, " declaration may be omitted if no local variables are declared. ", <$format, ["np", [], [], 'do_np]>, "Once the method begins normal execution, both arguments and local variables are treated the same (as local variables). The statements ", <$format, ["i", [], ["statement1"], 'do_i]>, ", ", <$format, ["i", [], ["statement2"], 'do_i]>, ", ", <$format, ["i", [], [".."], 'do_i]>, " compose the ColdC Code body. ", <$format, ["np", [], [], 'do_np]>, "A Method is defined using the ColdC function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_add_method"]], ["add_method()"], 'do_link]>], 'do_tt]>, ", or within a ", <$format, ["link", [["node", "$help_coldc_textdump"]], ["Textdump"], 'do_link]>, "."], #[['this, $help_coldc_methods_code]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_methods_code];
var $help_node nolist = 0;


new object $help_coldc_methods_flags: $help_coldc_methods;

var $root manager = $help_coldc_methods_flags;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854665861;
var $has_name name = ['prop, "Flags", "Flags"];
var $help_node links = #[["method_flags()", $help_func_method_flags], ["set_method_flags()", $help_func_set_method_flags]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Method flags define certain behaviour features of the method. Currently the following method flags exist: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["nooverride"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Methods which specify ", <$format, ["tt", [], ["nooverride"], 'do_tt]>, " cannot be overridden by any of the defining object's descendants."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["lock"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["This locks all aspects of a method. Locked methods cannot have their access or flags changed, nor can they be recompiled during run-time. Locked methods can be changed outside of the regular running environment (such as in a textdb, or with coldcc)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["forked"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["This is used to specify that the method forks from the current task. The return value of a forked method is the task id of the new task."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["native"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["This specifies a native method. Native methods are not really methods, but are actually functions acting as a method. Because of this native methods cannot be listed or manipulated in most of the usual ways."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "All method flags, with the exception of ", <$format, ["tt", [], ["native"], 'do_tt]>, ", can be manipulated using the functions ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_method_flags"]], ["method_flags()"], 'do_link]>], 'do_tt]>, " and ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_set_method_flags"]], ["set_method_flags()"], 'do_link]>], 'do_tt]>, "."], #[['this, $help_coldc_methods_flags]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_methods_flags];
var $help_node nolist = 0;


new object $help_coldc_methods_access: $help_coldc_methods;

var $root manager = $help_coldc_methods_access;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854665867;
var $has_name name = ['prop, "Access", "Access"];
var $help_node links = #[["Frobbed Method Calls", $help_coldc_methods_frob], ["method_access()", $help_func_method_access], ["set_method_access()", $help_func_set_method_access]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "It is possible to restrict what calls a method by setting the method's access. By default all methods are ", <$format, ["i", [], ["public"], 'do_i]>, " methods. The available settings for method access are: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "15%,85%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["public"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["This access state is the default. A public method can be called by any object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["protected"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Protected methods can only be called by the defining object, or descendants of the defining object (sender() must be this())."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["private"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Private methods can only be called by the object they were defined on (caller() must be this())."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["root"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Root methods can only be called by the ", <$format, ["tt", [], ["$root"], 'do_tt]>, " object (caller() must be ", <$format, ["tt", [], ["$root"], 'do_tt]>, ")."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["driver"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Driver methods can only be called by the driver."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["frob"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["This access state only allows ", <$format, ["link", [["node", "$help_coldc_methods_frob"]], ["Frobbed Method Calls"], 'do_link]>, "."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Method access can be manipulated using the functions ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_method_access"]], ["method_access()"], 'do_link]>], 'do_tt]>, " and ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_set_method_access"]], ["set_method_access()"], 'do_link]>], 'do_tt]>, "."], #[['links, #[["Frobbed Method Calls", "$help_coldc_methods_frob"], ["method_access()", "$help_func_method_access"], ["set_method_access()", "$help_func_set_method_access"]]]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_methods_access];
var $help_node nolist = 0;


new object $help_coldc_methods_frob: $help_coldc_methods_access;

var $root manager = $help_coldc_methods_frob;
var $help_node group = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854925896;
var $has_name name = ['prop, "Frobbed", "Frobbed"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Frobbed Method calls behave slightly different than any other access restriction. First, a frobbed method may only be called from a frob. That is, it must be called where the frob is the receiver, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["(<$object, #[]>).method()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If it is called in the normal way, it will be as if the frobbed method does not exist. For example, assume ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, " is a parent of ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, ". ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, " defines the method ", <$format, ["tt", [], [".name()"], 'do_tt]>, " as a standard method, but ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, " overrides it and defines it as a frobbed method. Calling ", <$format, ["tt", [], ["$obj_b.name()"], 'do_tt]>, " will actually skip the frobbed method and execute the method defined on ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, " where calling ", <$format, ["tt", [], ["(<$obj_b, #[]>).name()"], 'do_tt]>, " will execute the frobbed method defined on ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "When a Frobbed Method passes back to an overridden method it will look first for another Frobbed method, and then for a standard method. ", <$format, ["np", [], [], 'do_np]>, "If a method is defined as non-overridable, it may still be overridden by a Frobbed Method. This allows for Frob Class objects to emulate real object systems in the database, with frobs."], #[['this, $help_coldc_methods_frob]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_methods_frob];
var $help_node nolist = 0;


new object $help_coldc_tasks: $help_coldc_imp;

var $root manager = $help_coldc_tasks;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058088;
var $has_name name = ['prop, "Tasks and Frames", "Tasks and Frames"];
var $help_node links = #[["Execution Frame", $help_coldc_tasks_frames], ["Task", $help_coldc_tasks_tasks], ["Preempting", $help_coldc_tasks_preempt]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The state of a method as it is being evaluated is called the ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_tasks_frames"]], ["Execution Frame"], 'do_link]>], 'do_i]>, ". Each frame has a few unique values associated with it, which may or may not propagate to the next execution frame. ", <$format, ["np", [], [], 'do_np]>, "One or more frames executed in a series is called a ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_tasks_tasks"]], ["Task"], 'do_link]>], 'do_i]>, ". Tasks will originate from either a connection, a heartbeat, or by a fork in another task. There is no restriction on how many frames a task can execute. ", <$format, ["np", [], [], 'do_np]>, "It is possible to stop an executing frame, refresh the ticks it has and then continue executing. This is called ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_tasks_preempt"]], ["Preempting"], 'do_link]>], 'do_i]>, ". When a task is preempted it stops executing and is queued behind other current tasks. When these tasks are finished executing the preempted task continues, with a refreshed tick amount. Further information is given in the following sections:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_tasks_frames"]], ["Execution Frame"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_tasks_tasks"]], ["Task"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_tasks]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_tasks];
var $help_node nolist = 0;


new object $help_coldc_tasks_frames: $help_coldc_tasks;

var $root manager = $help_coldc_tasks_frames;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854937535;
var $has_name name = ['prop, "Frames", "Frames"];
var $help_node links = #[["ticks_left()", $help_func_ticks_left], ["method()", $help_func_method], ["this()", $help_func_method], ["definer()", $help_func_method], ["sender()", $help_func_method], ["caller()", $help_func_method]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The state of a method as it is being evaluated is called the ", <$format, ["i", [], ["execution frame"], 'do_i]>, ". Each frame has a few unique values associated with it, including the maximum operations it can execute, the method itself, the current object and the object defining the method being executed. These values are only relevant to the current frame, and may or may not propagate to the next execution frame. ", <$format, ["np", [], [], 'do_np]>, "The maximum operations a frame can execute are also referred to as the ticks. If a frame runs out of ticks before it finishes executing, the ", <$format, ["tt", [], ["~ticks"], 'do_tt]>, " error is thrown by the interpreter. ", <$format, ["np", [], [], 'do_np]>, "These values can be determined by calling the following functions, as is appropriate: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "23%,77%"]], [<$format, ["tr", [], [<$format, ["th", [], ["FUNCTION"], 'do_th]>, <$format, ["th", [], ["RETURNS"], 'do_th]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_ticks_left"]], ["ticks_left()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["The ticks remaining in the frame"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_method"]], ["method()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["The current method"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_method"]], ["this()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["The current object"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_method"]], ["definer()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["The object defining the method"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_method"]], ["sender()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["The object which called this method (the last frame's current object)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_method"]], ["caller()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["The object defining the method which called this method (the last frame's definer)"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['this, $help_coldc_tasks_frames]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_tasks_frames];
var $help_node nolist = 0;


new object $help_coldc_tasks_tasks: $help_coldc_tasks;

var $root manager = $help_coldc_tasks_tasks;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854937905;
var $has_name name = ['prop, "Tasks", "Tasks"];
var $help_node links = #[["task_id()", $help_func_task_id], ["task_info()", $help_func_task_info], ["tasks()", $help_func_tasks], ["stack()", $help_func_stack], ["user()", $help_func_user], ["set_user()", $help_func_set_user], ["atomic()", $help_func_atomic]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "One or more frames executed in a series is called a ", <$format, ["i", [], ["task"], 'do_i]>, ". Tasks will originate from either a connection, a heartbeat, or by a fork in another task. There is no restriction on how many frames a task can execute. ", <$format, ["np", [], [], 'do_np]>, "Several different functions return information about a task, or are used on a task-wide scale: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "23%,77%"]], [<$format, ["tr", [], [<$format, ["th", [], ["FUNCTION"], 'do_th]>, <$format, ["th", [], ["BEHAVIOUR"], 'do_th]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_task_id"]], ["task_id()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns unique ID for the current task"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_task_info"]], ["task_info()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns information on a task"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_tasks"]], ["tasks()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns a list of all paused or preempted tasks"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_stack"]], ["stack()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns full execution frame stack"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_user"]], ["user()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns task user"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_user"]], ["set_user()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Sets task user"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_atomic"]], ["atomic()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Used to turn on/off Atomic execution"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["task_id()", "$help_func_task_id"], ["task_info()", "$help_func_task_info"], ["tasks()", "$help_func_tasks"], ["stack()", "$help_func_stack"], ["user()", "$help_func_user"], ["set_user()", "$help_func_set_user"], ["atomic()", "$help_func_atomic"]]]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_tasks_tasks];
var $help_node nolist = 0;


new object $help_coldc_tasks_preempt: $help_coldc_tasks;

var $root manager = $help_coldc_tasks_preempt;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854946002;
var $has_name name = ['prop, "Preempting", "Preempting"];
var $help_node links = #[["pause()", $help_func_pause], ["refresh()", $help_func_refresh], ["suspend()", $help_func_suspend], ["resume()", $help_func_resume], ["cancel()", $help_func_cancel], ["A Preempting Example", $help_coldc_tasks_preempt_examp]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "When a task is preempted it stops executing and is queued behind other current tasks. When these tasks are finished executing the preempted task continues, with a refreshed tick amount. Preempting can be caused by calling either ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_pause"]], ["pause()"], 'do_link]>], 'do_tt]>, " or ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_refresh"]], ["refresh()"], 'do_link]>], 'do_tt]>, ". ", <$format, ["tt", [], ["pause()"], 'do_tt]>, " will always preempt immediately. ", <$format, ["tt", [], ["refresh()"], 'do_tt]>, " will only preempt if the tick count is nearly exhausted. Furthermore, if executing atomically ", <$format, ["tt", [], ["refresh()"], 'do_tt]>, " will not preempt, but will immediately refresh the tick count and continue executing. ", <$format, ["np", [], [], 'do_np]>, "Tasks may also be suspended indefinitely by using the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_suspend"]], ["suspend()"], 'do_link]>], 'do_tt]>, ". The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_resume"]], ["resume()"], 'do_link]>], 'do_tt]>, " will resume a suspended task. The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_cancel"]], ["cancel()"], 'do_link]>], 'do_tt]>, " will cancel a suspended task. ", <$format, ["np", [], [], 'do_np]>, "For more information see ", <$format, ["link", [["node", "$help_coldc_tasks_preempt_examp"]], ["A Preempting Example"], 'do_link]>, "."], #[['links, #[["pause()", "$help_func_pause"], ["refresh()", "$help_func_refresh"], ["suspend()", "$help_func_suspend"], ["resume()", "$help_func_resume"], ["cancel()", "$help_func_cancel"], ["A Preempting Example", "$help_coldc_tasks_preempt_examp"]]]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_tasks_preempt];
var $help_node nolist = 0;


new object $help_coldc_tasks_preempt_examp: $help_coldc_tasks_preempt;

var $root manager = $help_coldc_tasks_preempt_examp;
var $help_node group = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854946269;
var $has_name name = ['prop, "Example", "Example"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["np", [], [], 'do_np]>, "An example of suspending a task is when reading an indefinite amount of input from a connection. Input arrives through the ", <$format, ["i", [], ["parse"], 'do_i]>, " method on an object (see ", <$format, ["link", [["node", "$help_coldc_networking"]], ["Networking"], 'do_link]>, "), which we define as follows, assuming the object variables ", <$format, ["i", [], ["reading"], 'do_i]>, ", ", <$format, ["i", [], ["read"], 'do_i]>, ", ", <$format, ["i", [], ["buffer"], 'do_i]>, " and ", <$format, ["i", [], ["lines"], 'do_i]>, ". ", <$format, ["i", [], ["reading"], 'do_i]>, " is used to store a boolean value of true or false, depending upon if we are reading input or not. ", <$format, ["i", [], ["read"], 'do_i]>, " is used to store what we have already read from the connection. ", <$format, ["i", [], ["buffer"], 'do_i]>, " is used to store incoming information which is not yet parsable by the function ", <$format, ["i", [], ["buf_to_strings()"], 'do_i]>, " (i.e. there is no carriage return yet). ", <$format, ["i", [], ["lines"], 'do_i]>, " is used to buffer lines converted by ", <$format, ["i", [], ["buf_to_strings()"], 'do_i]>, " from the connection which we have not parsed yet. It is important to use an object variable for both ", <$format, ["i", [], ["buffer"], 'do_i]>, " and ", <$format, ["i", [], ["lines"], 'do_i]>, ", because if the task suspends all information stored in either variable would be suspended along with that instance of the task.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["ind", "4"]], [<$format, ["quote", [], ["driver method .parse() {\n    arg incoming;\n    var line;\n\n    lines = buf_to_strings(buffer + incoming));\n    buffer = lines[listlen(lines)];\n    lines = delete(lines, listlen(lines));\n\n    // now parse the lines\n    for line in (buf_to_strings(incoming)) {\n        if (reading) {\n            if (line == \".\")\n                .done_reading();\n            else\n                read += [line];\n        } else {\n            .parse_line(line);\n        }\n    }\n}"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "We will not define the method ", <$format, ["i", [], ["parse_line"], 'do_i]>, ", just assume that it parses the line as a command. When an object wishes to start reading from the connection it calls the method ", <$format, ["i", [], [".read()"], 'do_i]>, " on the connection object:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["ind", "4"]], [<$format, ["quote", [], ["public method .read() {\n    // reading just has to be true, so lets save space and store the\n    // task id there as well, instead of storing it in another variable.\n    reading = task_id();\n\n    // make sure this is an empty list\n    read = [];\n\n    // suspend the task, have our return value be the return value\n    // of suspend (which is whatever resume() sends)\n    return suspend();\n}"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When a period is found as the line being read, the connection is done reading (the period is insignificant, and is only used in this example for convenience), and the method ", <$format, ["i", [], ["done_reading"], 'do_i]>, " is called:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["ind", "4"]], [<$format, ["quote", [], ["protected method .done_reading() {\n    var info, task;\n\n    // get a local copy of what we read, and the task id\n    info = read;\n    task = reading;\n\n    // reset the object variables first\n    read = [];\n    reading = 0;\n\n    // resume the task, send what we read as the return\n    // value for suspend()\n    resume(task, info);\n}"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Now, all that has to happen to read input from a connection is to call the method ", <$format, ["i", [], [".read()"], 'do_i]>, " on the connection object, and the input read is returned from the method call. ", <$format, ["np", [], [], 'do_np]>, "It is possible to set a task as ", <$format, ["i", [], ["atomic"], 'do_i]>, ". Atomic tasks cannot be preempted or suspended. If an attempt is made to preempt or suspend an atomic task the error ", <$format, ["tt", [], ["~atomic"], 'do_tt]>, " is thrown instead. However, calling ", <$format, ["tt", [], ["refresh()"], 'do_tt]>, " while executing atomically will always refresh the current frame's ticks. A task's atomic state is toggled using the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_atomic"]], ["atomic()"], 'do_link]>], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Note:"], 'do_b]>, " be very cautious when using atomic tasks. Atomic tasks can easilly disrupt the regular integrity of an online environment. See the section on ", <$format, ["link", [["node", "$help_coldc_security"]], ["Security"], 'do_link]>, "."], #[['this, $help_coldc_tasks_preempt_examp]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_tasks_preempt_examp];
var $help_node nolist = 0;


new object $help_coldc_errors: $help_coldc_imp;

var $root manager = $help_coldc_errors;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058064;
var $has_name name = ['prop, "Errors", "Errors"];
var $help_node links = #[["throw()", $help_func_throw], ["Error-Handling Expressions", $help_coldc_err_expr], ["traceback()", $help_func_traceback], ["catch statement", $help_coldc_err_stmts], ["Error-Handling Statements", $help_coldc_err_stmts], ["propagation expression", $help_coldc_err_expr]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "When something goes wrong in a ", <$format, ["tt", [], ["ColdC"], 'do_tt]>, " method an error is thrown. The interpreter will throw errors, and methods can throw custom errors (using the ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_throw"]], ["throw()"], 'do_link]>], 'do_tt]>, " function). An error consists of an error code (the ", <$format, ["i", [], ["type"], 'do_i]>, " of error), a string describing the error, and--optionally--data relative to the error. ", <$format, ["np", [], [], 'do_np]>, "When the interpreter throws an error, it checks to see how the current method handles that error type. If the error occured in a critical expression (see ", <$format, ["link", [["node", "$help_coldc_err_expr"]], ["Error-Handling Expressions"], 'do_link]>, "), then the interpreter will cease evaluating the critical expression. Processing of the method will continue as if the interpreter had completed evaluation of the critical expression. The return value of the critical expression will be the error code associated with the thrown error. In this case, the traceback is not accessible from ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_traceback"]], ["traceback()"], 'do_link]>], 'do_tt]>, "; in order to get a traceback, a ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_coldc_err_stmts"]], ["catch statement"], 'do_link]>], 'do_tt]>, " must be used. ", <$format, ["np", [], [], 'do_np]>, "If the error did not occur in a critical expression, but occurred in a catch statement which catches the error code (either because it is a ", <$format, ["tt", [], ["catch all"], 'do_tt]>, " statement or because it lists the error code (see ", <$format, ["link", [["node", "$help_coldc_err_stmts"]], ["Error-Handling Statements"], 'do_link]>, "). Then the processing of the method jumps to the error handler, if one was provided, or to the end of the catch statement if not. ", <$format, ["np", [], [], 'do_np]>, "If the error did not occur in a critical expression or in an appropriate catch statement, then the current method aborts, and the interpreter throws an error in the calling method. Normally, the error thrown in the calling routine will have the error code ", <$format, ["tt", [], ["~methoderr"], 'do_tt]>, " unless the original error occurred within a ", <$format, ["link", [["node", "$help_coldc_err_expr"]], ["propagation expression"], 'do_link]>, ". If the error occurred within a propagation expression then the error code will be the same as it was for the original error. A propagation expression has no effect on how an error is handled except to cause the error code to propagate differently to the calling routine. ", <$format, ["np", [], [], 'do_np]>, "Errors are thrown using the ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_throw"]], ["throw()"], 'do_link]>], 'do_tt]>, " function. This does not throw an error in the current method; instead, it exits the current method and throws an error in the calling method. Thus a method cannot ignore an error which it threw itself using ", <$format, ["tt", [], ["throw()"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "There is one case in which a method cannot catch an interpreter-generated error. Methods have a limited amount of time to run, measured in ", <$format, ["i", [], ["ticks"], 'do_i]>, ". A method will generally only run out of ticks if it gets stuck in an infinite loop. If a method runs out of ticks, then the interpreter will throw a ", <$format, ["tt", [], ["~ticks"], 'do_tt]>, " error, which the method cannot catch. This causes the method to abort, which in turn causes the interpreter to throw a ", <$format, ["tt", [], ["~methoderr"], 'do_tt]>, " error in the calling routine. ", <$format, ["np", [], [], 'do_np]>, "Critical expressions should be used when calling code which is possibly buggy or when the method may be undefined, and it is undesirable for the current method to stop executing as a result. For instance, a method which announces a string to every object in a container should probably ignore errors in the methods for each individual object which handle receiving the string. ", <$format, ["np", [], [], 'do_np]>, "Catch statements should be used to handle errors in any way other than ignoring them. The catch statement is much more powerful than the critical expression, and is ideal for situations in which fine-grain control over error handling is required. ", <$format, ["np", [], [], 'do_np]>, "Propagation expressions should be used when the current method is an intermediary between an outside object and an internal feature. For instance, a method which checks permissions and calls an object function such as ", <$format, ["tt", [], ["list_method()"], 'do_tt]>, " is acting as an intermediary. In this case, the method should throw the same errors as the ", <$format, ["tt", [], ["list_method()"], 'do_tt]>, " function, so the function call should be enclosed within a propagation expression."], #[['this, $help_coldc_errors]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_errors];
var $help_node nolist = 0;


new object $help_coldc_security: $help_coldc_imp;

var $root manager = $help_coldc_security;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058097;
var $has_name name = ['prop, "Security", "Security"];
var $help_node links = #[["bind_function()", $help_func_bind_function], ["atomic()", $help_func_atomic], ["cancel()", $help_func_cancel], ["create()", $help_func_create], ["backup()", $help_func_backup], ["shutdown()", $help_func_shutdown], ["set_heartbeat()", $help_func_set_heartbeat], ["bind_port()", $help_func_bind_port], ["unbind_port()", $help_func_unbind_port], ["open_connection()", $help_func_open_connection], ["fopen()", $help_func_fopen], ["fstat()", $help_func_fstat], ["fchmod()", $help_func_fchmod], ["fmkdir()", $help_func_fmkdir], ["frmdir()", $help_func_frmdir], ["files()", $help_func_files], ["fremove()", $help_func_fremove], ["frename()", $help_func_frename], ["fclose()", $help_func_fclose], ["fseek()", $help_func_fseek], ["feof()", $help_func_feof], ["fwrite()", $help_func_fwrite], ["fread()", $help_func_fread], ["execute()", $help_func_execute], ["fflush()", $help_func_fflush], ["unbind_function()", $help_func_unbind_function], ["Defining Methods", $help_coldc_methods]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "As the ColdC driver does not know what sort of environment the database defines, by default all functions are callable by any object in the database. In order to preserve integrity it is strongly suggested that the database builds a heirarchy of trusted objects. Bind administrative-level functions to these objects using the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_bind_function"]], ["bind_function()"], 'do_link]>], 'do_tt]>, " and restrict access to them. ", <$format, ["np", [], [], 'do_np]>, "It is suggested that the following functions always be bound and secured: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "30%,30%,30%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_atomic"]], ["atomic()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_cancel"]], ["cancel()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_create"]], ["create()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_backup"]], ["backup()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_shutdown"]], ["shutdown()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_heartbeat"]], ["set_heartbeat()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_bind_port"]], ["bind_port()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_unbind_port"]], ["unbind_port()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_open_connection"]], ["open_connection()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fopen"]], ["fopen()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fstat"]], ["fstat()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fchmod"]], ["fchmod()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fmkdir"]], ["fmkdir()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_frmdir"]], ["frmdir()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_files"]], ["files()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fremove"]], ["fremove()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_frename"]], ["frename()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fclose"]], ["fclose()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fseek"]], ["fseek()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_feof"]], ["feof()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fwrite"]], ["fwrite()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fread"]], ["fread()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_execute"]], ["execute()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fflush"]], ["fflush()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_bind_function"]], ["bind_function()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_unbind_function"]], ["unbind_function()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "It is also suggested that any additional function which modifies an object or which alters/retrieves data on an object be bound. ", <$format, ["np", [], [], 'do_np]>, "The database can further be secured by solidifying key methods in its internal security scheme (if one exists) and locking them (by setting the ", <$format, ["tt", [], ["'lock"], 'do_tt]>, " method flag, see section ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, ")."], #[['this, $help_coldc_security]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_security];
var $help_node nolist = 0;


new object $help_coldc_net: $help_coldc_imp;

var $root manager = $help_coldc_net;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058107;
var $has_name name = ['prop, "Networking", "Networking"];
var $help_node links = #[["bind_port()", $help_func_bind_port], ["close_connection()", $help_func_close_connection], ["connection()", $help_func_connection], ["cwrite()", $help_func_cwrite], ["cwritef()", $help_func_cwritef], ["open_connection()", $help_func_open_connection], ["unbind_port()", $help_func_unbind_port], ["reassign_connection()", $help_func_reassign_connection], ["server connection", $help_coldc_net_server], ["client connection", $help_coldc_net_client]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdC gives the ability to handle network sockets with the following functions: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "30%,30%,30%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_bind_port"]], ["bind_port()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_close_connection"]], ["close_connection()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_connection"]], ["connection()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_cwrite"]], ["cwrite()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_cwritef"]], ["cwritef()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_open_connection"]], ["open_connection()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_unbind_port"]], ["unbind_port()"], 'do_link]>], 'do_td]>, <$format, ["td", [["colspan", "2"]], [<$format, ["link", [["node", "$help_func_reassign_connection"]], ["reassign_connection()"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Connections are bound to a ", <$format, ["i", [], ["connection object"], 'do_i]>, ". The driver will use the following methods on a connection object:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], [".connect()", <$format, ["br", [], [], 'do_br]>, ".disconnect()", <$format, ["br", [], [], 'do_br]>, ".failed()", <$format, ["br", [], [], 'do_br]>, ".parse()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "There are two types of connections which can be created. The first is a ", <$format, ["link", [["node", "$help_coldc_net_server"]], ["server connection"], 'do_link]>, ", or a passive connection. To do this the driver listens on a network port and waits for incoming connections. The second type is an ", <$format, ["link", [["node", "$help_coldc_net_client"]], ["client connection"], 'do_link]>, ", or a active connection. This type of connection is established by the driver to another network host."], #[['this, $help_coldc_net]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_net];
var $help_node nolist = 0;


new object $help_coldc_net_server: $help_coldc_net;

var $root manager = $help_coldc_net_server;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854948047;
var $has_name name = ['prop, "Server Connection", "Server Connection"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "To establish a server connection first call the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_bind_port"]], ["bind_port()"], 'do_link]>], 'do_tt]>, ". The argument to this function is the network port to listen on. Note: most operating systems will restrict low numbered ports (usually anything below 1024 is restricted, and can only be opened with special privelages). If there are no errors, the current object is listening as a server on the specified port. ", <$format, ["np", [], [], 'do_np]>, "When an external client opens a connection the driver will call the method ", <$format, ["tt", [], [".connect()"], 'do_tt]>, " with two arguments. The first argument is a STRING, specifying the remote IP address of the client. The second argument is an INTEGER, specifying the socket where the connection was established. In general this number can be ignored. ", <$format, ["np", [], [], 'do_np]>, "Data received on the connection will be sent as a buffer to the method ", <$format, ["tt", [], [".parse()"], 'do_tt]>, ", after the method ", <$format, ["tt", [], [".connect()"], 'do_tt]>, " is called. Data is sent to the connection using the functions ", <$format, ["tt", [], ["cwrite()"], 'do_tt]>, " and ", <$format, ["tt", [], ["cwritef()"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "If the client terminates the connection, the method ", <$format, ["tt", [], [".disconnect()"], 'do_tt]>, " is called. Note: this method will not be called if the object terminates the connection through ", <$format, ["tt", [], ["close_connection()"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "If multiple connections will be received on the network port, it is suggested that when a connection is started the connection object either reassigns the connection to another connection object (using the function ", <$format, ["tt", [], ["reassign_connection()"], 'do_tt]>, "), or it notifies a new connection object to re-bind the port to itself. If this is not done, new connections will preempt and close the older connection (as only one connection can be on an object at a time)."], #[['this, $help_coldc_net_server]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_net_server];
var $help_node nolist = 0;


new object $help_coldc_net_client: $help_coldc_net;

var $root manager = $help_coldc_net_client;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854948047;
var $has_name name = ['prop, "Client Connection", "Client Connection"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "To establish a client connection call the function ", <$format, ["tt", [], ["open_connection()"], 'do_tt]>, " with the first argument as a STRING specifing the IP address of the host, and the second argument an INTEGER specifying the network port to connect on. This function is not a blocking function. Calling it will simply start the process of opening a connection. If there are no immediate errors the function will return normally. ", <$format, ["np", [], [], 'do_np]>, "When a connection is opened the driver will call the method ", <$format, ["tt", [], [".connect()"], 'do_tt]>, " on the current object, with the argument being an INTEGER task_id for the task which called ", <$format, ["tt", [], ["open_connection()"], 'do_tt]>, ". Connection code may wish to ", <$format, ["tt", [], ["suspend()"], 'do_tt]>, " after calling ", <$format, ["tt", [], ["open_connection()"], 'do_tt]>, ", then have the method ", <$format, ["tt", [], [".connect()"], 'do_tt]>, " resume the task when it is received. ", <$format, ["np", [], [], 'do_np]>, "If the connection could not be established, the method ", <$format, ["tt", [], [".failed()"], 'do_tt]>, " is called instead. The first argument is once again the task id, the second argument is an ERROR representing why the connection could not be established. ", <$format, ["np", [], [], 'do_np]>, "Once the connection is established, input and output is handled the same as on a server connection."], #[['this, $help_coldc_net_client]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_net_client];
var $help_node nolist = 0;


new object $help_coldc_regexp: $help_coldc_imp;

var $root manager = $help_coldc_regexp;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058118;
var $has_name name = ['prop, "Regexps|Regular Expressions", "Regexps|Regular Expressions"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdC Regular Expressions use Henry Spencer's Regular Expression package with further extensions similar to those Perl has implemented. ", <$format, ["np", [], [], 'do_np]>, "A Regular Expression is an abstract way of matching text. The simplest Regular Expression is a direct match. For instance, the string \"that\" exists within the string \"this and that are here.\", therefore \"that\" is a Regular Expression. ", <$format, ["np", [], [], 'do_np]>, "However, regular expressions can be much more complex than this case, as there are many possibilities which may be matched in strings. Wildcard matching is a common way of matching more than a simple instance of text. Wildcard matching generally matches any number of anything where a ", <$format, ["tt", [], ["`*'"], 'do_tt]>, " is found in the wildcard. Although useful it does have its restrictions. Wildcard matching is not used in Regular Expressions because of its lack of control. ", <$format, ["np", [], [], 'do_np]>, "The following is a list of all possible special characters in a regular expression which have special meaning: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "10%,90%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["\\"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Escape Mechanism, changes the meaning of the next character"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["^"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Match the beginning of a string, or if at the beginning of a range, logically inverts the value (i.e. anything NOT in this range)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["$"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Match the end of a string"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["|"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Branch Seperator"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["()"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Grouping"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["[]"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Range"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["."], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Match any one character"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["*"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Match zero or more of the previous"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Match one or more of the previous"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["?"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Match zero or one of the previous"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, " ", <$format, ["subj", [["level", "2"]], ["ColdC Regular Expressions Explained"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "The first concept of Regular Expressions are ", <$format, ["i", [], ["branches"], 'do_i]>, ". There can be zero or more ", <$format, ["i", [], ["branches"], 'do_i]>, " in a Regular Expression, seperated by the pipe character (\"|\"). A Regular Expression will match anything in one of the branches. An example of this is:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["this|that|there"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This Regular Expression will match \"this\" OR \"that\" OR \"there\". It is easiest to logically think of branches in this manner. ", <$format, ["np", [], [], 'do_np]>, "A branch is further defined as zero or more ", <$format, ["i", [], ["pieces"], 'do_i]>, " joined together. A ", <$format, ["i", [], ["piece"], 'do_i]>, " is an ", <$format, ["i", [], ["atom"], 'do_i]>, " possibly followed by an asterisk, a plus sign, or a question mark (\"*\", \"+\", or \"?\"). The asterisk, plus sign, or question mark defines how to match the atom. An atom followed by an asterisk matches zero or more occurances of the atom. An atom followed by a plus sign matches one or more occurances of the atom. An atom followed by a question mark matches zero or one occurance of the atom. ", <$format, ["np", [], [], 'do_np]>, "An ", <$format, ["i", [], ["atom"], 'do_i]>, " is either a Regular Expression Group or Range (see below), or one of the following: a period (\".\"), a carat (\"^\"), a dollar sign (\"$\"), a back-slash (\"\\\") followed by a single character, or a single character with no other significance. A period matches any single character in the input text, a carat matches the beginning of the input text, a dollar-sign matches the end of the input text, and a back-slash followed by a single character either has special significance--such as matching all white space or all digits--or it removes special significance from the following character. For instance, \"$\" would match a dollar-sign in the input text, rather than matching the end of the line (which is what the dollar-sign usually does). ", <$format, ["np", [], [], 'do_np]>, "A Group is anything enclosed within a set of parenthesis (", <$format, ["tt", [], ["\"()\""], 'do_tt]>, "). Groups will help to clarify how the Regular Expression should match, in addition to what results should be returned from the Regular Expression. If one or more groups exist, the result of the regular expression will include the groups, possibly in addition to the entire area matched in the string (what is returned will depend upon the function). ", <$format, ["np", [], [], 'do_np]>, "A range is a sequence of characters enclosed in square brackets (", <$format, ["tt", [], ["\"[]\""], 'do_tt]>, "). It normally matches any single character contained within the range sequence. Characters which normally have special significance (such as a dollar-sign, period and a back-slash) loose that significance when enclosed in a range. However, a range has its own special characters. If the range begins with a carat (", <$format, ["tt", [], ["\"^\""], 'do_tt]>, "), it matches any single character which is ", <$format, ["i", [], ["not"], 'do_i]>, " in the sequence. If two characters in the sequence are separated by a dash (", <$format, ["tt", [], ["\"-\""], 'do_tt]>, "), the full range of ASCII characters between the two are matched, including the two. For instance, ", <$format, ["tt", [], ["\"[0-9]\""], 'do_tt]>, " matches any single decimal digit from zero to nine. To include a literal square bracket (", <$format, ["tt", [], ["\"]\""], 'do_tt]>, ") in the sequence do not use the back-slash to escape it (as the back-slash does not have special meaning when in a range), instead place it at the begining of the range (following a possible ", <$format, ["tt", [], ["\"^\""], 'do_tt]>, "). To include a literal dash (", <$format, ["tt", [], ["\"-\""], 'do_tt]>, ") place it the start or end of the range. ", <$format, ["np", [], [], 'do_np]>, "Consider the following examples: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "50%,50%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["a?"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Match zero or one 'a' characters"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["(this|that)*"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Match zero or more occurances of \"this\" or \"that\""], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["[a-z]+"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Match one or more occurances of any alphabetic character (a through z)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["[^0-9]?"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Match zero or one occurance of any non-digit character"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The following characters have special meaning when matching (similar to PERL Regular Expressions): ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "10%,90%"]], [<$format, ["tr", [], [<$format, ["td", [], ["\"\w\""], 'do_td]>, <$format, ["td", [], ["Match a word word character (alphanumeric plus \"_\")"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["\"\W\""], 'do_td]>, <$format, ["td", [], ["Match a non-word character"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["\"\s\""], 'do_td]>, <$format, ["td", [], ["Match a whitespace character"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["\"\S\""], 'do_td]>, <$format, ["td", [], ["Match a non-whitespace character"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["\"\d\""], 'do_td]>, <$format, ["td", [], ["Match a digit character"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["\"\D\""], 'do_td]>, <$format, ["td", [], ["Match a non-digit character"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, <$format, ["i", [], ["Note: the above escape characters have not yet been integrated into the regular expression matcher."], 'do_i]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_coldc_regexp];
var $help_node nolist = 0;


new object $help_coldc_files: $help_coldc_imp;

var $root manager = $help_coldc_files;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058124;
var $has_name name = ['prop, "Files", "Files"];
var $help_node links = #[["execute()", $help_func_execute], ["fchmod()", $help_func_fchmod], ["fclose()", $help_func_fclose], ["feof()", $help_func_feof], ["fflush()", $help_func_fflush], ["file()", $help_func_file], ["files()", $help_func_files], ["fmkdir()", $help_func_fmkdir], ["fopen()", $help_func_fopen], ["frmdir()", $help_func_frmdir], ["fstat()", $help_func_fstat], ["fread()", $help_func_fread], ["fremove()", $help_func_fremove], ["frename()", $help_func_frename], ["fseek()", $help_func_fseek], ["fwrite()", $help_func_fwrite]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdC gives the ability to handle files with the following functions: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "25%,25%,25%,25%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_execute"]], ["execute()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fchmod"]], ["fchmod()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fclose"]], ["fclose()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_feof"]], ["feof()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fflush"]], ["fflush()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_file"]], ["file()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_files"]], ["files()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fmkdir"]], ["fmkdir()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fopen"]], ["fopen()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_frmdir"]], ["frmdir()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fstat"]], ["fstat()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fread"]], ["fread()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fremove"]], ["fremove()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_frename"]], ["frename()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fseek"]], ["fseek()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fwrite"]], ["fwrite()"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When a file is opened it is associated (i.e. bound) with the current object. Therefore, most file functions assume there is a file associated with the current object when used (such as ", <$format, ["tt", [], ["fwrite()"], 'do_tt]>, "). If there is not a file, the error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "If the driver was compiled with ", <$format, ["tt", [], ["RESTRICTIVE_FILES"], 'do_tt]>, ", the driver will restrict where on the filesystem files can be manipulated (usually the ", <$format, ["tt", [], ["./root"], 'do_tt]>, " directory, with the exception of the function ", <$format, ["tt", [], ["execute()"], 'do_tt]>, ", which will use the directory ", <$format, ["tt", [], ["./dbbin"], 'do_tt]>, ". More information on where the directories are given in the ", <$format, ["a", [["href", "http\://www.cold.org/Genesis/"]], ["Genesis Manual"], 'do_a]>, "). ", <$format, ["np", [], [], 'do_np]>, "A file is opened using the function ", <$format, ["tt", [], ["fopen()"], 'do_tt]>, ", and is closed using the function ", <$format, ["tt", [], ["fclose()"], 'do_tt]>, ". Reaching the end of a file will not close it. Destroying the object for a file will close the file. ", <$format, ["np", [], [], 'do_np]>, "Example of opening, writing to and closing a simple text logfile:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["fopen(\"log\");\nfwrite(\"[\" + $time.format(\"%d %b %y %H:%M\") + \"] \" + message);\nfclose();"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Example of reading an image file:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["stat = fopen(\"image.gif\", \"-\");\nbuffer = fread(stat[2]);\nfclose();"], 'do_quote]>], 'do_dfn]>], #[['this, $help_coldc_files]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_files];
var $help_node nolist = 0;


new object $help_coldc_textdump: $help_coldc;

var $root manager = $help_coldc_textdump;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854926711;
var $has_name name = ['prop, "Textdump", "Textdump"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[['this, $help_coldc_textdump]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_textdump];
var $help_node nolist = 0;


new object $help_coldc_func: $help_coldc;

var $root manager = $help_coldc_func;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058130;
var $has_name name = ['prop, "Functions", "Functions"];
var $help_node links = #[["Buffer", $help_funcs_buf], ["Data", $help_funcs_data], ["Dictionary", $help_funcs_dict], ["Error", $help_funcs_err], ["File", $help_funcs_file], ["List", $help_funcs_list], ["Method", $help_funcs_meth], ["Misc", $help_funcs_misc], ["Network", $help_funcs_net], ["Numeric", $help_funcs_num], ["Object", $help_funcs_obj], ["String", $help_funcs_str], ["System", $help_funcs_sys], ["Task", $help_funcs_task], ["Variable", $help_funcs_var]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "18%,18%,18%,18%,18%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_buf"]], ["Buffer"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_data"]], ["Data"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_dict"]], ["Dictionary"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_err"]], ["Error"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_file"]], ["File"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_list"]], ["List"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_meth"]], ["Method"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_misc"]], ["Misc"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_net"]], ["Network"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_num"]], ["Numeric"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_obj"]], ["Object"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_str"]], ["String"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_sys"]], ["System"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_task"]], ["Task"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_var"]], ["Variable"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_coldc_func]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_func];
var $help_node nolist = 0;

public method .generate_body() {
    var k, out, funcs, max, cols, col, x, f, fdict;
    
    (definer() == sender()) || (> .perms(sender()) <);
    if ((this() != definer()) && (!(definer() in parents())))
        throw(~ack, "Don't run this on " + this());
    if (this() == definer()) {
        for k in (children())
            k.generate_body();
    }
    out = "";
    funcs = children();
    fdict = #[];
    for f in (funcs) {
        for x in ((f.name()).explode("|"))
            fdict = dict_add(fdict, x, f);
    }
    funcs = (fdict.keys()).sort();
    max = ((fdict.keys()).element_maxlength()) + 4;
    cols = 75 / max;
    if (cols < 1)
        throw(~type, (("Columns are less than one: " + cols) + " ") + max);
    col = toint((max / 75.0) * 100) + "%";
    out += "{table cols=" + col;
    if (cols > 1)
        out += ("," + col) * (cols - 1);
    out += ":";
    while (funcs) {
        refresh();
        out += "{tr:";
        for x in [1 .. cols] {
            out += "{td:";
            if (funcs) {
                f = funcs[1];
                funcs = delete(funcs, 1);
                out += ((("{link node=" + (fdict[f])) + ":") + f) + "}";
            }
            out += "}";
        }
        out += "}";
    }
    out += "}";
    .set_body(out);
};


new object $help_funcs_var: $help_coldc_func;

var $root manager = $help_funcs_var;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384020;
var $has_name name = ['prop, "Variable", "Variable"];
var $help_node links = #[["add_var()", $help_func_add_var], ["clear_var()", $help_func_clear_var], ["del_var()", $help_func_del_var], ["get_var()", $help_func_get_var], ["set_var()", $help_func_set_var], ["variables()", $help_func_variables]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "20%,20%,20%,20%,20%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_add_var"]], ["add_var()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_clear_var"]], ["clear_var()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_del_var"]], ["del_var()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_get_var"]], ["get_var()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_var"]], ["set_var()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_variables"]], ["variables()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_var]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_var];
var $help_node nolist = 0;


new object $help_func_add_var: $help_funcs_var;

var $root manager = $help_func_add_var;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "add_var()", "add_var()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " add_var(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function defines an object variable on the current object. The name of the variable is defined by the symbol ", <$format, ["i", [], ["name"], 'do_i]>, ". If an object variable already exists by the desired name, the error ", <$format, ["tt", [], ["~varexists"], 'do_tt]>, " is thrown. ", <$format, ["tt", [], ["add_var()"], 'do_tt]>, " returns ", <$format, ["tt", [], ["1"], 'do_tt]>, " if it is successful."], #[['this, $help_func_add_var]]]>;
var $root inited = 1;
var $root managed = [$help_func_add_var];
var $help_node nolist = 0;


new object $help_func_clear_var: $help_funcs_var;

var $root manager = $help_func_clear_var;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "clear_var()", "clear_var()"];
var $help_node links = #[["Objects and Variables", $help_coldc_objs_vars]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " clear_var(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function clears the instance of an object variable, on a descendant. The variable specified by ", <$format, ["i", [], ["name"], 'do_i]>, " must be defined on the same ancestor defining the method which is calling ", <$format, ["tt", [], ["clear_var()"], 'do_tt]>, ". If not, the error ", <$format, ["tt", [], ["~varnf"], 'do_tt]>, " is thrown. If this function is not called before an an ancestor is removed, variables defined on that ancestor and set on the current object ", <$format, ["i", [], ["will remain"], 'do_i]>, " (due to encapsulation). This function is also useful in reducing database usage, as a cleared variable takes up no space, where a set variable (even to a value of ", <$format, ["tt", [], ["0"], 'do_tt]>, ") does. Upon successful execution ", <$format, ["tt", [], ["clear_var()"], 'do_tt]>, " returns ", <$format, ["tt", [], ["1"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "See the section ", <$format, ["link", [["node", "$help_coldc_objs_vars"]], ["Objects and Variables"], 'do_link]>, " for more information on the instance of an object variable."], #[['this, $help_func_clear_var]]]>;
var $root inited = 1;
var $root managed = [$help_func_clear_var];
var $help_node nolist = 0;


new object $help_func_del_var: $help_funcs_var;

var $root manager = $help_func_del_var;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "del_var()", "del_var()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " del_var(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function deletes the object variable pointed to by the argument ", <$format, ["i", [], ["name"], 'do_i]>, " defined on the current object (it does not delete an instance of a variable). If the object variable is not defined on the current object, the error ", <$format, ["tt", [], ["~varnf"], 'do_tt]>, " is thrown. Upon successful execution ", <$format, ["tt", [], ["del_var()"], 'do_tt]>, " returns ", <$format, ["tt", [], ["1"], 'do_tt]>, "."], #[['this, $help_func_del_var]]]>;
var $root inited = 1;
var $root managed = [$help_func_del_var];
var $help_node nolist = 0;


new object $help_func_get_var: $help_funcs_var;

var $root manager = $help_func_get_var;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "get_var()", "get_var()"];
var $help_node links = #[["Variable Expressions", $help_coldc_vars]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " get_var(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the current object's instance of the object variable specified to by the argument ", <$format, ["i", [], ["name"], 'do_i]>, ". The variable must be defined on the same object which defined the method which calls ", <$format, ["tt", [], ["get_var()"], 'do_tt]>, ". If the object variable is not defined, the error ", <$format, ["tt", [], ["~varnf"], 'do_tt]>, " is thrown. Otherwise the current object's value for the variable is returned. ", <$format, ["np", [], [], 'do_np]>, "This is an obtuse way of retrieving the value of an object variable, and is generally only used when there is confusion with a local variable. For more information see ", <$format, ["link", [["node", "$help_coldc_vars"]], ["Variable Expressions"], 'do_link]>, "."], #[['this, $help_func_get_var]]]>;
var $root inited = 1;
var $root managed = [$help_func_get_var];
var $help_node nolist = 0;


new object $help_func_set_var: $help_funcs_var;

var $root manager = $help_func_set_var;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "set_var()", "set_var()"];
var $help_node links = #[["assignment operator", $help_coldc_assign]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " set_var(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ", ", <$format, ["i", [], ["ANY value"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function sets the instance of an object variable on the current object. The variable must be defined on the same object which defined the method which calls ", <$format, ["tt", [], ["set_var()"], 'do_tt]>, ". Using this function is the same as using the ", <$format, ["link", [["node", "$help_coldc_assign"]], ["assignment operator"], 'do_link]>, ". If the object variable is not defined, the error ", <$format, ["tt", [], ["~varnf"], 'do_tt]>, " is thrown. The return value for ", <$format, ["tt", [], ["set_var()"], 'do_tt]>, " is the second argument ", <$format, ["tt", [], ["value"], 'do_tt]>, ". The following two examples are equivalent:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["set_var('time_stamp, time())", <$format, ["br", [], [], 'do_br]>, "=> 855723496"], 'do_dfn]>, " ", <$format, ["dfn", [], ["time_stamp = time()"], 'do_dfn]>], #[['this, $help_func_set_var]]]>;
var $root inited = 1;
var $root managed = [$help_func_set_var];
var $help_node nolist = 0;


new object $help_func_variables: $help_funcs_var;

var $root manager = $help_func_variables;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "variables()", "variables()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " variables()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used to determine all of the object variables defined on the current object (not the instances of all variables). A list of symbols naming each variable is returned."], #[['this, $help_func_variables]]]>;
var $root inited = 1;
var $root managed = [$help_func_variables];
var $help_node nolist = 0;


new object $help_funcs_meth: $help_coldc_func;

var $root manager = $help_funcs_meth;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Method", "Method"];
var $help_node links = #[["add_method()", $help_func_add_method], ["del_method()", $help_func_del_method], ["find_method()", $help_func_find_method], ["find_next_method()", $help_func_find_next_method], ["list_method()", $help_func_list_method], ["method_access()", $help_func_method_access], ["method_bytecode()", $help_func_method_bytecode], ["method_flags()", $help_func_method_flags], ["method_info()", $help_func_method_info], ["methods()", $help_func_methods], ["rename_method()", $help_func_rename_method], ["set_method_access()", $help_func_set_method_access], ["set_method_flags()", $help_func_set_method_flags]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "30%,30%,30%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_add_method"]], ["add_method()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_del_method"]], ["del_method()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_find_method"]], ["find_method()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_find_next_method"]], ["find_next_method()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_list_method"]], ["list_method()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_method_access"]], ["method_access()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_method_bytecode"]], ["method_bytecode()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_method_flags"]], ["method_flags()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_method_info"]], ["method_info()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_methods"]], ["methods()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_rename_method"]], ["rename_method()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_method_access"]], ["set_method_access()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_method_flags"]], ["set_method_flags()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_meth]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_meth];
var $help_node nolist = 0;


new object $help_func_add_method: $help_funcs_meth;

var $root manager = $help_func_add_method;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "add_method()", "add_method()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " add_method(", <$format, ["i", [], ["LIST code"], 'do_i]>, ", ", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function compiles ", <$format, ["i", [], ["code"], 'do_i]>, " (which should be a list of strings) and uses the result as the definition of the method named by the symbol ", <$format, ["i", [], ["name"], 'do_i]>, ". If there were errors in compiling, a list of strings describing the errors is returned, otherwise an empty list is returned. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["add_method([\"cwrite(\\\"foo\\\");\"], 'foo)", <$format, ["br", [], [], 'do_br]>, "=> [] ", <$format, ["np", [], [], 'do_np]>, "add_method([\"cwrite(\\\"foo\\\")\"], 'foo)", <$format, ["br", [], [], 'do_br]>, "=> [\"Line 2: parse error\"]"], 'do_tt]>], 'do_dfn]>], #[['this, $help_func_add_method]]]>;
var $root inited = 1;
var $root managed = [$help_func_add_method];
var $help_node nolist = 0;


new object $help_func_list_method: $help_funcs_meth;

var $root manager = $help_func_list_method;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "list_method()", "list_method()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " list_method(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER indent"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER flags"], 'do_i]>, "]])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used to decompile a method. It accepts a symbol, assuming it to be the name of a method. If the method is defined on the current object it is decompiled and returned as a list of strings. If the method is not found, the error ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "The second argument ", <$format, ["i", [], ["indent"], 'do_i]>, " can be given to specify an alternate indentation to use (default is four spaces). The third argument can be specified to change the default formatting behaviour. The argument is an integer which can have three different values:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], ["1"], 'do_dt]>, <$format, ["dd", [], ["Full Parenthesis"], 'do_dd]>, <$format, ["dt", [], ["2"], 'do_dt]>, <$format, ["dd", [], ["Full Braces"], 'do_dd]>, <$format, ["dt", [], ["3"], 'do_dt]>, <$format, ["dd", [], ["Full Parenthesis and Braces"], 'do_dd]>], 'do_dl]>], #[['this, $help_func_list_method]]]>;
var $root inited = 1;
var $root managed = [$help_func_list_method];
var $help_node nolist = 0;


new object $help_func_del_method: $help_funcs_meth;

var $root manager = $help_func_del_method;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "del_method()", "del_method()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " del_method(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function removes the method named by the symbol ", <$format, ["i", [], ["name"], 'do_i]>, " from the current object. ", <$format, ["tt", [], ["del_method()"], 'do_tt]>, " returns ", <$format, ["tt", [], ["1"], 'do_tt]>, " if there was a method named ", <$format, ["i", [], ["name"], 'do_i]>, " on the current object; otherwise, a ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " error is thrown."], #[['this, $help_func_del_method]]]>;
var $root inited = 1;
var $root managed = [$help_func_del_method];
var $help_node nolist = 0;


new object $help_func_find_method: $help_funcs_meth;

var $root manager = $help_func_find_method;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "find_method()", "find_method()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " find_method(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function searches for the first occurance of the method named by the symbol ", <$format, ["i", [], ["name"], 'do_i]>, ", on an ancestor of the current object. If a method is found, the ancestor is returned. Otherwise the error ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " is thrown."], #[['this, $help_func_find_method]]]>;
var $root inited = 1;
var $root managed = [$help_func_find_method];
var $help_node nolist = 0;


new object $help_func_find_next_method: $help_funcs_meth;

var $root manager = $help_func_find_next_method;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "find_next_method()", "find_next_method()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " find_next_method(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ", ", <$format, ["i", [], ["OBJNUM after"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function searches for the occurance of the method named by the symbol ", <$format, ["i", [], ["name"], 'do_i]>, ", after the ancestor ", <$format, ["i", [], ["after"], 'do_i]>, ". If a method is found, the ancestor is returned. Otherwise the error ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " is thrown."], #[['this, $help_func_find_next_method]]]>;
var $root inited = 1;
var $root managed = [$help_func_find_next_method];
var $help_node nolist = 0;


new object $help_func_method_bytecode: $help_funcs_meth;

var $root manager = $help_func_method_bytecode;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "method_bytecode()", "method_bytecode()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " method_bytecode(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Returns the bytecode for the specified method, defined on the current object. For instance, consider the following method: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\npublic method .test() {\n    return \"test\";\n};"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Would return the following bytecode:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["method_bytecode('test)", <$format, ["br", [], [], 'do_br]>, "=> ['STRING, \"test\", 'RETURN_EXPR, 'RETURN]"], 'do_dfn]>], #[['this, $help_func_method_bytecode]]]>;
var $root inited = 1;
var $root managed = [$help_func_method_bytecode];
var $help_node nolist = 0;


new object $help_func_method_access: $help_funcs_meth;

var $root manager = $help_func_method_access;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "method_access()", "method_access()"];
var $help_node links = #[["Methods", $help_coldc_methods]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["SYMBOL"], 'do_i]>, " method_access(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the method access for the method specified with the argument ", <$format, ["i", [], ["name"], 'do_i]>, ". See ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Methods"], 'do_link]>, " for more information on method access."], #[['this, $help_func_method_access]]]>;
var $root inited = 1;
var $root managed = [$help_func_method_access];
var $help_node nolist = 0;


new object $help_func_method_flags: $help_funcs_meth;

var $root manager = $help_func_method_flags;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "method_flags()", "method_flags()"];
var $help_node links = #[["Defining Methods", $help_coldc_methods]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " method_flags(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function finds the method specified with the argument ", <$format, ["i", [], ["name"], 'do_i]>, " and returns the list of flags currently set on the method. Method flags are fully explained in the section on ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, ". If the method ", <$format, ["i", [], ["name"], 'do_i]>, " cannot be found, the error ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " is thrown."], #[['this, $help_func_method_flags]]]>;
var $root inited = 1;
var $root managed = [$help_func_method_flags];
var $help_node nolist = 0;


new object $help_func_method_info: $help_funcs_meth;

var $root manager = $help_func_method_info;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "method_info()", "method_info()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " method_info(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a list of miscellaneous information on the method named by ", <$format, ["i", [], ["name"], 'do_i]>, ". If the method is not found, the error ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " is thrown. Otherwise a list is returned. The elements in the list are (in order):", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["STRING args"], 'do_li]>, <$format, ["li", [], ["INTEGER number of arguments"], 'do_li]>, <$format, ["li", [], ["INTEGER number of local variables defined"], 'do_li]>, <$format, ["li", [], ["INTEGER number of opcodes used"], 'do_li]>, <$format, ["li", [], ["SYMBOL method access"], 'do_li]>, <$format, ["li", [], ["LIST method flags"], 'do_li]>], 'do_ol]>], #[['this, $help_func_method_info]]]>;
var $root inited = 1;
var $root managed = [$help_func_method_info];
var $help_node nolist = 0;


new object $help_func_methods: $help_funcs_meth;

var $root manager = $help_func_methods;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "methods()", "methods()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " methods()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a list of symbols naming each method defined on the current object."], #[['this, $help_func_methods]]]>;
var $root inited = 1;
var $root managed = [$help_func_methods];
var $help_node nolist = 0;


new object $help_func_rename_method: $help_funcs_meth;

var $root manager = $help_func_rename_method;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "rename_method()", "rename_method()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " rename_method(", <$format, ["i", [], ["SYMBOL old_name"], 'do_i]>, ", ", <$format, ["i", [], ["SYMBOL new_name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function changes the name of the method on the current object, specified by the argument ", <$format, ["i", [], ["old_name"], 'do_i]>, ", and changes it to the name specified by the argument ", <$format, ["i", [], ["new_name"], 'do_i]>, ". If no method can be found by the name ", <$format, ["i", [], ["old_name"], 'do_i]>, ", the error ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " is thrown."], #[['this, $help_func_rename_method]]]>;
var $root inited = 1;
var $root managed = [$help_func_rename_method];
var $help_node nolist = 0;


new object $help_func_set_method_access: $help_funcs_meth;

var $root manager = $help_func_set_method_access;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "set_method_access()", "set_method_access()"];
var $help_node links = #[["Methods", $help_coldc_methods]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " set_method_access(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ", ", <$format, ["i", [], ["SYMBOL access"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function sets the method access for the method ", <$format, ["i", [], ["name"], 'do_i]>, ". See ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Methods"], 'do_link]>, " for more information on method access."], #[['this, $help_func_set_method_access]]]>;
var $root inited = 1;
var $root managed = [$help_func_set_method_access];
var $help_node nolist = 0;


new object $help_func_set_method_flags: $help_funcs_meth;

var $root manager = $help_func_set_method_flags;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "set_method_flags()", "set_method_flags()"];
var $help_node links = #[["Method Flags", $help_coldc_methods_flags]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " set_method_flags(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ", ", <$format, ["i", [], ["LIST flags"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function sets the method flags for the method specified with the first argument ", <$format, ["i", [], ["name"], 'do_i]>, ". The flags are specified as a list of symbols in ", <$format, ["i", [], ["flags"], 'do_i]>, ". Full information on method flags can be found in the section ", <$format, ["link", [["node", "$help_coldc_methods_flags"]], ["Method Flags"], 'do_link]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["set_method_flags('tell, ['nooverride])", <$format, ["br", [], [], 'do_br]>, "=> 1"], 'do_dfn]>], #[['this, $help_func_set_method_flags]]]>;
var $root inited = 1;
var $root managed = [$help_func_set_method_flags];
var $help_node nolist = 0;


new object $help_funcs_obj: $help_coldc_func;

var $root manager = $help_funcs_obj;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Object", "Object"];
var $help_node links = #[["ancestors()", $help_func_ancestors], ["children()", $help_func_children], ["chparents()", $help_func_chparents], ["create()", $help_func_create], ["data()", $help_func_data], ["del_objname()", $help_func_del_objname], ["destroy()", $help_func_destroy], ["has_ancestor()", $help_func_has_ancestor], ["lookup()", $help_func_lookup], ["objname()", $help_func_objname], ["objnum()", $help_func_objnum], ["parents()", $help_func_parents], ["set_objname()", $help_func_set_objname]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "24%,24%,24%,24%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_ancestors"]], ["ancestors()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_children"]], ["children()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_chparents"]], ["chparents()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_create"]], ["create()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_data"]], ["data()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_del_objname"]], ["del_objname()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_destroy"]], ["destroy()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_has_ancestor"]], ["has_ancestor()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_lookup"]], ["lookup()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_objname"]], ["objname()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_objnum"]], ["objnum()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_parents"]], ["parents()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_objname"]], ["set_objname()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['links, #[["ancestors()", "$help_func_ancestors"], ["children()", "$help_func_children"], ["chparents()", "$help_func_chparents"], ["create()", "$help_func_create"], ["data()", "$help_func_data"], ["del_objname()", "$help_func_del_objname"], ["destroy()", "$help_func_destroy"], ["has_ancestor()", "$help_func_has_ancestor"], ["lookup()", "$help_func_lookup"], ["objname()", "$help_func_objname"], ["objnum()", "$help_func_objnum"], ["parents()", "$help_func_parents"], ["set_objname()", "$help_func_set_objname"]]]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_obj];
var $help_node nolist = 0;


new object $help_func_ancestors: $help_funcs_obj;

var $root manager = $help_func_ancestors;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "ancestors()", "ancestors()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " ancestors([", <$format, ["i", [], ["SYMBOL order"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a list of the ancestors of the current object. The order of the list is specified by sending either ", <$format, ["tt", [], ["'depth"], 'do_tt]>, " or ", <$format, ["tt", [], ["'breadth"], 'do_tt]>, " (for a depth-first or breadth-first order, respectively). If no order is specified, the order is depth-first (similar to methods). The current object is always the first element in this list. The heirarchy:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["    $root\n    /   \\\\\n$obj_a   |\n   |     |\n$obj_b $obj_c\n    \\\   /\n   $obj_d"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Is used in the following examples, as called from ", <$format, ["tt", [], ["$obj_d"], 'do_tt]>, ":", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["ancestors()", <$format, ["br", [], [], 'do_br]>, "=> [$obj_d, $obj_b, $obj_a, $obj_c, $root]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["ancestors('breadth)", <$format, ["br", [], [], 'do_br]>, "=> [$obj_d, $obj_b, $obj_c, $obj_a, $root]"], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_func_ancestors];
var $help_node nolist = 0;


new object $help_func_children: $help_funcs_obj;

var $root manager = $help_func_children;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "children()", "children()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " children()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a list of object numbers for the children of the current object, in no particular order."], #[['this, $help_func_children]]]>;
var $root inited = 1;
var $root managed = [$help_func_children];
var $help_node nolist = 0;


new object $help_func_chparents: $help_funcs_obj;

var $root manager = $help_func_chparents;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "chparents()", "chparents()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " chparents(", <$format, ["i", [], ["LIST parents"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function changes the parents of the current object to the list of objnums in ", <$format, ["i", [], ["parents"], 'do_i]>, ". If any of the objnums in ", <$format, ["i", [], ["parents"], 'do_i]>, " do not refer to an existing object, then the error ", <$format, ["tt", [], ["~objnf"], 'do_tt]>, " is thrown. If any of the parents have the current object as an ancestor, or are the current object, then the error ", <$format, ["tt", [], ["~parent"], 'do_tt]>, " is thrown. If ", <$format, ["i", [], ["parents"], 'do_i]>, " is an empty list, then ", <$format, ["tt", [], ["~perm"], 'do_tt]>, " is thrown. Otherwise a ", <$format, ["tt", [], ["1"], 'do_tt]>, " is returned."], #[['this, $help_func_chparents]]]>;
var $root inited = 1;
var $root managed = [$help_func_chparents];
var $help_node nolist = 0;


new object $help_func_create: $help_funcs_obj;

var $root manager = $help_func_create;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "create()", "create()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " create(", <$format, ["i", [], ["LIST parents"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function creates and returns the objnum of an object with the parents in the list ", <$format, ["i", [], ["parents"], 'do_i]>, ", which should be a list of objnums referring to existing objects. If any of the parent objnums do not refer to existing objects, then ", <$format, ["tt", [], ["create()"], 'do_tt]>, " throws the error ", <$format, ["tt", [], ["~objnf"], 'do_tt]>, "."], #[['this, $help_func_create]]]>;
var $root inited = 1;
var $root managed = [$help_func_create];
var $help_node nolist = 0;


new object $help_func_data: $help_funcs_obj;

var $root manager = $help_func_data;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "data()", "data()"];
var $help_node links = #[["clear_var()", $help_func_clear_var]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["DICTIONARY"], 'do_i]>, " data([", <$format, ["i", [], ["OBJNUM ancestor"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This administrative function is used to retrieve all instances of object variables the current object has, as well as the values of any object variable they define. If ", <$format, ["i", [], ["ancestor"], 'do_i]>, " is not defined it will return ", <$format, ["i", [], ["all"], 'do_i]>, " instances defined by any ancestor. If ", <$format, ["i", [], ["ancestor"], 'do_i]>, " is defined it will only return data which is defined by the specific ancestor. ", <$format, ["np", [], [], 'do_np]>, "The data is returned in a dictionary, where each object variable is a key and the association to the key is the value for the object variable. If no ancestor is specified and all instances are returned, each ancestor's values are contained within another dictionary, where the key is the ancestor. ", <$format, ["np", [], [], 'do_np]>, "If an ancestor defines an object variable, but no instance of that variable has been created for the current object (or the instance has been cleared with the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_clear_var"]], ["clear_var()"], 'do_link]>], 'do_tt]>, "), it is not included in the dictionary. ", <$format, ["np", [], [], 'do_np]>, "The keys in a dictionary returned by ", <$format, ["tt", [], ["data()"], 'do_tt]>, " do not have any particular ordering."], #[['this, $help_func_data]]]>;
var $root inited = 1;
var $root managed = [$help_func_data];
var $help_node nolist = 0;


new object $help_func_del_objname: $help_funcs_obj;

var $root manager = $help_func_del_objname;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "del_objname()", "del_objname()"];
var $help_node links = #[["Referencing Objects", $help_coldc_objs_ref]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " del_objname()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function deletes an objname associated with the current object. When an objname is deleted the object may only be referenced with it's objnum (for more information on objnames and objnums read ", <$format, ["link", [["node", "$help_coldc_objs_ref"]], ["Referencing Objects"], 'do_link]>, "). If the current object does not have an objname, the error ", <$format, ["tt", [], ["~namenf"], 'do_tt]>, " is thrown."], #[['this, $help_func_del_objname]]]>;
var $root inited = 1;
var $root managed = [$help_func_del_objname];
var $help_node nolist = 0;


new object $help_func_destroy: $help_funcs_obj;

var $root manager = $help_func_destroy;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "destroy()", "destroy()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " destroy()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function marks the current object for removal from the database. The object is destroyed when all methods executing on it are completed (suspended and preempted methods as well as the current task). Objects left orphaned by the destruction of their only parent are reparented to the parents of the parent which was destroyed. ", <$format, ["np", [], [], 'do_np]>, "Attempts to destroy the root or system objects will fail with the error ", <$format, ["tt", [], ["~perm"], 'do_tt]>, "."], #[['this, $help_func_destroy]]]>;
var $root inited = 1;
var $root managed = [$help_func_destroy];
var $help_node nolist = 0;


new object $help_func_has_ancestor: $help_funcs_obj;

var $root manager = $help_func_has_ancestor;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "has_ancestor()", "has_ancestor()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " has_ancestor(", <$format, ["i", [], ["OBJNUM ancestor"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns one (1) if the current object has ", <$format, ["i", [], ["ancestor"], 'do_i]>, " as an ancestor, or zero (0) if it does not."], #[['this, $help_func_has_ancestor]]]>;
var $root inited = 1;
var $root managed = [$help_func_has_ancestor];
var $help_node nolist = 0;


new object $help_func_lookup: $help_funcs_obj;

var $root manager = $help_func_lookup;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "lookup()", "lookup()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " lookup(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function finds the object number for the object name specified by the argument ", <$format, ["i", [], ["name"], 'do_i]>, ". If no object exists with that name, the error ", <$format, ["tt", [], ["~namenf"], 'do_tt]>, " is thrown. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["lookup('root)", <$format, ["br", [], [], 'do_br]>, "=> #1"], 'do_dfn]>], #[['this, $help_func_lookup]]]>;
var $root inited = 1;
var $root managed = [$help_func_lookup];
var $help_node nolist = 0;


new object $help_func_objname: $help_funcs_obj;

var $root manager = $help_func_objname;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "objname()", "objname()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["SYMBOL"], 'do_i]>, " objname()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the symbol representation of the current object's name. If the current object does not have an object name assigned, this function throws the error ", <$format, ["tt", [], ["~namenf"], 'do_tt]>, "."], #[['this, $help_func_objname]]]>;
var $root inited = 1;
var $root managed = [$help_func_objname];
var $help_node nolist = 0;


new object $help_func_objnum: $help_funcs_obj;

var $root manager = $help_func_objnum;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "objnum()", "objnum()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " objnum()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns an integer representing the current object's object number."], #[['this, $help_func_objnum]]]>;
var $root inited = 1;
var $root managed = [$help_func_objnum];
var $help_node nolist = 0;


new object $help_func_parents: $help_funcs_obj;

var $root manager = $help_func_parents;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "parents()", "parents()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " parents()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a list of the objnums for the parents of the current object."], #[['this, $help_func_parents]]]>;
var $root inited = 1;
var $root managed = [$help_func_parents];
var $help_node nolist = 0;


new object $help_func_set_objname: $help_funcs_obj;

var $root manager = $help_func_set_objname;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "set_objname()", "set_objname()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " set_objname(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function sets the argument ", <$format, ["i", [], ["name"], 'do_i]>, " as the current object's objname. If another object already has the object name ", <$format, ["i", [], ["name"], 'do_i]>, ", the error ", <$format, ["tt", [], ["~error"], 'do_tt]>, " is thrown. If the current object already has an object name, it is replaced with the new name. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["set_objname('user_bob)", <$format, ["br", [], [], 'do_br]>, "=> 1"], 'do_dfn]>], #[['this, $help_func_set_objname]]]>;
var $root inited = 1;
var $root managed = [$help_func_set_objname];
var $help_node nolist = 0;


new object $help_funcs_sys: $help_coldc_func;

var $root manager = $help_funcs_sys;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "System", "System"];
var $help_node links = #[["anticipate_assignment()", $help_func_anticipate_assignment], ["backup()", $help_func_backup], ["cache_info()", $help_func_cache_info], ["config()", $help_func_config], ["set_heartbeat()", $help_func_set_heartbeat], ["shutdown()", $help_func_shutdown]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "36%,36%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_anticipate_assignment"]], ["anticipate_assignment()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_backup"]], ["backup()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_cache_info"]], ["cache_info()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_config"]], ["config()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_heartbeat"]], ["set_heartbeat()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_shutdown"]], ["shutdown()"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], #[['links, #[["anticipate_assignment()", "$help_func_anticipate_assignment"], ["backup()", "$help_func_backup"], ["cache_info()", "$help_func_cache_info"], ["config()", "$help_func_config"], ["set_heartbeat()", "$help_func_set_heartbeat"], ["shutdown()", "$help_func_shutdown"]]]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_sys];
var $help_node nolist = 0;


new object $help_func_backup: $help_funcs_sys;

var $root manager = $help_func_backup;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "backup()", "backup()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " backup()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function synchronizes the running database to disk and starts an asyncrynous backup (Genesis copies the files to the file ", <$format, ["i", [], ["binary"], 'do_i]>, ".bak, where ", <$format, ["i", [], ["binary"], 'do_i]>, " is the binary database directory name specified upon bootup). This function executes atomically, and a slight pause may be noticed while it synchronizes the object cache to disk and copies the index files. ", <$format, ["np", [], [], 'do_np]>, "The return value of ", <$format, ["tt", [], ["backup()"], 'do_tt]>, " is always ", <$format, ["tt", [], ["1"], 'do_tt]>, ", and should be ignored. If a backup is in progress the error ", <$format, ["tt", [], ["~perm"], 'do_tt]>, " is thrown. The error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown if there are file or directory problems. When the asyncrynous backup is finished the driver calls ", <$format, ["tt", [], ["$sys.backup_done()"], 'do_tt]>, "."], #[]]>;
var $root inited = 1;
var $root managed = [$help_func_backup];
var $help_node nolist = 0;


new object $help_func_set_heartbeat: $help_funcs_sys;

var $root manager = $help_func_set_heartbeat;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "set_heartbeat()", "set_heartbeat()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " set_heartbeat(", <$format, ["i", [], ["INTEGER interval"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function sets the periodic global heartbeat for the database to the argument ", <$format, ["i", [], ["interval"], 'do_i]>, ", where ", <$format, ["i", [], ["interval"], 'do_i]>, " is in the delay in seconds. The heartbeat can be disabled by setting the interval to zero or a negative number. The default heartbeat interval is five seconds. The heartbeat is sent by the driver calling the method ", <$format, ["tt", [], ["$sys.heartbeat()"], 'do_tt]>, "."], #[]]>;
var $root inited = 1;
var $root managed = [$help_func_set_heartbeat];
var $help_node nolist = 0;


new object $help_func_shutdown: $help_funcs_sys;

var $root manager = $help_func_shutdown;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855385300;
var $root managed = [$help_func_shutdown];
var $has_name name = ['prop, "shutdown()", "shutdown()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " shutdown()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function completes all of the current tasks, syncronizes the database, flushes all output and shuts down the server."], #[['this, $help_func_shutdown]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_anticipate_assignment: $help_funcs_sys;

var $root manager = $help_func_anticipate_assignment;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855388597;
var $root managed = [$help_func_anticipate_assignment];
var $has_name name = ['prop, "anticipate_assignment()", "anticipate_assignment()"];
var $help_node links = #[["Errors", $help_coldc_errors]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " anticipate_assignment()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Do not use this unless you know exactly what you are doing, and how stacks and frames work in the ColdC driver. ", <$format, ["np", [], [], 'do_np]>, "This function is used to reduce the amount of references to data on the stack, in order to keep from unecessarily copying data. It does this by breaking encapsulation and looking at the calling frame's execution stack. If an assignment will be made to data passed as an argument, as a result of the current method's return--the variable is cleared of any references before the data is modified in the current frame. ", <$format, ["np", [], [], 'do_np]>, "Because of how this works be careful to only call anticipate_assignment() after any ", <$format, ["link", [["node", "$help_coldc_errors"]], ["Errors"], 'do_link]>, " are thrown. Any errors thrown after this function is called will have the potential of losing data in the calling method."], #[['links, #[["Errors", "$help_coldc_errors"]]]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_config: $help_funcs_sys;

var $root manager = $help_func_config;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855429715;
var $root managed = [$help_func_config];
var $has_name name = ['prop, "config()", "config()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " config(", <$format, ["i", [], ["SYMBOL what"], 'do_i]>, "[, ", <$format, ["i", [], ["ANY value"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This administrative function is used to change run-time values for the driver and execution states. Current Genesis only partially implements this function--it recognizes the changes but does not fully comply with them. The value is specified with the argument ", <$format, ["i", [], ["what"], 'do_i]>, ". If no second argument is given the current value is returned. If a second argument is given, the value is set to that value, if appropriate--if the new value is inappropriate the error ", <$format, ["tt", [], ["~type"], 'do_tt]>, " is thrown. Values are: ", <$format, ["dfn", [["nobound", 1]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], ["'datasize"], 'do_td]>, <$format, ["td", [], ["Maximum Data Size (in bytes)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["'forkdepth"], 'do_td]>, <$format, ["td", [], ["Maximum fork depth"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["'calldepth"], 'do_td]>, <$format, ["td", [], ["Maximum call depth"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["'recursion"], 'do_td]>, <$format, ["td", [], ["Maximum Swapping"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["'objswap"], 'do_td]>, <$format, ["td", [], ["Object Swapping"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['this, $help_func_config]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_cache_info: $help_funcs_sys;

var $root manager = $help_func_cache_info;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 879897889;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "cache_info()", "cache_info()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " cache_info()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This administrative function returns a visual map of the active memory cache for database objects. The list returned will have three elements, where each element is:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["Cache Width (INT)"], 'do_li]>, <$format, ["li", [], ["Cache Depth (INT)"], 'do_li]>, <$format, ["li", [], ["Cache Map (LIST)"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "The Cache Map is a list of strings containing a single character entry for each point in the cache (where the list is ", <$format, ["i", [], ["width"], 'do_i]>, " wide, and there are ", <$format, ["i", [], ["depth"], 'do_i]>, "). The characters can be a lower or uppercase ", <$format, ["tt", [], ["i"], 'do_tt]>, " or ", <$format, ["tt", [], ["a"], 'do_tt]>, ". The character ", <$format, ["tt", [], ["a"], 'do_tt]>, " refers to active objects and the character ", <$format, ["tt", [], ["i"], 'do_tt]>, " refers to inactive objects. If it is capitalized, the object is marked dirty."], #[]]>;
var $root inited = 1;
var $root managed = [$help_func_cache_info];


new object $help_funcs_task: $help_coldc_func;

var $root manager = $help_funcs_task;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Task", "Task"];
var $help_node links = #[["atomic()", $help_func_atomic], ["call_trace()", $help_func_call_trace], ["caller()", $help_func_caller], ["cancel()", $help_func_cancel], ["debug_callers()", $help_func_debug_callers], ["definer()", $help_func_definer], ["method()", $help_func_method], ["pass()", $help_func_pass], ["pause()", $help_func_pause], ["refresh()", $help_func_refresh], ["resume()", $help_func_resume], ["sender()", $help_func_sender], ["set_user()", $help_func_set_user], ["stack()", $help_func_stack], ["suspend()", $help_func_suspend], ["task_id()", $help_func_task_id], ["task_info()", $help_func_task_info], ["tasks()", $help_func_tasks], ["this()", $help_func_this], ["tick()", $help_func_tick], ["ticks_left()", $help_func_ticks_left], ["user()", $help_func_user]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "25%,25%,25%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_atomic"]], ["atomic()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_call_trace"]], ["call_trace()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_caller"]], ["caller()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_cancel"]], ["cancel()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_debug_callers"]], ["debug_callers()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_definer"]], ["definer()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_method"]], ["method()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_pass"]], ["pass()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_pause"]], ["pause()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_refresh"]], ["refresh()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_resume"]], ["resume()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_sender"]], ["sender()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_user"]], ["set_user()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_stack"]], ["stack()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_suspend"]], ["suspend()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_task_id"]], ["task_id()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_task_info"]], ["task_info()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_tasks"]], ["tasks()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_this"]], ["this()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_tick"]], ["tick()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_ticks_left"]], ["ticks_left()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_user"]], ["user()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_task]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_task];
var $help_node nolist = 0;


new object $help_func_atomic: $help_funcs_task;

var $root manager = $help_func_atomic;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "atomic()", "atomic()"];
var $help_node links = #[["refresh()", $help_func_refresh], ["Frames and Tasks", $help_coldc_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " atomic(", <$format, ["i", [], ["INTEGER goatomic"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used to turn on and off atomic execution. When executing atomically ", <$format, ["i", [], ["no other tasks will be run"], 'do_i]>, ". This also means that any function that normally preempts will throw an error (with the exception of ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_refresh"]], ["refresh()"], 'do_link]>], 'do_tt]>, "). If the argument is false (zero) the interpreter stops executing atomically. If the argument is true (non-zero) the interpreter starts executing atomically. Note: ", <$format, ["i", [], ["read the section ", <$format, ["link", [["node", "$help_coldc_tasks"]], ["Frames and Tasks"], 'do_link]>], 'do_i]>, " before using ", <$format, ["tt", [], ["atomic()"], 'do_tt]>, "."], #[['this, $help_func_atomic]]]>;
var $root inited = 1;
var $root managed = [$help_func_atomic];
var $help_node nolist = 0;


new object $help_func_caller: $help_funcs_task;

var $root manager = $help_func_caller;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "caller()", "caller()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " caller()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the objnum of the object which defines the method which called the current method. If the current method was called by the driver zero (0) is returned instead."], #[['this, $help_func_caller]]]>;
var $root inited = 1;
var $root managed = [$help_func_caller];
var $help_node nolist = 0;


new object $help_func_cancel: $help_funcs_task;

var $root manager = $help_func_cancel;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "cancel()", "cancel()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " cancel(", <$format, ["i", [], ["INTEGER task_id"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function cancels the suspended or preempted task with the task id given by ", <$format, ["i", [], ["task_id"], 'do_i]>, ". If the task does not exist, ", <$format, ["tt", [], ["~type"], 'do_tt]>, " is thrown."], #[['this, $help_func_cancel]]]>;
var $root inited = 1;
var $root managed = [$help_func_cancel];
var $help_node nolist = 0;


new object $help_func_definer: $help_funcs_task;

var $root manager = $help_func_definer;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "definer()", "definer()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " definer()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the objnum of the object which defines the current method."], #[['this, $help_func_definer]]]>;
var $root inited = 1;
var $root managed = [$help_func_definer];
var $help_node nolist = 0;


new object $help_func_method: $help_funcs_task;

var $root manager = $help_func_method;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "method()", "method()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["SYMBOL"], 'do_i]>, " method()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the name of the current method, as a symbol."], #[['this, $help_func_method]]]>;
var $root inited = 1;
var $root managed = [$help_func_method];
var $help_node nolist = 0;


new object $help_func_pause: $help_funcs_task;

var $root manager = $help_func_pause;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "pause()", "pause()"];
var $help_node links = #[["Frames and Tasks", $help_coldc_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " pause()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function instantly preempts the current task, letting other tasks execute before it resumes execution with a refreshed tick count. See ", <$format, ["link", [["node", "$help_coldc_tasks"]], ["Frames and Tasks"], 'do_link]>, " for more information on preempting and task control."], #[['this, $help_func_pause]]]>;
var $root inited = 1;
var $root managed = [$help_func_pause];
var $help_node nolist = 0;


new object $help_func_refresh: $help_funcs_task;

var $root manager = $help_func_refresh;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "refresh()", "refresh()"];
var $help_node links = #[["pause()", $help_func_pause], ["Frames and Tasks", $help_func_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " refresh()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When the server is running non-atomically this function checks the current frame's tick count and preempts the task if it is nearly depleted (similar to ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_pause"]], ["pause()"], 'do_link]>], 'do_tt]>, "), resuming it with a new tick count after all other current tasks have completed, otherwise it does nothing. If the server is running atomically the task will not preempt, but the tick count will automatically be refreshed. See ", <$format, ["link", [["node", "$help_func_tasks"]], ["Frames and Tasks"], 'do_link]>, " for more information on task preempting."], #[['this, $help_func_refresh]]]>;
var $root inited = 1;
var $root managed = [$help_func_refresh];
var $help_node nolist = 0;


new object $help_func_resume: $help_funcs_task;

var $root manager = $help_func_resume;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "resume()", "resume()"];
var $help_node links = #[["suspend()", $help_func_suspend], ["Frames and Tasks", $help_coldc_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], ["INTEGER resume(", <$format, ["i", [], ["INTEGER task_id"], 'do_i]>, "[, ", <$format, ["i", [], ["ANY value"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function resumes the suspended task specified by the argument ", <$format, ["i", [], ["task_id"], 'do_i]>, ". The error ", <$format, ["tt", [], ["~type"], 'do_tt]>, " is thrown if the task does not exist. The optional second argument ", <$format, ["i", [], ["value"], 'do_i]>, " is used as the return value for the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_suspend"]], ["suspend()"], 'do_link]>], 'do_tt]>, ". If a second argument is not specified the return value of ", <$format, ["tt", [], ["suspend()"], 'do_tt]>, " is zero. See ", <$format, ["link", [["node", "$help_coldc_tasks"]], ["Frames and Tasks"], 'do_link]>, " for more information on preempting and task control."], #[['this, $help_func_resume]]]>;
var $root inited = 1;
var $root managed = [$help_func_resume];
var $help_node nolist = 0;


new object $help_func_sender: $help_funcs_task;

var $root manager = $help_func_sender;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "sender()", "sender()"];
var $help_node links = #[["Tasks and Frames", $help_coldc_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " sender()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the objnum of the object which called the current method. If the current method was called by the driver, zero (0) is returned instead. Further information can be found in the section ", <$format, ["link", [["node", "$help_coldc_tasks"]], ["Tasks and Frames"], 'do_link]>, "."], #[['this, $help_func_sender]]]>;
var $root inited = 1;
var $root managed = [$help_func_sender];
var $help_node nolist = 0;


new object $help_func_stack: $help_funcs_task;

var $root manager = $help_func_stack;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "stack()", "stack()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " stack()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the call stack for the current task. Each element in the list is a list itself, representing a specific frame. The first element represents the first frame, and so on, up to the current frame. ", <$format, ["np", [], [], 'do_np]>, "Each frame list is ordered as follows:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["OBJNUM sender"], 'do_li]>, <$format, ["li", [], ["OBJNUM caller"], 'do_li]>, <$format, ["li", [], ["SYMBOL method name"], 'do_li]>, <$format, ["li", [], ["INTEGER line number"], 'do_li]>, <$format, ["li", [], ["INTEGER current op code"], 'do_li]>], 'do_ol]>], #[['this, $help_func_stack]]]>;
var $root inited = 1;
var $root managed = [$help_func_stack];
var $help_node nolist = 0;


new object $help_func_suspend: $help_funcs_task;

var $root manager = $help_func_suspend;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "suspend()", "suspend()"];
var $help_node links = #[["resume()", $help_func_resume], ["Frames and Tasks", $help_coldc_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " suspend()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function suspends the current task indefinitely. A suspended task is resumed by calling the function (in another task) ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_resume"]], ["resume()"], 'do_link]>], 'do_tt]>, ". The return value of suspend is given as the second argument to ", <$format, ["tt", [], ["resume()"], 'do_tt]>, ". If no second argument is given, the return value of ", <$format, ["tt", [], ["suspend()"], 'do_tt]>, " is zero. See ", <$format, ["link", [["node", "$help_coldc_tasks"]], ["Frames and Tasks"], 'do_link]>, " for more information on task control."], #[['this, $help_func_suspend]]]>;
var $root inited = 1;
var $root managed = [$help_func_suspend];
var $help_node nolist = 0;


new object $help_func_task_id: $help_funcs_task;

var $root manager = $help_func_task_id;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "task_id()", "task_id()"];
var $help_node links = #[["Frames and Tasks", $help_coldc_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " task_id()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the task id for the current task. See ", <$format, ["link", [["node", "$help_coldc_tasks"]], ["Frames and Tasks"], 'do_link]>, " for more information on preempting and task control."], #[['this, $help_func_task_id]]]>;
var $root inited = 1;
var $root managed = [$help_func_task_id];
var $help_node nolist = 0;


new object $help_func_tasks: $help_funcs_task;

var $root manager = $help_func_tasks;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "tasks()", "tasks()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " tasks()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a list of integers, where each integer is the task id for a currently suspended or preempted task."], #[['this, $help_func_tasks]]]>;
var $root inited = 1;
var $root managed = [$help_func_tasks];
var $help_node nolist = 0;


new object $help_func_this: $help_funcs_task;

var $root manager = $help_func_this;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "this()", "this()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " this()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the objnum of the current object."], #[['this, $help_func_this]]]>;
var $root inited = 1;
var $root managed = [$help_func_this];
var $help_node nolist = 0;


new object $help_func_tick: $help_funcs_task;

var $root manager = $help_func_tick;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "tick()", "tick()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " tick()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the current system-wide tick. It exists for backwards compatability, and should not be used."], #[['this, $help_func_tick]]]>;
var $root inited = 1;
var $root managed = [$help_func_tick];
var $help_node nolist = 0;


new object $help_func_ticks_left: $help_funcs_task;

var $root manager = $help_func_ticks_left;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "ticks_left()", "ticks_left()"];
var $help_node links = #[["Frames and Tasks", $help_coldc_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " ticks_left()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the ticks remaining for the current frame. See ", <$format, ["link", [["node", "$help_coldc_tasks"]], ["Frames and Tasks"], 'do_link]>, " for more information on frames and ticks."], #[['this, $help_func_ticks_left]]]>;
var $root inited = 1;
var $root managed = [$help_func_ticks_left];
var $help_node nolist = 0;


new object $help_func_set_user: $help_funcs_task;

var $root manager = $help_func_set_user;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855723148;
var $root managed = [$help_func_set_user];
var $has_name name = ['prop, "set_user()", "set_user()"];
var $help_node links = #[["user()", $help_func_user]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " set_user()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function sets the task's user to the current object. Later calls to the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_user"]], ["user()"], 'do_link]>], 'do_tt]>, " will return this object, until this function is called again. If no user is set, zero is returned instead. This is intended as an easy means to define a controlling object for a task."], #[['this, $help_func_set_user]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_user: $help_funcs_task;

var $root manager = $help_func_user;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855723311;
var $root managed = [$help_func_user];
var $has_name name = ['prop, "user()", "user()"];
var $help_node links = #[["set_user()", $help_func_set_user]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " user()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the task's user, as it was set with ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_set_user"]], ["set_user()"], 'do_link]>], 'do_tt]>, ". If no user was set, zero is returned instead. This is intended as an easy means to define a controlling object for a task."], #[['this, $help_func_user]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_pass: $help_funcs_task;

var $root manager = $help_func_pass;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855811819;
var $root managed = [$help_func_pass];
var $has_name name = ['prop, "pass()", "pass()"];
var $help_node links = #[["Overridden Methods", $help_coldc_mcall_over]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " pass(", <$format, ["i", [], ["..."], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used to call an overridden method, from the current method. When called any arguments sent to ", <$format, ["tt", [], ["pass()"], 'do_tt]>, " are sent to the overridden method, as if it was called with those arguments. When passing to a method, the current frame's values do not change (i.e. the caller and sender stay the same as in the method that is passing back). For more information see the section ", <$format, ["link", [["node", "$help_coldc_mcall_over"]], ["Overridden Methods"], 'do_link]>, "."], #[['this, $help_func_pass]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_task_info: $help_funcs_task;

var $root manager = $help_func_task_info;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855811820;
var $root managed = [$help_func_task_info];
var $has_name name = ['prop, "task_info()", "task_info()"];
var $help_node links = #[["config()", $help_func_config]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " task_info(", <$format, ["i", [], ["INTEGER task_id"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns full information on the task specified with the argument ", <$format, ["i", [], ["task_id"], 'do_i]>, ". If the task does not exist, ", <$format, ["tt", [], ["~type"], 'do_tt]>, " is thrown. The returned list contains a minimum of seven elements, with subsequent elements defining the specific frames, these are:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["INTEGER task id"], 'do_li]>, <$format, ["li", [], ["INTEGER preempted"], 'do_li]>, <$format, ["li", [], ["INTEGER datasize limit"], 'do_li]>, <$format, ["li", [], ["INTEGER fork limit"], 'do_li]>, <$format, ["li", [], ["INTEGER recursion limit"], 'do_li]>, <$format, ["li", [], ["INTEGER objswap limit"], 'do_li]>, <$format, ["li", [], ["INTEGER calldepth limit"], 'do_li]>, <$format, ["li", [], ["LIST frame"], 'do_li]>, <$format, ["li", [], ["..."], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "The second element ", <$format, ["i", [], ["preempted"], 'do_i]>, " is true if this task was preempted, false if it was suspended. For more information on the limit elements, see ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_config"]], ["config()"], 'do_link]>], 'do_tt]>, ". Remaining frame elements are eight element lists formatted as:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["OBJNUM current object"], 'do_li]>, <$format, ["li", [], ["OBJNUM caller"], 'do_li]>, <$format, ["li", [], ["OBJNUM sender"], 'do_li]>, <$format, ["li", [], ["OBJNUM user"], 'do_li]>, <$format, ["li", [], ["INTEGER current opcode"], 'do_li]>, <$format, ["li", [], ["INTEGER last opcode"], 'do_li]>, <$format, ["li", [], ["INTEGER ticks remaining"], 'do_li]>, <$format, ["li", [], ["SYMBOL method name"], 'do_li]>], 'do_ol]>], #[['this, $help_func_task_info]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_call_trace: $help_funcs_task;

var $root manager = $help_func_call_trace;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855811820;
var $root managed = [$help_func_call_trace];
var $has_name name = ['prop, "call_trace()", "call_trace()"];
var $help_node links = #[["debug mode", $help_func_debug_callers]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST|INTEGER"], 'do_i]>], 'do_tt]>, " call_trace()"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Depending on the ", <$format, ["link", [["node", "$help_func_debug_callers"]], ["debug mode"], 'do_link]>, ", one of the following will be returned:", <$format, ["subj", [["level", "3"]], ["mode 0"], 'do_subj]>, "Return 0 ", <$format, ["subj", [["level", "3"]], ["mode 1"], 'do_subj]>, "Returns a list samples gathered by debugger. Each method call is sampled as the following list:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["[tick#, this, definer, method]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], ["tick#"], 'do_dt]>, <$format, ["dd", [], ["tick in which the call occured"], 'do_dd]>, <$format, ["dt", [], ["this"], 'do_dt]>, <$format, ["dd", [], ["receiver of the call"], 'do_dd]>, <$format, ["dt", [], ["definer"], 'do_dt]>, <$format, ["dd", [], ["definer of the called method"], 'do_dd]>, <$format, ["dt", [], ["method"], 'do_dt]>, <$format, ["dd", [], ["method name (a symbol)"], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "Each method return is sampled as a tick#.", <$format, ["np", [], [], 'do_np]>, "Note: The tick counts will be off if the task has been preepmpted and another task executed during the pause.", <$format, ["subj", [["level", "3"]], ["mode 2"], 'do_subj]>, "In addition to the above, each method call has fifth element, giving the list of all the arguments passed in the call. Optional arguments (those defined as @rest in the arg list) are gathered into a list and placed into the result as a single element.", <$format, ["np", [], [], 'do_np]>, "This function will automatically set the debug mode to 0."], #[['this, $help_func_call_trace]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_debug_callers: $help_funcs_task;

var $root manager = $help_func_debug_callers;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855811820;
var $root managed = [$help_func_debug_callers];
var $has_name name = ['prop, "debug_callers()", "debug_callers()"];
var $help_node links = #[["call_trace", $help_func_call_trace]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>], 'do_tt]>, " debug_callers(", <$format, ["i", [], ["INTEGER mode"], 'do_i]>, ")"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function sets the mode for ", <$format, ["link", [["node", "$help_func_call_trace"]], ["call_trace"], 'do_link]>, " function. If mode is set to non-zero value, the method calling sampler will automatically start. The result of this function is 0."], #[['this, $help_func_debug_callers]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_funcs_err: $help_coldc_func;

var $root manager = $help_funcs_err;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Error", "Error"];
var $help_node links = #[["error()", $help_func_error], ["rethrow()", $help_func_rethrow], ["throw()", $help_func_throw], ["traceback()", $help_func_traceback]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "20%,20%,20%,20%,20%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_error"]], ["error()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_rethrow"]], ["rethrow()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_throw"]], ["throw()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_traceback"]], ["traceback()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_err]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_err];
var $help_node nolist = 0;


new object $help_func_error: $help_funcs_err;

var $root manager = $help_func_error;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "error()", "error()"];
var $help_node links = #[["Errors", $help_coldc_errors]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ERROR"], 'do_i]>, " error()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the error code associated with the current error. This function can only be called from within an error handler. For more information see the section on ", <$format, ["link", [["node", "$help_coldc_errors"]], ["Errors"], 'do_link]>, "."], #[['this, $help_func_error]]]>;
var $root inited = 1;
var $root managed = [$help_func_error];
var $help_node nolist = 0;


new object $help_func_rethrow: $help_funcs_err;

var $root manager = $help_func_rethrow;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "rethrow()", "rethrow()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], ["rethrow(", <$format, ["i", [], ["ERROR code"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function continues propagation of an error condition. The interpreter will abort the current method and throw the error specified by ", <$format, ["i", [], ["code"], 'do_i]>, " in the calling method. Calling this function outside of an error handler will result in the error ", <$format, ["tt", [], ["~error"], 'do_tt]>, "."], #[['this, $help_func_rethrow]]]>;
var $root inited = 1;
var $root managed = [$help_func_rethrow];
var $help_node nolist = 0;


new object $help_func_throw: $help_funcs_err;

var $root manager = $help_func_throw;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "throw()", "throw()"];
var $help_node links = #[["traceback()", $help_func_traceback], ["Errors", $help_coldc_errors]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], ["throw(", <$format, ["i", [], ["ERROR code"], 'do_i]>, ", ", <$format, ["i", [], ["STRING explanation"], 'do_i]>, "[, ", <$format, ["i", [], ["ANY additional"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function throws an error with the code ", <$format, ["i", [], ["code"], 'do_i]>, " in the calling method, not the current method. The current method does not have the ability to stop an error originating in itself. The variables ", <$format, ["i", [], ["explanation"], 'do_i]>, " and ", <$format, ["i", [], ["additional"], 'do_i]>, " appear in the traceback. For more information on error handling see ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_traceback"]], ["traceback()"], 'do_link]>], 'do_tt]>, " and ", <$format, ["link", [["node", "$help_coldc_errors"]], ["Errors"], 'do_link]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["throw(~perm, \"Sender is not the system object.\");"], 'do_dfn]>], #[['this, $help_func_throw]]]>;
var $root inited = 1;
var $root managed = [$help_func_throw];
var $help_node nolist = 0;


new object $help_func_traceback: $help_funcs_err;

var $root manager = $help_func_traceback;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "traceback()", "traceback()"];
var $help_node links = #[["Errors", $help_coldc_errors]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " traceback()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the propogated error stack. The first element in the traceback list is the error condition, the second element is what caused the error. The subsequent errors describe the method call stack from the point of origin. The error condition list is ordered as follows:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["ERROR code"], 'do_li]>, <$format, ["li", [], ["STRING explanation"], 'do_li]>, <$format, ["li", [], ["ANY additional"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "The second element (what caused the error) will vary, depending upon where the error came from. If the error came from an operator, function or native method, it is a two element list:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["SYMBOL which is one of ", <$format, ["tt", [], ["'opcode"], 'do_tt]>, ", ", <$format, ["tt", [], ["'function"], 'do_tt]>, " or ", <$format, ["tt", [], ["'native"], 'do_tt]>], 'do_li]>, <$format, ["li", [], ["SYMBOL what operator, or the name of the function/native method."], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "If the error originated in a method, this list is ordered as:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], [<$format, ["tt", [], ["'method"], 'do_tt]>], 'do_li]>, <$format, ["li", [], ["SYMBOL method name"], 'do_li]>, <$format, ["li", [], ["OBJNUM current object"], 'do_li]>, <$format, ["li", [], ["OBJNUM defining object"], 'do_li]>, <$format, ["li", [], ["INTEGER line in method"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "All other elements are ordered as:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["ERROR error code"], 'do_li]>, <$format, ["li", [], ["SYMBOL method name"], 'do_li]>, <$format, ["li", [], ["OBJNUM current object"], 'do_li]>, <$format, ["li", [], ["OBJNUM defining object"], 'do_li]>, <$format, ["li", [], ["INTEGER line in method"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "Keep in mind that the error code will change to ", <$format, ["tt", [], ["~methoderr"], 'do_tt]>, " when it propogates, unless the propogate expression is used. See the section ", <$format, ["link", [["node", "$help_coldc_errors"]], ["Errors"], 'do_link]>, " for more information. A full traceback might look like:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["[[~numargs, \"Called with no arguments, requires one.\", 0],", <$format, ["br", [], [], 'do_br]>, "['function, 'listlen],", <$format, ["br", [], [], 'do_br]>, "[~numargs, 'foo, $brandon, $brandon, 1],", <$format, ["br", [], [], 'do_br]>, "[~methoderr, 'tmp_eval_855796437, $brandon, $brandon, 6]]"], 'do_tt]>], 'do_dfn]>], #[['this, $help_func_traceback]]]>;
var $root inited = 1;
var $root managed = [$help_func_traceback];
var $help_node nolist = 0;


new object $help_funcs_net: $help_coldc_func;

var $root manager = $help_funcs_net;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Network", "Network"];
var $help_node links = #[["bind_port()", $help_func_bind_port], ["close_connection()", $help_func_close_connection], ["connection()", $help_func_connection], ["cwrite()", $help_func_cwrite], ["cwritef()", $help_func_cwritef], ["open_connection()", $help_func_open_connection], ["reassign_connection()", $help_func_reassign_connection], ["unbind_port()", $help_func_unbind_port]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "33%,33%,33%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_bind_port"]], ["bind_port()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_close_connection"]], ["close_connection()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_connection"]], ["connection()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_cwrite"]], ["cwrite()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_cwritef"]], ["cwritef()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_open_connection"]], ["open_connection()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_reassign_connection"]], ["reassign_connection()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_unbind_port"]], ["unbind_port()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_net]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_net];
var $help_node nolist = 0;


new object $help_func_bind_port: $help_funcs_net;

var $root manager = $help_func_bind_port;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "bind_port()", "bind_port()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " bind_port(", <$format, ["i", [], ["INTEGER port"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING addr"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function binds a network port to the current object. If successful, the current object will receive connections on the port. The first argument specifies the port to bind to. Positive port numbers represent the TCP protocol. Negative port numbers represent the UDP protocol. The second optional argument is the address to bind to, which must be a standard IP address (not an internet domain name). This is usually not required, but can be useful if multiple addresses exist on the system and only one must be bound. ", <$format, ["np", [], [], 'do_np]>, "If the port is pre-bound (see the Genesis documentation) but the address does not match up, the error ", <$format, ["tt", [], ["~preaddr"], 'do_tt]>, " may be thrown. If the port is pre-bound and the protocols do not match, the error ", <$format, ["tt", [], ["~pretype"], 'do_tt]>, " is thrown. If the given address is not a valid IP address the error ", <$format, ["tt", [], ["~address"], 'do_tt]>, " is thrown. Other errors may be thrown as ", <$format, ["tt", [], ["~socket"], 'do_tt]>, " or ", <$format, ["tt", [], ["~bind"], 'do_tt]>, " if other problems arise."], #[['this, $help_func_bind_port]]]>;
var $root inited = 1;
var $root managed = [$help_func_bind_port];
var $help_node nolist = 0;


new object $help_func_close_connection: $help_funcs_net;

var $root manager = $help_func_close_connection;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "close_connection()", "close_connection()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " close_connection()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function closes the connection on the current object. If there is no connection on the current object, zero is returned."], #[['this, $help_func_close_connection]]]>;
var $root inited = 1;
var $root managed = [$help_func_close_connection];
var $help_node nolist = 0;


new object $help_func_connection: $help_funcs_net;

var $root manager = $help_func_connection;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "connection()", "connection()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " connection()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a list of information on the current connection. If no connection exists, ", <$format, ["tt", [], ["~net"], 'do_tt]>, " is thrown. The list is ordered as:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["INTEGER boolean (true if the connection is readable)"], 'do_li]>, <$format, ["li", [], ["INTEGER boolean (true if the connection is writable)"], 'do_li]>, <$format, ["li", [], ["INTEGER boolean (true if the connection is dead)"], 'do_li]>, <$format, ["li", [], ["INTEGER file descriptor"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "Most of this information is useful only for debugging, as it can change immediately (all but the file descriptor). This function is useful for determining if the current object has a valid connection."], #[['this, $help_func_connection]]]>;
var $root inited = 1;
var $root managed = [$help_func_connection];
var $help_node nolist = 0;


new object $help_func_cwrite: $help_funcs_net;

var $root manager = $help_func_cwrite;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "cwrite()", "cwrite()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " cwrite(", <$format, ["i", [], ["BUFFER buffer"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function writes the buffer data in the argument ", <$format, ["i", [], ["buffer"], 'do_i]>, " to the connection on the current object. If there is no connection on the current object a zero is returned. Otherwise a one is returned."], #[['this, $help_func_cwrite]]]>;
var $root inited = 1;
var $root managed = [$help_func_cwrite];
var $help_node nolist = 0;


new object $help_func_cwritef: $help_funcs_net;

var $root manager = $help_func_cwritef;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "cwritef()", "cwritef()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " cwritef(", <$format, ["i", [], ["STRING file_path"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER block"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function opens the file specified by ", <$format, ["i", [], ["file_path"], 'do_i]>, " and writes it's contents directly to the connection. The block size it reads and writes (defaulting to the driver defined variable in defs.h DEF_BLOCKSIZE, usually this is 512) can be changed by specifying an optional second argument. If the second is a negative one (-1) it will attempt to read the entire file at once, and write it to the connection (the old coldmud behavior). The size of the file (in bytes) is returned. If a problem arises the error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown."], #[['this, $help_func_cwritef]]]>;
var $root inited = 1;
var $root managed = [$help_func_cwritef];
var $help_node nolist = 0;


new object $help_func_open_connection: $help_funcs_net;

var $root manager = $help_func_open_connection;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "open_connection()", "open_connection()"];
var $help_node links = #[["Networking", $help_coldc_net]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " open_connection(", <$format, ["i", [], ["STRING host"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER port"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function opens an outbound connection to ", <$format, ["i", [], ["host"], 'do_i]>, " at port ", <$format, ["i", [], ["port"], 'do_i]>, ", on the current object. If the host address ", <$format, ["i", [], ["host"], 'do_i]>, " is invalid, the error ", <$format, ["tt", [], ["~address"], 'do_tt]>, " is thrown. If the socket could not be established, ", <$format, ["tt", [], ["~socket"], 'do_tt]>, " is thrown. For more information, see the section on ", <$format, ["link", [["node", "$help_coldc_net"]], ["Networking"], 'do_link]>, "."], #[['this, $help_func_open_connection]]]>;
var $root inited = 1;
var $root managed = [$help_func_open_connection];
var $help_node nolist = 0;


new object $help_func_reassign_connection: $help_funcs_net;

var $root manager = $help_func_reassign_connection;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "reassign_connection()", "reassign_connection()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " reassign_connection(", <$format, ["i", [], ["OBJNUM new"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function changes the controlling object for a connection from the current object to the object specified by the argument ", <$format, ["i", [], ["new"], 'do_i]>, ". If the new object does not exist, ", <$format, ["tt", [], ["~objnf"], 'do_tt]>, " is thrown. If the new object already has a connection, the error ", <$format, ["tt", [], ["~perm"], 'do_tt]>, " is thrown."], #[['this, $help_func_reassign_connection]]]>;
var $root inited = 1;
var $root managed = [$help_func_reassign_connection];
var $help_node nolist = 0;


new object $help_func_unbind_port: $help_funcs_net;

var $root manager = $help_func_unbind_port;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "unbind_port()", "unbind_port()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " unbind_port(", <$format, ["i", [], ["INTEGER port"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function stops listening to the port specified by ", <$format, ["i", [], ["port"], 'do_i]>, ". If the object is not listening to the specified port, ", <$format, ["tt", [], ["~servnf"], 'do_tt]>, " is thrown."], #[['this, $help_func_unbind_port]]]>;
var $root inited = 1;
var $root managed = [$help_func_unbind_port];
var $help_node nolist = 0;


new object $help_funcs_file: $help_coldc_func;

var $root manager = $help_funcs_file;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "File", "File"];
var $help_node links = #[["dblog()", $help_func_dblog], ["execute()", $help_func_execute], ["fchmod()", $help_func_fchmod], ["fclose()", $help_func_fclose], ["feof()", $help_func_feof], ["fflush()", $help_func_fflush], ["file()", $help_func_file], ["files()", $help_func_files], ["fmkdir()", $help_func_fmkdir], ["fopen()", $help_func_fopen], ["fread()", $help_func_fread], ["fremove()", $help_func_fremove], ["frename()", $help_func_frename], ["frmdir()", $help_func_frmdir], ["fseek()", $help_func_fseek], ["fstat()", $help_func_fstat], ["fwrite()", $help_func_fwrite]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "17%,17%,17%,17%,17%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_dblog"]], ["dblog()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_execute"]], ["execute()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fchmod"]], ["fchmod()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fclose"]], ["fclose()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_feof"]], ["feof()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fflush"]], ["fflush()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_file"]], ["file()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_files"]], ["files()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fmkdir"]], ["fmkdir()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fopen"]], ["fopen()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fread"]], ["fread()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fremove"]], ["fremove()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_frename"]], ["frename()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_frmdir"]], ["frmdir()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fseek"]], ["fseek()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fstat"]], ["fstat()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fwrite"]], ["fwrite()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_file]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_file];
var $help_node nolist = 0;


new object $help_func_dblog: $help_funcs_file;

var $root manager = $help_func_dblog;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "dblog()", "dblog()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " dblog(", <$format, ["i", [], ["STRING line"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function writes ", <$format, ["i", [], ["line"], 'do_i]>, " to the database logfile (specified on startup, defaulting to ", <$format, ["tt", [], ["logs/db.log"], 'do_tt]>, ")."], #[['this, $help_func_dblog]]]>;
var $root inited = 1;
var $root managed = [$help_func_dblog];
var $help_node nolist = 0;


new object $help_func_execute: $help_funcs_file;

var $root manager = $help_func_execute;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "execute()", "execute()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " execute(", <$format, ["i", [], ["STRING program"], 'do_i]>, ", ", <$format, ["i", [], ["LIST args"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER nb"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function executes the program named by ", <$format, ["i", [], ["program"], 'do_i]>, " with the arguments given in the list ", <$format, ["i", [], ["arguments"], 'do_i]>, ". Each argument must be a string. By default, calling this function will block execution of genesis until the called program returns. If the optional third argument is specified as a true value, the program is forked and executed in a non-blocking manner. The return value is the return value of the program, or, in the case of a non-blocking execution it is zero. ", <$format, ["np", [], [], 'do_np]>, "This function looks for the program in the executable directory specified upon startup by the driver. This usually defaults to ", <$format, ["tt", [], ["dbbin"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "In the future input and output for the program may be handled as if it were a file."], #[['this, $help_func_execute]]]>;
var $root inited = 1;
var $root managed = [$help_func_execute];
var $help_node nolist = 0;


new object $help_func_fchmod: $help_funcs_file;

var $root manager = $help_func_fchmod;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fchmod()", "fchmod()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " fchmod(", <$format, ["i", [], ["STRING mode"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING file"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function changes the mode of a file or directory. The mode is an octal number constructed by logically OR-ing the following values:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], ["4000"], 'do_dt]>, <$format, ["dd", [], ["set-user-ID-on-execution"], 'do_dd]>, <$format, ["dt", [], ["2000"], 'do_dt]>, <$format, ["dd", [], ["set-group-ID-on-execution"], 'do_dd]>, <$format, ["dt", [], ["1000"], 'do_dt]>, <$format, ["dd", [], ["sticky bit, see the unix manual on chmod"], 'do_dd]>, <$format, ["dt", [], ["0400"], 'do_dt]>, <$format, ["dd", [], ["read by owner"], 'do_dd]>, <$format, ["dt", [], ["0200"], 'do_dt]>, <$format, ["dd", [], ["write by owner"], 'do_dd]>, <$format, ["dt", [], ["0100"], 'do_dt]>, <$format, ["dd", [], ["execute (or search for directories) by owner"], 'do_dd]>, <$format, ["dt", [], ["0070"], 'do_dt]>, <$format, ["dd", [], ["read, write, execute/search by group"], 'do_dd]>, <$format, ["dt", [], ["0007"], 'do_dt]>, <$format, ["dd", [], ["read, write, execute/search by others"], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "The read, write, and execute/search values for group and others are en- coded as described for owner. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["fchmod(\"0644\", \"home.html\")", <$format, ["br", [], [], 'do_br]>, "=> 1"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If the ", <$format, ["tt", [], ["RESTRICTIVE_FILES"], 'do_tt]>, " option has been compiled into the driver, sticky and setuid/setgid bits cannot be changed."], #[['this, $help_func_fchmod]]]>;
var $root inited = 1;
var $root managed = [$help_func_fchmod];
var $help_node nolist = 0;


new object $help_func_fclose: $help_funcs_file;

var $root manager = $help_func_fclose;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fclose()", "fclose()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " fclose()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function closes the file on the current object and returns one (1). If no file is open on the current object, the error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown."], #[['this, $help_func_fclose]]]>;
var $root inited = 1;
var $root managed = [$help_func_fclose];
var $help_node nolist = 0;


new object $help_func_feof: $help_funcs_file;

var $root manager = $help_func_feof;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "feof()", "feof()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " feof()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns true (1) if the open file on the current object is at it's end, or false (0) if it is not. If the current object does not have an open file, ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown."], #[['this, $help_func_feof]]]>;
var $root inited = 1;
var $root managed = [$help_func_feof];
var $help_node nolist = 0;


new object $help_func_fflush: $help_funcs_file;

var $root manager = $help_func_fflush;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fflush()", "fflush()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " fflush()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function flushes any buffered output for the open file on the current object and returns one (1). If there is no file on the current object the error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown."], #[['this, $help_func_fflush]]]>;
var $root inited = 1;
var $root managed = [$help_func_fflush];
var $help_node nolist = 0;


new object $help_func_file: $help_funcs_file;

var $root manager = $help_func_file;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "file()", "file()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " file()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the following ordered list of information on the file on the current object:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["BOOLEAN file is readable"], 'do_li]>, <$format, ["li", [], ["BOOLEAN file is writable"], 'do_li]>, <$format, ["li", [], ["BOOLEAN file is closed"], 'do_li]>, <$format, ["li", [], ["BOOLEAN file is binary"], 'do_li]>, <$format, ["li", [], ["STRING file path"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "If no file is bound to the current object, the error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown."], #[['this, $help_func_file]]]>;
var $root inited = 1;
var $root managed = [$help_func_file];
var $help_node nolist = 0;


new object $help_func_files: $help_funcs_file;

var $root manager = $help_func_files;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "files()", "files()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " files(", <$format, ["i", [], ["STRING directory"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a lit of files in the specified directory. The current and previous directory (\".\" and \"..\") are not included in this listing. Each element in the list is a string. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["files(\"html/\");", <$format, ["br", [], [], 'do_br]>, "=> [\"index.html\", \"tCD.gif\", \"Intro\", \"history.html\"]"], 'do_dfn]>], #[['this, $help_func_files]]]>;
var $root inited = 1;
var $root managed = [$help_func_files];
var $help_node nolist = 0;


new object $help_func_fmkdir: $help_funcs_file;

var $root manager = $help_func_fmkdir;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fmkdir()", "fmkdir()"];
var $help_node links = #[["fchmod()", $help_func_fchmod]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " fmkdir(", <$format, ["i", [], ["STRING path"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function creates the directory specified by ", <$format, ["i", [], ["path"], 'do_i]>, ". If a file or directory already exists by that designation, the error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown. Otherwise the directory is created with read, write and execute permission for the owner, and no permissions for group or others (these permissions can be changed with the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_fchmod"]], ["fchmod()"], 'do_link]>], 'do_tt]>, "."], #[['this, $help_func_fmkdir]]]>;
var $root inited = 1;
var $root managed = [$help_func_fmkdir];
var $help_node nolist = 0;


new object $help_func_fopen: $help_funcs_file;

var $root manager = $help_func_fopen;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fopen()", "fopen()"];
var $help_node links = #[["Files", $help_coldc_files], ["fstat()", $help_func_fstat]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " fopen(", <$format, ["i", [], ["STRING filename"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING mode"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used to open a file on the current object. It is called with one or two arguments. The first argument is the name of the file to open. If the driver was compiled with the ", <$format, ["tt", [], ["RESTRICTIVE_FILES"], 'do_tt]>, " option, the filename will have restrictions (see the section on ", <$format, ["link", [["node", "$help_coldc_files"]], ["Files"], 'do_link]>, " for more information). If ", <$format, ["tt", [], ["RESTRICTIVE_FILES"], 'do_tt]>, " was compiled, all files will have the ", <$format, ["i", [], ["root"], 'do_i]>, " directory prepended to them (this directory is defined by a command line argument to ", <$format, ["a", [["href", "http://www.cold.org/Software/Genesis/"]], [<$format, ["i", [], ["Genesis"], 'do_i]>], 'do_a]>, "). If it was not compiled, but the file does not begin with a slash (\"/\"), the ", <$format, ["i", [], ["root"], 'do_i]>, " directory will still be prepended. ", <$format, ["np", [], [], 'do_np]>, "The second argument is the mode for the file. If the mode begins with \"<\" or nothing, the file is opened for reading. If the mode begins with \">\", the file is truncated to zero length or created for writing. If the mode begins with \">>\", the file is opend for appending. If the second argument is not specified, the mode of file defaults to \"<\". ", <$format, ["np", [], [], 'do_np]>, "A \"+\" may be placed before \">\" or \"<\" to specify both read and write access to the file. Ending a mode with a \"-\" sets it as a binary file, meaning that input and output to the file is through buffers, rather than ColdC strings. ", <$format, ["np", [], [], 'do_np]>, "If successful, the return value of fopen() is stat information in the format returned by ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_fstat"]], ["fstat()"], 'do_link]>], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["stat = fopen(\"log\", \">>\")"], 'do_dfn]>, " ", <$format, ["dfn", [], ["stat = fopen(\"/usr/home/test.info\", \"+>-\")"], 'do_dfn]>], #[['this, $help_func_fopen]]]>;
var $root inited = 1;
var $root managed = [$help_func_fopen];
var $help_node nolist = 0;


new object $help_func_fread: $help_funcs_file;

var $root manager = $help_func_fread;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fread()", "fread()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING|BUFFER"], 'do_i]>, " fread([", <$format, ["i", [], ["INTEGER block"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Read from the existing file bound to this object. If the file is a binary file, a buffer is returned. If the file is a text file (default), a string is returned. If the file is at the end, the ", <$format, ["tt", [], ["~eof"], 'do_tt]>, " error is thrown. With binary files an optional block size may be specified. The default block size is 512 characters. Example: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\n        catch ~eof {\n            while (1) {\n                line = fread();\n                .tell(line);\n            }\n        }\n"], 'do_quote]>], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_func_fread];
var $help_node nolist = 0;


new object $help_func_fremove: $help_funcs_file;

var $root manager = $help_func_fremove;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fremove()", "fremove()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " fremove(", <$format, ["i", [], ["STRING path"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function removes a file. If the argument ", <$format, ["i", [], ["path"], 'do_i]>, " is given, it will attempt to remove that file."], #[['this, $help_func_fremove]]]>;
var $root inited = 1;
var $root managed = [$help_func_fremove];
var $help_node nolist = 0;


new object $help_func_frename: $help_funcs_file;

var $root manager = $help_func_frename;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "frename()", "frename()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["INTEGER frename(ANY from, STRING to)"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function renames the file specified by the argument ", <$format, ["i", [], ["from"], 'do_i]>, ", to the name specified by the argument ", <$format, ["i", [], ["to"], 'do_i]>, ". If ", <$format, ["i", [], ["from"], 'do_i]>, " is not a string or is logically false, the driver renames the file on the current object. Do not rename the file on the current object by specifying the file's name, as the driver will not know the name has changed and this may cause confusion at a later time. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["frename(\"\", \"old.txt\")", <$format, ["br", [], [], 'do_br]>, "=> 1"], 'do_dfn]>], #[['this, $help_func_frename]]]>;
var $root inited = 1;
var $root managed = [$help_func_frename];
var $help_node nolist = 0;


new object $help_func_frmdir: $help_funcs_file;

var $root manager = $help_func_frmdir;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "frmdir()", "frmdir()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " frmdir(", <$format, ["i", [], ["STRING path"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function removes the directory specified by ", <$format, ["i", [], ["path"], 'do_i]>, ". If an error occurs, ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown (the error explanation will vary depending upon what occurred)."], #[['this, $help_func_frmdir]]]>;
var $root inited = 1;
var $root managed = [$help_func_frmdir];
var $help_node nolist = 0;


new object $help_func_fseek: $help_funcs_file;

var $root manager = $help_func_fseek;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fseek()", "fseek()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " fseek(", <$format, ["i", [], ["INTEGER offset"], 'do_i]>, ", ", <$format, ["i", [], ["SYMBOL whence"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function changes the file position to ", <$format, ["i", [], ["offset"], 'do_i]>, ". The variable ", <$format, ["i", [], ["whence"], 'do_i]>, " is either ", <$format, ["tt", [], ["'SEEK_SET"], 'do_tt]>, ", ", <$format, ["tt", [], ["'SEEK_CUR"], 'do_tt]>, ", ", <$format, ["tt", [], ["'SEEK_END"], 'do_tt]>, ". Read the unix manual page for the function ", <$format, ["tt", [], ["fseek"], 'do_tt]>, ", for more information. ", <$format, ["np", [], [], 'do_np]>, "If the file is not both readable and writable, this function cannot be used."], #[['this, $help_func_fseek]]]>;
var $root inited = 1;
var $root managed = [$help_func_fseek];
var $help_node nolist = 0;


new object $help_func_fstat: $help_funcs_file;

var $root manager = $help_func_fstat;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fstat()", "fstat()"];
var $help_node links = #[["fchmod()", $help_func_fchmod]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " fstat([", <$format, ["i", [], ["STRING path"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns information on a file. If the file is not specified as ", <$format, ["i", [], ["path"], 'do_i]>, ", then it returns information on the open file on the current object. The information is returned as an ordered list:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["STRING octal file mode (see ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_fchmod"]], ["fchmod()"], 'do_link]>], 'do_tt]>, ")"], 'do_li]>, <$format, ["li", [], ["INTEGER file size (in bytes)"], 'do_li]>, <$format, ["li", [], ["INTEGER time when the file was last accessed"], 'do_li]>, <$format, ["li", [], ["INTEGER time when the file data was last modified"], 'do_li]>, <$format, ["li", [], ["INTEGER time when the file status was last changed"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "For more information refer to the unix manual page on ", <$format, ["tt", [], ["stat"], 'do_tt]>, ". The octal file mode will likely include additional bit fields from what is commonly seen. These represent file attributes, such as directories, FIFO, etc. The last four bits will refer to the permissions. For instance:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["fstat(\"html\")", <$format, ["br", [], [], 'do_br]>, "=> [\"40775\", 512, 855442283, 851293545, 855435595]"], 'do_dfn]>], #[['links, #[["fchmod()", "$help_func_fchmod"]]]]]>;
var $root inited = 1;
var $root managed = [$help_func_fstat];
var $help_node nolist = 0;


new object $help_func_fwrite: $help_funcs_file;

var $root manager = $help_func_fwrite;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fwrite()", "fwrite()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " fwrite(", <$format, ["i", [], ["STRING|BUFFER info"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Write to an existing file bound to this object. The argument is either a buffer (if it is a binary file), or a string (if it is a text file). The return value is an integer representing an offset value of characters which were ", <$format, ["i", [], ["not"], 'do_i]>, " written out (due to an error). In normal operating conditions the return value will be zero. ", <$format, ["np", [], [], 'do_np]>, "Using fwrite() with strings will always terminate the string with a newline character (ASCII 10)."], #[['this, $help_func_fwrite]]]>;
var $root inited = 1;
var $root managed = [$help_func_fwrite];
var $help_node nolist = 0;


new object $help_funcs_misc: $help_coldc_func;

var $root manager = $help_funcs_misc;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Misc", "Misc"];
var $help_node links = #[["bind_function()", $help_func_bind_function], ["ctime()", $help_func_ctime], ["localtime()", $help_func_localtime], ["mtime()", $help_func_mtime], ["time()", $help_func_time], ["unbind_function()", $help_func_unbind_function]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "28%,28%,28%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_bind_function"]], ["bind_function()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_ctime"]], ["ctime()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_localtime"]], ["localtime()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_mtime"]], ["mtime()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_time"]], ["time()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_unbind_function"]], ["unbind_function()"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_misc]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_misc];
var $help_node nolist = 0;


new object $help_func_bind_function: $help_funcs_misc;

var $root manager = $help_func_bind_function;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "bind_function()", "bind_function()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " bind_function(", <$format, ["i", [], ["SYMBOL function"], 'do_i]>, ", ", <$format, ["i", [], ["OBJNUM obj"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used to secure other ColdC functions which may have potential security problems. It binds the function specified by the argument ", <$format, ["i", [], ["function"], 'do_i]>, " to the object specified by ", <$format, ["i", [], ["obj"], 'do_i]>, ". After a function is bound to an object, only methods ", <$format, ["i", [], ["defined"], 'do_i]>, " on that object may call the function. The error ", <$format, ["tt", [], ["~perm"], 'do_tt]>, " is thrown if methods defined on descendants of the object or on any other object call a bound function which is not bound to them."], #[['this, $help_func_bind_function]]]>;
var $root inited = 1;
var $root managed = [$help_func_bind_function];
var $help_node nolist = 0;


new object $help_func_ctime: $help_funcs_misc;

var $root manager = $help_func_ctime;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "ctime()", "ctime()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["STRING ctime([INTEGER time])"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function converts the integer ", <$format, ["i", [], ["time"], 'do_i]>, " into a string format, using the operating system's ", <$format, ["i", [], ["ctime"], 'do_i]>, " library call. This call may handle any time conversions automatically (such as Daylight Savings and Leap Years). If ", <$format, ["i", [], ["time"], 'do_i]>, " is not specified, then ", <$format, ["tt", [], ["ctime()"], 'do_tt]>, " uses the current time. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["ctime(739180536)", <$format, ["br", [], [], 'do_br]>, "=> \"Fri Jun 4 03:55:36 1993\""], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_func_ctime];
var $help_node nolist = 0;


new object $help_func_localtime: $help_funcs_misc;

var $root manager = $help_func_localtime;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "localtime()", "localtime()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " localtime([", <$format, ["i", [], ["INTEGER time"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns an 11 element list representing the specified by the argument ", <$format, ["i", [], ["time"], 'do_i]>, ". If no argument is given, it will use the current time instead. The elements are taken from ", <$format, ["tt", [], ["struct tm"], 'do_tt]>, " in C and altered as needed to begin at one instead of zero. Elements are broken down in the list as follows:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["INTEGER time (same as returned by the function ", <$format, ["tt", [], ["time()"], 'do_tt]>, ")"], 'do_li]>, <$format, ["li", [], ["INTEGER seconds (1-60)"], 'do_li]>, <$format, ["li", [], ["INTEGER minutes (1-60)"], 'do_li]>, <$format, ["li", [], ["INTEGER hours (1-24))"], 'do_li]>, <$format, ["li", [], ["INTEGER day of month (1-31)"], 'do_li]>, <$format, ["li", [], ["INTEGER month in year (1-12)"], 'do_li]>, <$format, ["li", [], ["INTEGER year (use year + 1900 for the full year)"], 'do_li]>, <$format, ["li", [], ["INTEGER week day (1-7, Sunday=1)"], 'do_li]>, <$format, ["li", [], ["INTEGER year day (1-366)"], 'do_li]>, <$format, ["li", [], ["INTEGER is daylight savings in effect?"], 'do_li]>, <$format, ["li", [], ["STRING time zone name"], 'do_li]>, <$format, ["li", [], ["INTEGER timezone offset in seconds from GMT"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "Note: there is one bug, in order to optimize the speed of this function the timezone name (as a string) is cached. This will mean that if the timezone name changes while genesis is running the name will not update correctly."], #[]]>;
var $root inited = 1;
var $root managed = [$help_func_localtime];
var $help_node nolist = 0;


new object $help_func_mtime: $help_funcs_misc;

var $root manager = $help_func_mtime;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "mtime()", "mtime()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " mtime()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If the system the server is on does not have the unix function ", <$format, ["tt", [], ["gettimeofday()"], 'do_tt]>, " then this function will return ", <$format, ["tt", [], ["-1"], 'do_tt]>, ". If it does, this function will return the current microseconds, from the C structure ", <$format, ["tt", [], ["struct timeval"], 'do_tt]>, ". This is useful in certain situations, but in general its granularity is too fine for most cases. This will only work if cold is running on some unix systems."], #[['this, $help_func_mtime]]]>;
var $root inited = 1;
var $root managed = [$help_func_mtime];
var $help_node nolist = 0;


new object $help_func_time: $help_funcs_misc;

var $root manager = $help_func_time;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "time()", "time()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " time()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the system time in seconds since midnight GMT, January 1, 1970--likely adjusted for the local timezone (this is OS dependant). The functions ", <$format, ["tt", [], ["ctime()"], 'do_tt]>, ", ", <$format, ["tt", [], ["localtime()"], 'do_tt]>, " and the native method ", <$format, ["tt", [], ["$time.format()"], 'do_tt]>, " can be used in manipulating this number."], #[]]>;
var $root inited = 1;
var $root managed = [$help_func_time];
var $help_node nolist = 0;


new object $help_func_unbind_function: $help_funcs_misc;

var $root manager = $help_func_unbind_function;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "unbind_function()", "unbind_function()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " unbind_function(", <$format, ["i", [], ["SYMBOL function"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function unbinds a function from an object. The function is specified by the argument ", <$format, ["i", [], ["function"], 'do_i]>, "."], #[['this, $help_func_unbind_function]]]>;
var $root inited = 1;
var $root managed = [$help_func_unbind_function];
var $help_node nolist = 0;


new object $help_funcs_data: $help_coldc_func;

var $root manager = $help_funcs_data;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Data", "Data"];
var $help_node links = #[["class()", $help_func_class], ["fromliteral()", $help_func_fromliteral], ["size()", $help_func_size], ["toerr()", $help_func_toerr], ["tofloat()", $help_func_tofloat], ["toint()", $help_func_toint], ["toliteral()", $help_func_toliteral], ["toobjnum()", $help_func_toobjnum], ["tostr()", $help_func_tostr], ["tosym()", $help_func_tosym], ["type()", $help_func_type], ["valid()", $help_func_valid]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "22%,22%,22%,22%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_class"]], ["class()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fromliteral"]], ["fromliteral()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_size"]], ["size()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_toerr"]], ["toerr()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_tofloat"]], ["tofloat()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_toint"]], ["toint()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_toliteral"]], ["toliteral()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_toobjnum"]], ["toobjnum()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_tostr"]], ["tostr()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_tosym"]], ["tosym()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_type"]], ["type()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_valid"]], ["valid()"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_data]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_data];
var $help_node nolist = 0;


new object $help_func_class: $help_funcs_data;

var $root manager = $help_func_class;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "frob_class()", "frob_class()"];
var $help_node links = #[["Frobs", $help_coldc_types_frobs]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " frob_class(", <$format, ["i", [], ["FROB frob"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the class of a frob. See ", <$format, ["link", [["node", "$help_coldc_types_frobs"]], ["Frobs"], 'do_link]>, " for more details on Frobs."], #[['links, #[["Frobs", "$help_coldc_types_frobs"]]]]]>;
var $root inited = 1;
var $root managed = [$help_func_class];
var $help_node nolist = 0;


new object $help_func_size: $help_funcs_data;

var $root manager = $help_func_size;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "size()", "size()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " size([", <$format, ["i", [], ["ANY data"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used for sizing data. If no arguments are specified, it will return the size of the current object, including all of the methods and object variable instances defined on it. Otherwise it returns the size of the first argument. Note: specifying an objnum as the argument will return the size of the objnum, not the size of the object it represents!", <$format, ["p", [], [], 'do_p]>, "The number returned represents the size, in bytes, ", <$format, ["i", [], ["on disk"], 'do_i]>, ". Because data is packed when written to the disk database, what is returned will not be comparable to runtime memory footprints.", <$format, ["p", [], [], 'do_p]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["size(#1234)", <$format, ["br", [], [], 'do_br]>, "=> 4"], 'do_dfn]>, " ", <$format, ["dfn", [], ["size([1, 2, 3, 4])", <$format, ["br", [], [], 'do_br]>, "=> 15"], 'do_dfn]>, " ", <$format, ["dfn", [], ["size(#[['key1, 1], ['key2, \"test\"]])", <$format, ["br", [], [], 'do_br]>, "=> 45"], 'do_dfn]>, " ", <$format, ["dfn", [], ["size(<$root, #[['name, \"foo\"]]>);", <$format, ["br", [], [], 'do_br]>, "=> 37"], 'do_dfn]>, " ", <$format, ["dfn", [], ["size()", <$format, ["br", [], [], 'do_br]>, "=> 5822"], 'do_dfn]>], #[['this, $help_func_size]]]>;
var $root inited = 1;
var $root managed = [$help_func_size];
var $help_node nolist = 0;


new object $help_func_toerr: $help_funcs_data;

var $root manager = $help_func_toerr;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "toerr()", "toerr()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ERROR"], 'do_i]>, " toerr(", <$format, ["i", [], ["SYMBOL errname"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function converts the argument specified by ", <$format, ["i", [], ["errname"], 'do_i]>, " to an error code."], #[['this, $help_func_toerr]]]>;
var $root inited = 1;
var $root managed = [$help_func_toerr];
var $help_node nolist = 0;


new object $help_func_tofloat: $help_funcs_data;

var $root manager = $help_func_tofloat;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "tofloat()", "tofloat()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["FLOAT"], 'do_i]>, " tofloat(", <$format, ["i", [], ["STRING|INTEGER|OBJNUM data"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function accepts a STRING, INTEGER or OBJNUM data type and converts it to a FLOAT data type. Specifying any other data type will result in a ", <$format, ["tt", [], ["~type"], 'do_tt]>, " error."], #[['this, $help_func_tofloat]]]>;
var $root inited = 1;
var $root managed = [$help_func_tofloat];
var $help_node nolist = 0;


new object $help_func_toint: $help_funcs_data;

var $root manager = $help_func_toint;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "toint()", "toint()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " toint(", <$format, ["i", [], ["FLOAT|STRING|OBJNUM data"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function accepts a FLOAT, STRING or OBJNUM data type and converts it to an integer data type. Specifying any other data type will result in a ", <$format, ["tt", [], ["~type"], 'do_tt]>, " error."], #[['this, $help_func_toint]]]>;
var $root inited = 1;
var $root managed = [$help_func_toint];
var $help_node nolist = 0;


new object $help_func_toliteral: $help_funcs_data;

var $root manager = $help_func_toliteral;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "toliteral()", "toliteral()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " toliteral(", <$format, ["i", [], ["ANY data"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function converts any data to a literal representation of itself, which, if re-compiled, would result in the same data."], #[['this, $help_func_toliteral]]]>;
var $root inited = 1;
var $root managed = [$help_func_toliteral];
var $help_node nolist = 0;


new object $help_func_toobjnum: $help_funcs_data;

var $root manager = $help_func_toobjnum;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "toobjnum()", "toobjnum()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " toobjnum(", <$format, ["tt", [], ["INTEGER number"], 'do_tt]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function converts the integer data type specified by ", <$format, ["i", [], ["number"], 'do_i]>, " to an objnum data type. The returned objnum may or may not point to a valid object."], #[['this, $help_func_toobjnum]]]>;
var $root inited = 1;
var $root managed = [$help_func_toobjnum];
var $help_node nolist = 0;


new object $help_func_tostr: $help_funcs_data;

var $root manager = $help_func_tostr;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "tostr()", "tostr()"];
var $help_node links = #[["toliteral()", $help_func_toliteral]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " tostr(", <$format, ["i", [], ["ANY data"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a simple representation of the data specified by ", <$format, ["i", [], ["data"], 'do_i]>, ". It is not a literal representation, as ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_toliteral"]], ["toliteral()"], 'do_link]>], 'do_tt]>, " does, but insteads is more succinct. For instance, with complex data types such as lists, the returned representation is simply ", <$format, ["tt", [], ["\"[list]\""], 'do_tt]>, ". Less complex data types such as integers will still return the correct integer value."], #[['this, $help_func_tostr]]]>;
var $root inited = 1;
var $root managed = [$help_func_tostr];
var $help_node nolist = 0;


new object $help_func_tosym: $help_funcs_data;

var $root manager = $help_func_tosym;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "tosym()", "tosym()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["SYMBOL"], 'do_i]>, " tosym(", <$format, ["i", [], ["STRING input"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function creates a symbol from the string ", <$format, ["i", [], ["input"], 'do_i]>, ". Symbols can only contain alphanumeric characters, and the underscore character. If a string is specified with more than these characters, the error ", <$format, ["tt", [], ["~symbol"], 'do_tt]>, " is thrown."], #[['this, $help_func_tosym]]]>;
var $root inited = 1;
var $root managed = [$help_func_tosym];
var $help_node nolist = 0;


new object $help_func_type: $help_funcs_data;

var $root manager = $help_func_type;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "type()", "type()"];
var $help_node links = #[["Data Types", $help_coldc_types]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["SYMBOL"], 'do_i]>, " type(", <$format, ["i", [], ["ANY data"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a symbol name for the data type of ", <$format, ["i", [], ["data"], 'do_i]>, ". The following symbols represent the respective types:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], ["INTEGER"], 'do_dt]>, <$format, ["dd", [], ["'integer"], 'do_dd]>, <$format, ["dt", [], ["FLOAT"], 'do_dt]>, <$format, ["dd", [], ["'float"], 'do_dd]>, <$format, ["dt", [], ["STRING"], 'do_dt]>, <$format, ["dd", [], ["'string"], 'do_dd]>, <$format, ["dt", [], ["SYMBOL"], 'do_dt]>, <$format, ["dd", [], ["'symbol"], 'do_dd]>, <$format, ["dt", [], ["LIST"], 'do_dt]>, <$format, ["dd", [], ["'list"], 'do_dd]>, <$format, ["dt", [], ["OBJNUM"], 'do_dt]>, <$format, ["dd", [], ["'objnum"], 'do_dd]>, <$format, ["dt", [], ["DICTIONARY"], 'do_dt]>, <$format, ["dd", [], ["'dictionary"], 'do_dd]>, <$format, ["dt", [], ["ERROR"], 'do_dt]>, <$format, ["dd", [], ["'error"], 'do_dd]>, <$format, ["dt", [], ["FROB"], 'do_dt]>, <$format, ["dd", [], ["'frob"], 'do_dd]>, <$format, ["dt", [], ["BUFFER"], 'do_dt]>, <$format, ["dd", [], ["'buffer"], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "More information can be found in the section on ", <$format, ["link", [["node", "$help_coldc_types"]], ["Data Types"], 'do_link]>, "."], #[['this, $help_func_type]]]>;
var $root inited = 1;
var $root managed = [$help_func_type];
var $help_node nolist = 0;


new object $help_func_valid: $help_funcs_data;

var $root manager = $help_func_valid;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "valid()", "valid()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " valid(", <$format, ["i", [], ["OBJNUM objnum"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns one (true) if the object pointed to by ", <$format, ["i", [], ["objnum"], 'do_i]>, " exists, or zero (false) if it does not."], #[['this, $help_func_valid]]]>;
var $root inited = 1;
var $root managed = [$help_func_valid];
var $help_node nolist = 0;


new object $help_func_fromliteral: $help_funcs_data;

var $root manager = $help_func_fromliteral;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855441374;
var $root managed = [$help_func_fromliteral];
var $has_name name = ['prop, "fromliteral()", "fromliteral()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " fromliteral(", <$format, ["i", [], ["STRING data"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function takes the literal representation of the data given in the string argument ", <$format, ["i", [], ["data"], 'do_i]>, " and parses it to actual data, returning the result. If it cannot parse the data, the error ", <$format, ["tt", [], ["~type"], 'do_tt]>, " is thrown. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["fromliteral(\"[1, 'foo]\")", <$format, ["br", [], [], 'do_br]>, "=> [1, 'foo]"], 'do_dfn]>], #[['this, $help_func_fromliteral]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_frob_value: $help_funcs_data;

var $root manager = $help_func_frob_value;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 864934991;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "frob_value()", "frob_value()"];
var $help_node links = #[["Frobs", $help_coldc_types_frobs]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["DATA"], 'do_i]>, " frob_value(", <$format, ["i", [], ["FROB frob"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the value of a frob. See ", <$format, ["link", [["node", "$help_coldc_types_frobs"]], ["Frobs"], 'do_link]>, " for more details on Frobs."], #[['links, #[["Frobs", "$help_coldc_types_frobs"]]]]]>;
var $root inited = 1;
var $root managed = [$help_func_frob_value];


new object $help_func_frob_handler: $help_funcs_data;

var $root manager = $help_func_frob_handler;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 864934999;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "frob_handler()", "frob_handler()"];
var $help_node links = #[["Frobs", $help_coldc_types_frobs]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["SYMBOL"], 'do_i]>, " frob_handler(", <$format, ["i", [], ["FROB frob"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the handler of a frob. See ", <$format, ["link", [["node", "$help_coldc_types_frobs"]], ["Frobs"], 'do_link]>, " for more details on Frobs."], #[['links, #[["Frobs", "$help_coldc_types_frobs"]]]]]>;
var $root inited = 1;
var $root managed = [$help_func_frob_handler];


new object $help_funcs_buf: $help_coldc_func;

var $root manager = $help_funcs_buf;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Buffer", "Buffer"];
var $help_node links = #[["buf_replace()", $help_func_buf_replace], ["buf_to_str()", $help_func_buf_to_str], ["buf_to_strings()", $help_func_buf_to_strings], ["bufgraft()", $help_func_bufgraft], ["bufidx()", $help_func_bufidx], ["buflen()", $help_func_buflen], ["str_to_buf()", $help_func_str_to_buf], ["strings_to_buf()", $help_func_strings_to_buf], ["subbuf()", $help_func_subbuf]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "26%,26%,26%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_buf_replace"]], ["buf_replace()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_buf_to_str"]], ["buf_to_str()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_buf_to_strings"]], ["buf_to_strings()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_bufgraft"]], ["bufgraft()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_bufidx"]], ["bufidx()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_buflen"]], ["buflen()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_str_to_buf"]], ["str_to_buf()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_strings_to_buf"]], ["strings_to_buf()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_subbuf"]], ["subbuf()"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_buf]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_buf];
var $help_node nolist = 0;


new object $help_func_buf_replace: $help_funcs_buf;

var $root manager = $help_func_buf_replace;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "buf_replace()", "buf_replace()"];
var $help_node links = #[["bufgraft()", $help_func_bufgraft]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["BUFFER"], 'do_i]>, " buf_replace(", <$format, ["i", [], ["BUFFER buf"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER pos"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER char"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function replaces the character in the buffer at position ", <$format, ["i", [], ["pos"], 'do_i]>, " with the character specified by the integer ", <$format, ["i", [], ["char"], 'do_i]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["buf_replace(`[98, 111, 111], 1, 102)", <$format, ["br", [], [], 'do_br]>, "=> `[102, 111, 111]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_bufgraft"]], ["bufgraft()"], 'do_link]>], 'do_tt]>, " performs a similar role."], #[['this, $help_func_buf_replace]]]>;
var $root inited = 1;
var $root managed = [$help_func_buf_replace];
var $help_node nolist = 0;


new object $help_func_buf_to_str: $help_funcs_buf;

var $root manager = $help_func_buf_to_str;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "buf_to_str()", "buf_to_str()"];
var $help_node linnverts = 0;
var $root inited = 1;
var $root managed = [$help_func_buf_to_str];
var $help_node nolist = 0;
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["BUFFER"], 'do_i]>, " buf_to_str(", <$format, ["i", [], ["BUFFER buf"], 'do_i]>, "[, ", <$format, ["i", [], ["BUFFER sep"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function converts the buffer specified by buf to a list of printable strings, with a final buffer element. Each string is a line in the buffer, terminated by a newline. If any characters remain unterminated, they are placed in the last element as a buffer. The last element will always be a buffer, regarless of whether any characters are in it. ", <$format, ["np", [], [], 'do_np]>, "buf_to_strings() will alternatively split the strings based off the optional second argument. Note: it is not necessary to specify both a carriage return and a newline as the seperator--if both exist--as the newline will be sufficient to break the string, and the carriage return will be discarded as an unprintable character in the string."], #[]]>;
var $help_node links = #[];


new object $help_func_buf_to_strings: $help_funcs_buf;

var $root manager = $help_func_buf_to_strings;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "buf_to_strings()", "buf_to_strings()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " buf_to_strings(", <$format, ["i", [], ["BUFFER buf"], 'do_i]>, "[, ", <$format, ["i", [], ["BUFFER sep"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function converts the buffer specified by ", <$format, ["i", [], ["buf"], 'do_i]>, " to a list of printable strings, with a final buffer element. Each string is a line in the buffer, terminated by a newline. If any characters remain unterminated, they are placed in the last element as a buffer. The last element will always be a buffer, regardless of whether any characters are in it. ", <$format, ["np", [], [], 'do_np]>, <$format, ["tt", [], ["buf_to_strings()"], 'do_tt]>, " will alternatively split the strings based off the optional second argument. Note: it is not necessary to specify both a carriage return and a newline as the separator--if both exist--as the newline will be sufficient to break the string, and the carriage return will be discarded as an unprintable character in the string."], #[]]>;
var $root inited = 1;
var $root managed = [$help_func_buf_to_strings];
var $help_node nolist = 0;


new object $help_func_bufgraft: $help_funcs_buf;

var $root manager = $help_func_bufgraft;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "bufgraft()", "bufgraft()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["BUFFER"], 'do_i]>, " bufgraft(", <$format, ["i", [], ["BUFFER buf"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER pos"], 'do_i]>, ", ", <$format, ["i", [], ["BUFFER what"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function will graft the buffer ", <$format, ["i", [], ["what"], 'do_i]>, " into the buffer ", <$format, ["i", [], ["buf"], 'do_i]>, " at ", <$format, ["i", [], ["pos"], 'do_i]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["bufgraft(`[1, 2, 3, 4], 2, `[100, 100])", <$format, ["br", [], [], 'do_br]>, "=> `[1, 100, 100, 2, 3, 4]"], 'do_dfn]>], #[['this, $help_func_bufgraft]]]>;
var $root inited = 1;
var $root managed = [$help_func_bufgraft];
var $help_node nolist = 0;


new object $help_func_buflen: $help_funcs_buf;

var $root manager = $help_func_buflen;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "buflen()", "buflen()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " buflen(", <$format, ["i", [], ["BUFFER buf"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the length of the buffer ", <$format, ["i", [], ["buf"], 'do_i]>, "."], #[['this, $help_func_buflen]]]>;
var $root inited = 1;
var $root managed = [$help_func_buflen];
var $help_node nolist = 0;


new object $help_func_str_to_buf: $help_funcs_buf;

var $root manager = $help_func_str_to_buf;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "str_to_buf()", "str_to_buf()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["BUFFER"], 'do_i]>, " str_to_buf(", <$format, ["i", [], ["STRING str"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function converts the string specified by the argument ", <$format, ["i", [], ["str"], 'do_i]>, " to a buffer. The character sequence ", <$format, ["tt", [], ["\"\\\n\""], 'do_tt]>, " will be converted to a carriage return and line feed (ASCII 13 and 10)."], #[['this, $help_func_str_to_buf]]]>;
var $root inited = 1;
var $root managed = [$help_func_str_to_buf];
var $help_node nolist = 0;


new object $help_func_strings_to_buf: $help_funcs_buf;

var $root manager = $help_func_strings_to_buf;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "strings_to_buf()", "strings_to_buf()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["BUFFER"], 'do_i]>, " strings_to_buf(", <$format, ["i", [], ["LIST strings"], 'do_i]>, "[, ", <$format, ["i", [], ["BUFFER sep"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function builds a buffer from the strings given in the list ", <$format, ["i", [], ["strings"], 'do_i]>, ". Each string represents a line which is terminated with a carriage return and a newline (ASCII 13 and 10). If the argument ", <$format, ["i", [], ["sep"], 'do_i]>, " is specified, each string is terminated with it instead. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["strings_to_buf([\"a\", \"b\", \"c\"])", <$format, ["br", [], [], 'do_br]>, "=> `[97, 13, 10, 98, 13, 10, 99, 13, 10]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["strings_to_buf([\"a\", \"b\", \"c\"], `[9])", <$format, ["br", [], [], 'do_br]>, "=> `[97, 9, 98, 9, 99, 9]"], 'do_dfn]>], #[['this, $help_func_strings_to_buf]]]>;
var $root inited = 1;
var $root managed = [$help_func_strings_to_buf];
var $help_node nolist = 0;


new object $help_func_subbuf: $help_funcs_buf;

var $root manager = $help_func_subbuf;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "subbuf()", "subbuf()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["BUFFER"], 'do_i]>, " subbuf(", <$format, ["i", [], ["BUFFER buf"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER start"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER length"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a subrange of the buffer specified by ", <$format, ["i", [], ["buf"], 'do_i]>, ". The subrange starts at position ", <$format, ["i", [], ["start"], 'do_i]>, ", and continues ", <$format, ["i", [], ["length"], 'do_i]>, " characters. If ", <$format, ["i", [], ["length"], 'do_i]>, " is unspecified, it will continue to the end of the buffer. If ", <$format, ["i", [], ["start"], 'do_i]>, " is outside of the range of the buffer, or ", <$format, ["i", [], ["length"], 'do_i]>, " will extend past the end of the buffer, the error ", <$format, ["tt", [], ["~range"], 'do_tt]>, " is thrown. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["subbuf(`[1, 2, 3, 4], 2, 2)", <$format, ["br", [], [], 'do_br]>, "=> `[2, 3]"], 'do_dfn]>], #[['this, $help_func_subbuf]]]>;
var $root inited = 1;
var $root managed = [$help_func_subbuf];
var $help_node nolist = 0;


new object $help_func_bufidx: $help_funcs_buf;

var $root manager = $help_func_bufidx;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855393081;
var $root managed = [$help_func_bufidx];
var $has_name name = ['prop, "bufidx()", "bufidx()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " bufidx(", <$format, ["i", [], ["BUFFER buf"], 'do_i]>, ", ", <$format, ["i", [], ["BUFFER|INTEGER what"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER origin"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the position in ", <$format, ["i", [], ["buf"], 'do_i]>, " where ", <$format, ["i", [], ["what"], 'do_i]>, " exists--starting from ", <$format, ["i", [], ["origin"], 'do_i]>, "--or a zero if it does not exist. If ", <$format, ["i", [], ["origin"], 'do_i]>, " is not specified it will default to ", <$format, ["i", [], ["1"], 'do_i]>, ". If ", <$format, ["i", [], ["what"], 'do_i]>, " is an integer, it is equivalent to ", <$format, ["i", [], ["`[what]"], 'do_i]>, ". The ", <$format, ["i", [], ["origin"], 'do_i]>, " represents where to start searching in the buffer. If it is a positive number it starts that many elements into the buffer. If it is a negative number it starts that many elements from the end of the buffer, and searches backwards--from the end of the buffer to the start. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["bufidx(`[1, 7, 1, 6, 7, 1], 7)", <$format, ["br", [], [], 'do_br]>, "=> 2 ", <$format, ["np", [], [], 'do_np]>, "bufidx(`[1, 7, 1, 6, 7, 1], 7, -1)", <$format, ["br", [], [], 'do_br]>, "=> 5 ", <$format, ["np", [], [], 'do_np]>, "bufidx(`[1, 7, 1, 6, 7, 1], `[6, 7])", <$format, ["br", [], [], 'do_br]>, "=> 4 ", <$format, ["np", [], [], 'do_np]>, "bufidx(`[1, 7, 1, 6, 7, 1], `[6, 8])", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_bufidx]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_funcs_dict: $help_coldc_func;

var $root manager = $help_funcs_dict;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Dictionary", "Dictionary"];
var $help_node links = #[["dict_add()", $help_func_dict_add], ["dict_contains()", $help_func_dict_contains], ["dict_del()", $help_func_dict_del], ["dict_keys()", $help_func_dict_keys], ["dict_union()", $help_func_dict_union], ["dict_values()", $help_func_dict_values]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "25%,25%,25%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_dict_add"]], ["dict_add()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_dict_contains"]], ["dict_contains()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_dict_del"]], ["dict_del()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_dict_keys"]], ["dict_keys()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_dict_union"]], ["dict_union()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_dict_values"]], ["dict_values()"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_dict]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_dict];
var $help_node nolist = 0;


new object $help_func_dict_add: $help_funcs_dict;

var $root manager = $help_func_dict_add;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "dict_add()", "dict_add()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["DICTIONARY"], 'do_i]>, " dict_add(", <$format, ["i", [], ["DICTIONARY dict"], 'do_i]>, ", ", <$format, ["i", [], ["ANY key"], 'do_i]>, ", ", <$format, ["i", [], ["ANY value"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function adds an association to the dictionary ", <$format, ["i", [], ["dict"], 'do_i]>, ". The key and value of the association are given as the ", <$format, ["i", [], ["key"], 'do_i]>, " and ", <$format, ["i", [], ["value"], 'do_i]>, " arguments. The new dictionary is returned. If ", <$format, ["i", [], ["key"], 'do_i]>, " already exists in ", <$format, ["i", [], ["dict"], 'do_i]>, ", then the value of the existing key is replaced with ", <$format, ["i", [], ["value"], 'do_i]>, ". Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["dict_add(#[[\"foo\", \"bar\"]], 3, 'quux)", <$format, ["br", [], [], 'do_br]>, "=> #[[\"foo\", \"bar\"], [3, 'quux]]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["dict_add(#[[\"foo\", 1], [\"bar\", 2], [\"baz\", 3]], \"bar\", 4)", <$format, ["br", [], [], 'do_br]>, "=> #[[\"foo\", 1], [\"bar\", 4], [\"baz\", 3]]"], 'do_dfn]>], #[['this, $help_func_dict_add]]]>;
var $root inited = 1;
var $root managed = [$help_func_dict_add];
var $help_node nolist = 0;


new object $help_func_dict_contains: $help_funcs_dict;

var $root manager = $help_func_dict_contains;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "dict_contains()", "dict_contains()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " dict_contains(", <$format, ["i", [], ["DICTIONARY dict"], 'do_i]>, ", ", <$format, ["i", [], ["ANY key"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns 1 if there is an association in ", <$format, ["i", [], ["dict"], 'do_i]>, " with the specified key, or 0 otherwise. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["dict_contains(#[[\"foo\", \"bar\"]], \"foo\")", <$format, ["br", [], [], 'do_br]>, "=> 1"], 'do_dfn]>, " ", <$format, ["dfn", [], ["dict_contains(#[[\"foo\", \"bar\"]], \"bar\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_dict_contains]]]>;
var $root inited = 1;
var $root managed = [$help_func_dict_contains];
var $help_node nolist = 0;


new object $help_func_dict_del: $help_funcs_dict;

var $root manager = $help_func_dict_del;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "dict_del()", "dict_del()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["DICTIONARY"], 'do_i]>, " dict_del(", <$format, ["i", [], ["DICTIONARY dict"], 'do_i]>, ", ", <$format, ["i", [], ["ANY key"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function the ", <$format, ["i", [], ["key"], 'do_i]>, " ", <$format, ["i", [], ["value"], 'do_i]>, " association from the dictionary ", <$format, ["i", [], ["dict"], 'do_i]>, " and returns the result. If there is no association with the specified key, then the error ", <$format, ["tt", [], ["~keynf"], 'do_tt]>, " is thrown. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["dict_del(#[[\"foo\", 1], [\"bar\", 2]], \"foo\")", <$format, ["br", [], [], 'do_br]>, "=> #[[\"bar\", 2]]"], 'do_dfn]>], #[['this, $help_func_dict_del]]]>;
var $root inited = 1;
var $root managed = [$help_func_dict_del];
var $help_node nolist = 0;


new object $help_func_dict_keys: $help_funcs_dict;

var $root manager = $help_func_dict_keys;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "dict_keys()", "dict_keys()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " dict_keys(", <$format, ["i", [], ["DICTIONARY dict"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a correctly ordered list of the keys of the associations in ", <$format, ["i", [], ["dict"], 'do_i]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["dict_keys(#[[\"foo\", 1], [\"bar\", 2], ['baz, 3]])", <$format, ["br", [], [], 'do_br]>, "=> [\"foo\", \"bar\", 'baz]"], 'do_dfn]>], #[['this, $help_func_dict_keys]]]>;
var $root inited = 1;
var $root managed = [$help_func_dict_keys];
var $help_node nolist = 0;


new object $help_func_dict_union: $help_funcs_dict;

var $root manager = $help_func_dict_union;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855434224;
var $root managed = [$help_func_dict_union];
var $has_name name = ['prop, "dict_union()", "dict_union()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["DICTIONARY"], 'do_i]>, " dict_union(", <$format, ["i", [], ["DICTIONARY dict1"], 'do_i]>, ", ", <$format, ["i", [], ["DICTIONARY dict2"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function merges the two dictionaries by adding each association from ", <$format, ["i", [], ["dict2"], 'do_i]>, " into ", <$format, ["i", [], ["dict1"], 'do_i]>, ". In the case of conflicts, the values in ", <$format, ["i", [], ["dict2"], 'do_i]>, " take precedence. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["dict_union(#[[\"foo\", 1], ['baz, 3]], #[[\"foo\", 2], [\"bar\", 2]])", <$format, ["br", [], [], 'do_br]>, "=> #[[\"foo\", 2], ['baz, 3], [\"bar\", 2]]"], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_dict_values: $help_funcs_dict;

var $root manager = $help_func_dict_values;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855434224;
var $root managed = [$help_func_dict_values];
var $has_name name = ['prop, "dict_values()", "dict_values()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " dict_values(", <$format, ["i", [], ["DICTIONARY dict"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a correctly ordered list of the keys of the associations in ", <$format, ["i", [], ["dict"], 'do_i]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["dict_values(#[[\"foo\", 1], [\"bar\", 2], ['baz, 3]])", <$format, ["br", [], [], 'do_br]>, "=> [1, 2, 3]"], 'do_dfn]>], #[['this, $help_func_dict_values]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_funcs_list: $help_coldc_func;

var $root manager = $help_funcs_list;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "List", "List"];
var $help_node links = #[["delete()", $help_func_delete], ["insert()", $help_func_insert], ["join()", $help_func_join], ["listgraft()", $help_func_listgraft], ["listidx()", $help_func_listidx], ["listlen()", $help_func_listlen], ["replace()", $help_func_replace], ["setadd()", $help_func_setadd], ["setremove()", $help_func_setremove], ["sublist()", $help_func_sublist], ["union()", $help_func_union]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "20%,20%,20%,20%,20%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_delete"]], ["delete()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_insert"]], ["insert()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_join"]], ["join()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_listgraft"]], ["listgraft()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_listidx"]], ["listidx()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_listlen"]], ["listlen()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_replace"]], ["replace()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_setadd"]], ["setadd()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_setremove"]], ["setremove()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_sublist"]], ["sublist()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_union"]], ["union()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_list]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_list];
var $help_node nolist = 0;


new object $help_func_delete: $help_funcs_list;

var $root manager = $help_func_delete;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "delete()", "delete()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " delete(", <$format, ["i", [], ["LIST list"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER pos"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function deletes the element in the argument ", <$format, ["i", [], ["list"], 'do_i]>, ", pointed to by the position argument ", <$format, ["i", [], ["pos"], 'do_i]>, ", and returns the result. If ", <$format, ["i", [], ["position"], 'do_i]>, " is less than ", <$format, ["tt", [], ["1"], 'do_tt]>, " or is greater than the length of ", <$format, ["i", [], ["list"], 'do_i]>, ", then ", <$format, ["tt", [], ["delete()"], 'do_tt]>, " throws a ", <$format, ["tt", [], ["~range"], 'do_tt]>, " error. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["delete([2, 3, 4], 2)", <$format, ["br", [], [], 'do_br]>, "=> [2, 4]"], 'do_dfn]>], #[['this, $help_func_delete]]]>;
var $root inited = 1;
var $root managed = [$help_func_delete];
var $help_node nolist = 0;


new object $help_func_insert: $help_funcs_list;

var $root manager = $help_func_insert;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "insert()", "insert()"];
var $help_node links = #[["listgraft()", $help_func_listgraft]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " insert(", <$format, ["i", [], ["LIST list"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER pos"], 'do_i]>, ", ", <$format, ["i", [], ["ANY value"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function inserts ", <$format, ["i", [], ["value"], 'do_i]>, " into ", <$format, ["i", [], ["list"], 'do_i]>, " before the element specified by the integer ", <$format, ["i", [], ["pos"], 'do_i]>, ". If ", <$format, ["i", [], ["pos"], 'do_i]>, " is outside the range of the list, the error ", <$format, ["tt", [], ["~range"], 'do_tt]>, " is thrown. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["insert([2, 3, 4], 3, 'foo)", <$format, ["br", [], [], 'do_br]>, "=> [2, 3, 'foo, 4]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["insert([\"foo\", 'bar, ~none], 4, 'baz)", <$format, ["br", [], [], 'do_br]>, "=> [\"foo\", 'bar, ~none, 'baz]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_listgraft"]], ["listgraft()"], 'do_link]>], 'do_tt]>, " performs a similar role to ", <$format, ["tt", [], ["insert()"], 'do_tt]>, "."], #[['this, $help_func_insert]]]>;
var $root inited = 1;
var $root managed = [$help_func_insert];
var $help_node nolist = 0;


new object $help_func_join: $help_funcs_list;

var $root manager = $help_func_join;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "join()", "join()"];
var $help_node links = #[["Non Arithmetic Operators", $help_coldc_non_arith]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " join(", <$format, ["i", [], ["LIST list"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING seperator"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function joins a list together as a string. The second argument is used to specify what seperates each element in the list. If the second argument is unspecified, this will default to a single space. If any element in the list is not a string, it will have a literal representation used instead, in the same manner as when using ", <$format, ["link", [["node", "$help_coldc_non_arith"]], ["Non Arithmetic Operators"], 'do_link]>, ". Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["join([\"Joe\", \"Sally\", \"Bob\", \"Sue\"])", <$format, ["br", [], [], 'do_br]>, "=> \"Joe Sally Bob Sue\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["join([\"This\", \"That\", 'there, 10], \", \")", <$format, ["br", [], [], 'do_br]>, "=> \"This, That, there, 10\""], 'do_dfn]>], #[['this, $help_func_join]]]>;
var $root inited = 1;
var $root managed = [$help_func_join];
var $help_node nolist = 0;


new object $help_func_listgraft: $help_funcs_list;

var $root manager = $help_func_listgraft;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "listgraft()", "listgraft()"];
var $help_node links = #[["splice operator", $help_coldc_splice], ["insert()", $help_func_insert]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " listgraft(", <$format, ["i", [], ["LIST list1"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER"], 'do_i]>, " pos, ", <$format, ["i", [], ["LIST list2"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is similar to the ", <$format, ["link", [["node", "$help_coldc_splice"]], ["splice operator"], 'do_link]>, " and ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_insert"]], ["insert()"], 'do_link]>], 'do_tt]>, ", except it grafts a list into another list, rather than inserting an element at a point in the list. It will take the list specified by ", <$format, ["i", [], ["list2"], 'do_i]>, " and place each element in that list into the list specified by ", <$format, ["i", [], ["list1"], 'do_i]>, ", starting at the position specified by ", <$format, ["i", [], ["pos"], 'do_i]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["listgraft([1, 2, 3, 4, 5], 3, [\"foo\", \"bar\", \"baz\"])", <$format, ["br", [], [], 'do_br]>, "=> [1, 2, \"foo\", \"bar\", \"baz\", 3, 4, 5]"], 'do_dfn]>], #[['this, $help_func_listgraft]]]>;
var $root inited = 1;
var $root managed = [$help_func_listgraft];
var $help_node nolist = 0;


new object $help_func_listlen: $help_funcs_list;

var $root manager = $help_func_listlen;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "listlen()", "listlen()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " listlen(", <$format, ["i", [], ["LIST list"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the length of ", <$format, ["i", [], ["list"], 'do_i]>, "."], #[['this, $help_func_listlen]]]>;
var $root inited = 1;
var $root managed = [$help_func_listlen];
var $help_node nolist = 0;


new object $help_func_replace: $help_funcs_list;

var $root manager = $help_func_replace;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "replace()", "replace()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " replace(", <$format, ["i", [], ["LIST list"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER pos"], 'do_i]>, ", ", <$format, ["i", [], ["ANY value"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function replaces the element in the argument ", <$format, ["i", [], ["list"], 'do_i]>, "--pointed to by the position argument ", <$format, ["i", [], ["pos"], 'do_i]>, "--with the argument ", <$format, ["tt", [], ["value"], 'do_tt]>, ", and returns the result. If the position argument is outside the range of the list, the error ", <$format, ["tt", [], ["~range"], 'do_tt]>, " is thrown. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["replace([2, 3, 4], 2, 'foo)", <$format, ["br", [], [], 'do_br]>, "=> [2, 'foo, 4]"], 'do_dfn]>], #[['this, $help_func_replace]]]>;
var $root inited = 1;
var $root managed = [$help_func_replace];
var $help_node nolist = 0;


new object $help_func_setadd: $help_funcs_list;

var $root manager = $help_func_setadd;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "setadd()", "setadd()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " setadd(", <$format, ["tt", [], ["LIST list"], 'do_tt]>, ", ", <$format, ["i", [], ["ANY value"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function appends the argument ", <$format, ["i", [], ["value"], 'do_i]>, " to the argument ", <$format, ["i", [], ["list"], 'do_i]>, " if it is not already in the list, and returns the result. If ", <$format, ["i", [], ["value"], 'do_i]>, " is already in the list, it does not add it. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["setadd([2, 3, 4], 'foo)", <$format, ["br", [], [], 'do_br]>, "=> [2, 3, 4, 'foo]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["setadd([2, 3, 4], 3)", <$format, ["br", [], [], 'do_br]>, "=> [2, 3, 4]"], 'do_dfn]>], #[['this, $help_func_setadd]]]>;
var $root inited = 1;
var $root managed = [$help_func_setadd];
var $help_node nolist = 0;


new object $help_func_setremove: $help_funcs_list;

var $root manager = $help_func_setremove;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "setremove()", "setremove()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " setremove(", <$format, ["i", [], ["LIST list"], 'do_i]>, ", ", <$format, ["i", [], ["ANY value"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function removes the argument ", <$format, ["i", [], ["value"], 'do_i]>, " from the argument ", <$format, ["i", [], ["list"], 'do_i]>, ", if it exists, and returns the result. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["setremove([2, 3, 4, 'foo], 'foo)", <$format, ["br", [], [], 'do_br]>, "=> [2, 3, 4]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["setremove([2, 3, 4], 5)", <$format, ["br", [], [], 'do_br]>, "=> [2, 3, 4]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["setremove([2, 3, 2, 4], 2)", <$format, ["br", [], [], 'do_br]>, "=> [3, 2, 4]"], 'do_dfn]>], #[['this, $help_func_setremove]]]>;
var $root inited = 1;
var $root managed = [$help_func_setremove];
var $help_node nolist = 0;


new object $help_func_sublist: $help_funcs_list;

var $root manager = $help_func_sublist;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "sublist()", "sublist()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " sublist(", <$format, ["i", [], ["LIST list"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER start"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER length"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a subrange of the list specified by ", <$format, ["i", [], ["list"], 'do_i]>, ". The subrange starts at position ", <$format, ["i", [], ["start"], 'do_i]>, ", and continues ", <$format, ["i", [], ["length"], 'do_i]>, " elements. If ", <$format, ["i", [], ["length"], 'do_i]>, " is unspecified, it will continue to the end of the list. If ", <$format, ["i", [], ["start"], 'do_i]>, " is outside of the range of the list, or ", <$format, ["i", [], ["length"], 'do_i]>, " will extend past the end of the list, the error ", <$format, ["tt", [], ["~range"], 'do_tt]>, " is thrown. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["sublist([2, 3, 4, 5, 6, 7], 2, 3)", <$format, ["br", [], [], 'do_br]>, "=> [3, 4, 5]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["sublist([2, 3, 4, 5, 6, 7], 3)", <$format, ["br", [], [], 'do_br]>, "=> [4, 5, 6, 7]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["sublist([2, 3, 4, 5, 6, 7], 7)", <$format, ["br", [], [], 'do_br]>, "=> []"], 'do_dfn]>], #[['this, $help_func_sublist]]]>;
var $root inited = 1;
var $root managed = [$help_func_sublist];
var $help_node nolist = 0;


new object $help_func_union: $help_funcs_list;

var $root manager = $help_func_union;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "union()", "union()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " union(", <$format, ["i", [], ["LIST list1"], 'do_i]>, ", ", <$format, ["i", [], ["LIST list2"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function adds each element of ", <$format, ["i", [], ["list2"], 'do_i]>, " to ", <$format, ["i", [], ["list1"], 'do_i]>, " which does not already exist in ", <$format, ["i", [], ["list1"], 'do_i]>, ". Elements which exist more than once in ", <$format, ["i", [], ["list2"], 'do_i]>, " will only be added to ", <$format, ["i", [], ["list1"], 'do_i]>, " once, but duplicate elements in ", <$format, ["i", [], ["list1"], 'do_i]>, " will remain. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["union([2, 3, 4], [4, 5, 4, 6])", <$format, ["br", [], [], 'do_br]>, "=> [2, 3, 4, 5, 6]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["union([2, 2, 4, 5], [4, 5, 6, 6, 7])", <$format, ["br", [], [], 'do_br]>, "=> [2, 2, 4, 5, 6, 7])"], 'do_dfn]>], #[['this, $help_func_union]]]>;
var $root inited = 1;
var $root managed = [$help_func_union];
var $help_node nolist = 0;


new object $help_func_listidx: $help_funcs_list;

var $root manager = $help_func_listidx;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855452888;
var $root managed = [$help_func_listidx];
var $has_name name = ['prop, "listidx()", "listidx()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " listidx(", <$format, ["i", [], ["LIST list"], 'do_i]>, ", ", <$format, ["i", [], ["ANY what"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER origin"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the position in the ", <$format, ["i", [], ["list"], 'do_i]>, " where ", <$format, ["i", [], ["what"], 'do_i]>, " exists--starting from ", <$format, ["i", [], ["origin"], 'do_i]>, "--or a zero if it does not exist. If ", <$format, ["i", [], ["origin"], 'do_i]>, " is not specified it will default to ", <$format, ["i", [], ["1"], 'do_i]>, ". The ", <$format, ["i", [], ["origin"], 'do_i]>, " represents where to start searching in the list. If it is a positive number it starts that many elements into the list. If it is a negative number it starts that many elements from the end of the list, and searches backwards--from the end of the list to the start. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["listidx([4, \"this\", [], 'bar], [])", <$format, ["br", [], [], 'do_br]>, "=> 3"], 'do_dfn]>, " ", <$format, ["dfn", [], ["listidx([4, \"this\", [], \"this\", 'bar], \"this\", -1)", <$format, ["br", [], [], 'do_br]>, "=> 4"], 'do_dfn]>, " ", <$format, ["dfn", [], ["listidx([4, \"this\", [], \"this\", 'bar], \"this\", -3)", <$format, ["br", [], [], 'do_br]>, "=> 2"], 'do_dfn]>], #[['this, $help_func_listidx]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_funcs_str: $help_coldc_func;

var $root manager = $help_funcs_str;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "String", "String"];
var $help_node links = #[["crypt()", $help_func_crypt], ["explode()", $help_func_explode], ["lowercase()", $help_func_lowercase], ["match_begin()", $help_func_match_begin], ["match_crypted()", $help_func_match_crypted], ["match_pattern()", $help_func_match_pattern], ["match_regexp()", $help_func_match_regexp], ["match_template()", $help_func_match_template], ["pad()", $help_func_pad], ["regexp()", $help_func_regexp], ["split()", $help_func_split], ["strcmp()", $help_func_strcmp], ["strfmt()", $help_func_strfmt], ["strgraft()", $help_func_strgraft], ["stridx()", $help_func_stridx], ["strlen()", $help_func_strlen], ["strsed()", $help_func_strsed], ["strsub()", $help_func_strsub], ["substr()", $help_func_substr], ["uppercase()", $help_func_uppercase]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "26%,26%,26%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_crypt"]], ["crypt()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_explode"]], ["explode()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_lowercase"]], ["lowercase()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_match_begin"]], ["match_begin()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_match_crypted"]], ["match_crypted()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_match_pattern"]], ["match_pattern()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_match_regexp"]], ["match_regexp()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_match_template"]], ["match_template()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_pad"]], ["pad()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_regexp"]], ["regexp()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_split"]], ["split()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_strcmp"]], ["strcmp()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_strfmt"]], ["strfmt()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_strgraft"]], ["strgraft()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_stridx"]], ["stridx()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_strlen"]], ["strlen()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_strsed"]], ["strsed()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_strsub"]], ["strsub()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_substr"]], ["substr()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_uppercase"]], ["uppercase()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_str]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_str];
var $help_node nolist = 0;


new object $help_func_crypt: $help_funcs_str;

var $root manager = $help_func_crypt;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "crypt()", "crypt()"];
var $help_node links = #[["match_crypted()", $help_func_match_crypted]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " crypt(", <$format, ["i", [], ["STRING str"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING salt"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function performs one-way encryption on ", <$format, ["i", [], ["str"], 'do_i]>, ", using the SHA encryption routine. If ", <$format, ["i", [], ["salt"], 'do_i]>, " is not specified, it is chosen randomly. The return value of ", <$format, ["tt", [], ["crypt()"], 'do_tt]>, " is the encrypted string. ", <$format, ["np", [], [], 'do_np]>, "The encryption performed by this function has the property that it is very difficult to find a string which will produce a given result; however, a given string and a given salt will always yield the same encrypted string. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["crypt(\"foo\", \"ab\")", <$format, ["br", [], [], 'do_br]>, "=> \"$2$ab$TmSIW.xT3sTkwqUhTLxCH192J37\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When matching an encrypted string versus a non-encrypted string, the function ", <$format, ["link", [["node", "$help_func_match_crypted"]], ["match_crypted()"], 'do_link]>, " should be used, as it will take into consideration any possible future changes to the crypt() implementation."], #[['links, #[["match_crypted()", "$help_func_match_crypted"]]]]]>;
var $root inited = 1;
var $root managed = [$help_func_crypt];
var $help_node nolist = 0;


new object $help_func_explode: $help_funcs_str;

var $root manager = $help_func_explode;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "explode()", "explode()"];
var $help_node links = #[["split()", $help_func_split]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " explode(", <$format, ["i", [], ["STRING str"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING sep"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER want-blanks"], 'do_i]>, "]])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function breaks ", <$format, ["i", [], ["string"], 'do_i]>, " into a list of strings, using the string ", <$format, ["i", [], ["sep"], 'do_i]>, " as the delimiter. If ", <$format, ["i", [], ["sep"], 'do_i]>, " is unspecified it uses spaces as the delimiter. If ", <$format, ["i", [], ["want-blanks"], 'do_i]>, " is specified and is true ", <$format, ["tt", [], ["explode()"], 'do_tt]>, " will include zero-length strings in the final list, otherwise it will not. The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_split"]], ["split()"], 'do_link]>], 'do_tt]>, " is similar, but uses a regular expression as the delimiter. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["explode(\" foo bar baz\")", <$format, ["br", [], [], 'do_br]>, "=> [\"foo\", \"bar\", \"baz\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["explode(\"foo:bar::baz\", \":\")", <$format, ["br", [], [], 'do_br]>, "=> [\"foo\", \"bar\", \"baz\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["explode(\"foo:bar::baz\", \":\", 1)", <$format, ["br", [], [], 'do_br]>, "=> [\"foo\", \"bar\", \"\", \"baz\"]"], 'do_dfn]>], #[['this, $help_func_explode]]]>;
var $root inited = 1;
var $root managed = [$help_func_explode];
var $help_node nolist = 0;


new object $help_func_lowercase: $help_funcs_str;

var $root manager = $help_func_lowercase;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "lowercase()", "lowercase()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " lowercase(", <$format, ["i", [], ["STRING str"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function changes each character in ", <$format, ["i", [], ["str"], 'do_i]>, " to it's lowercase value and returns the result."], #[['this, $help_func_lowercase]]]>;
var $root inited = 1;
var $root managed = [$help_func_lowercase];
var $help_node nolist = 0;


new object $help_func_match_begin: $help_funcs_str;

var $root manager = $help_func_match_begin;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "match_begin()", "match_begin()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " match_begin(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["STRING search"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING sep"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function looks for the string ", <$format, ["i", [], ["search"], 'do_i]>, " at the beginning of each word in ", <$format, ["i", [], ["str"], 'do_i]>, ". The word separator is given by the string ", <$format, ["i", [], ["sep"], 'do_i]>, " if it is specified; otherwise, a space (", <$format, ["tt", [], ["\" \""], 'do_tt]>, ") is used. The return value of ", <$format, ["tt", [], ["match_begin()"], 'do_tt]>, " is ", <$format, ["tt", [], ["1"], 'do_tt]>, " if ", <$format, ["i", [], ["search"], 'do_i]>, " was found at the beginning of a word in ", <$format, ["i", [], ["string"], 'do_i]>, ", or ", <$format, ["tt", [], ["0"], 'do_tt]>, " if not. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["match_begin(\"foo:bar:baz\", \"fo\", \":\")", <$format, ["br", [], [], 'do_br]>, "=> 1"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_begin(\"foo bar baz\", \"ar\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_match_begin]]]>;
var $root inited = 1;
var $root managed = [$help_func_match_begin];
var $help_node nolist = 0;


new object $help_func_match_pattern: $help_funcs_str;

var $root manager = $help_func_match_pattern;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "match_pattern()", "match_pattern()"];
var $help_node links = #[["Matching Conventions", $help_commands_matching]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " match_pattern(", <$format, ["i", [], ["STRING string"], 'do_i]>, ", ", <$format, ["i", [], ["STRING pattern"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function matches the wildcard pattern ", <$format, ["i", [], ["pattern"], 'do_i]>, " against ", <$format, ["i", [], ["string"], 'do_i]>, ". A wildcard pattern is a string with asterixes (", <$format, ["tt", [], ["`*'"], 'do_tt]>, ") signifying wildcards. A regular character matches itself, while a wildcard matches any number of arbitrary characters. The return value of ", <$format, ["tt", [], ["match_pattern()"], 'do_tt]>, " is a list of the substrings of ", <$format, ["i", [], ["string"], 'do_i]>, " which matched the wildcards in ", <$format, ["i", [], ["pattern"], 'do_i]>, ", or ", <$format, ["tt", [], ["0"], 'do_tt]>, " if the match fails. More information on pattern matching can be found in the section ", <$format, ["link", [["node", "$help_commands_matching"]], ["Matching Conventions"], 'do_link]>, ". Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["match_pattern(\"foobar\", \"*\")", <$format, ["br", [], [], 'do_br]>, "=> [\"foobar\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_pattern(\"foo quux bar quuux baz\", \"foo * bar * baz\")", <$format, ["br", [], [], 'do_br]>, "=> [\"quux\", \"quuux\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_pattern(\"narf:fnord\", \"narf:*\")", <$format, ["br", [], [], 'do_br]>, "=> [\"fnord\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_pattern(\"foo baz\", \"foo * bar\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_match_pattern]]]>;
var $root inited = 1;
var $root managed = [$help_func_match_pattern];
var $help_node nolist = 0;


new object $help_func_match_regexp: $help_funcs_str;

var $root manager = $help_func_match_regexp;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "match_regexp()", "match_regexp()"];
var $help_node links = #[["regexp()", $help_func_regexp], ["ColdC Regular Expressions", $help_func_regexp]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " match_regexp(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["STRING regexp"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER cs"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function matches the regular expression argument ", <$format, ["i", [], ["regexp"], 'do_i]>, " against the argument ", <$format, ["i", [], ["str"], 'do_i]>, ". If ", <$format, ["i", [], ["cs"], 'do_i]>, " is specified and is true, the match is case-sensitive; otherwise, it is case-insensitive. If the match succeeds, ", <$format, ["tt", [], ["match_regexp()"], 'do_tt]>, " returns a ten-element list giving the substitutions for the match (see below); otherwise, ", <$format, ["tt", [], ["match_regexp()"], 'do_tt]>, " returns 0. If the argument ", <$format, ["i", [], ["regexp"], 'do_i]>, " is not a valid regular expression, the error ", <$format, ["tt", [], ["~regexp"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "This function is often used when all that is desired is whether a match was made or not. The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_regexp"]], ["regexp()"], 'do_link]>], 'do_tt]>, " is better for handling the full results of a regexp match. For more information on ColdC Regular Expressions see the section ", <$format, ["link", [["node", "$help_func_regexp"]], ["ColdC Regular Expressions"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "The substitutions are the text in ", <$format, ["i", [], ["str"], 'do_i]>, " which matches the parenthesized subexpressions in ", <$format, ["i", [], ["regexp"], 'do_i]>, ". The first substitution is the text in ", <$format, ["i", [], ["str"], 'do_i]>, " which matches the whole regexp. Thus, a regular expression can contain no more than nine parenthesized subexpressions. Substitutions are returned as two-element lists ", <$format, ["tt", [], [<$format, ["i", [], ["[start, len]"], 'do_i]>], 'do_tt]>, " giving the index of the matching text in ", <$format, ["i", [], ["str"], 'do_i]>, " and the length of the text. ", <$format, ["np", [], [], 'do_np]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["match_regexp(\"fooBAR\", \"bar\")", <$format, ["br", [], [], 'do_br]>, "=> [[4, 3], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_regexp(\"Greg says, 'Hello.'\", \"^([^ ]+) says, '(.*)'$\")", <$format, ["br", [], [], 'do_br]>, "=> [[1, 19], [1, 4], [13, 6], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_regexp(\" 300 100 200 \", \"[0-9]+\")", <$format, ["br", [], [], 'do_br]>, "=> [[2, 3], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_regexp(\"foo\", \"bar\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_regexp(\"Foo\", \"foo\", 1)", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_match_regexp]]]>;
var $root inited = 1;
var $root managed = [$help_func_match_regexp];
var $help_node nolist = 0;


new object $help_func_match_template: $help_funcs_str;

var $root manager = $help_func_match_template;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "match_template()", "match_template()"];
var $help_node links = #[["Matching Conventions", $help_commands_matching]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " match_template(", <$format, ["i", [], ["STRING string"], 'do_i]>, ", ", <$format, ["i", [], ["STRING template"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function matches the template ", <$format, ["i", [], ["template"], 'do_i]>, " against the command ", <$format, ["i", [], ["string"], 'do_i]>, ". The return value of ", <$format, ["tt", [], ["match_template()"], 'do_tt]>, " is a list of fields resulting from the template match, or ", <$format, ["tt", [], ["0"], 'do_tt]>, " if the match fails or if ", <$format, ["i", [], ["template"], 'do_i]>, " is an invalid template. ", <$format, ["np", [], [], 'do_np]>, "General information on matching can be found in the section ", <$format, ["link", [["node", "$help_commands_matching"]], ["Matching Conventions"], 'do_link]>, ". Templates are composed of ", <$format, ["i", [], ["word-patterns"], 'do_i]>, " and ", <$format, ["i", [], ["wildcards"], 'do_i]>, ". ", <$format, ["i", [], ["Word-patterns"], 'do_i]>, " may contain a mix of the ", <$format, ["i", [], ["partial-match"], 'do_i]>, " operator and the ", <$format, ["i", [], ["or"], 'do_i]>, " operator. ", <$format, ["np", [], [], 'do_np]>, "A ", <$format, ["i", [], ["word-pattern"], 'do_i]>, " is any sequence of characters bounded by spaces, or the beginning or end of the string. The pattern may include a question mark (", <$format, ["tt", [], ["'?'"], 'do_tt]>, "), which is the ", <$format, ["i", [], ["partial-match"], 'do_i]>, " operator; or it may include any number of pipe characters (", <$format, ["tt", [], ["'|'"], 'do_tt]>, "), which is the ", <$format, ["i", [], ["or"], 'do_i]>, " operator. The result from a word-pattern match is the string which matched the word-pattern. ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["i", [], ["partial-match"], 'do_i]>, " operator is used to indicate that partial matches that extend at least as far as the question mark are ok. For instance, the ", <$format, ["i", [], ["word-pattern"], 'do_i]>, " ", <$format, ["tt", [], ["\"ex?am\""], 'do_tt]>, " matches any of the words ", <$format, ["tt", [], ["\"ex\""], 'do_tt]>, ", ", <$format, ["tt", [], ["\"exa\""], 'do_tt]>, " and ", <$format, ["tt", [], ["\"exam\""], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["i", [], ["or"], 'do_i]>, " operator is used to group more than one word where any of the words in the group can be matched as one word. For instance, the template ", <$format, ["tt", [], ["\"this|that|there\""], 'do_tt]>, " would match ", <$format, ["tt", [], ["\"this\""], 'do_tt]>, " ", <$format, ["i", [], ["OR"], 'do_i]>, " ", <$format, ["tt", [], ["\"that\""], 'do_tt]>, " ", <$format, ["i", [], ["OR"], 'do_i]>, " ", <$format, ["tt", [], ["\"there\""], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["i", [], ["Wildcards"], 'do_i]>, " can be either ", <$format, ["i", [], ["simple"], 'do_i]>, " or ", <$format, ["i", [], ["coupled"], 'do_i]>, ". A ", <$format, ["i", [], ["simple wildcard"], 'do_i]>, " is represented by an asterix (", <$format, ["tt", [], ["'*'"], 'do_tt]>, "). A simple wildcard matches any number of words in ", <$format, ["i", [], ["string"], 'do_i]>, ", and must be bounded by spaces or the beginning or end of the template. If the wildcard is followed in the template by a word-pattern, then it can also match a ", <$format, ["i", [], ["quoted wildcard match"], 'do_i]>, ". ", <$format, ["np", [], [], 'do_np]>, "A quoted wildcard match is just like a ColdC string literal: it begins and ends with a double quote (", <$format, ["tt", [], ["'\"'"], 'do_tt]>, "), and can include a literal double quote or backslash by preceding the character with a backslash (", <$format, ["tt", [], ["'\'"], 'do_tt]>, "). If the simple wildcard is followed by a word-pattern, and the words in ", <$format, ["i", [], ["string"], 'do_i]>, " that the wildcard would match begin with a double quote, then the match must be a quoted wildcard match or the match fails, even if the match would have succeeded if the words were not treated as a quoted wildcard match. However, if the words that the wildcard would match begin with a backslash followed by a double quote, then the backslash is ignored and the double quote and the text following it are treated as regular words. ", <$format, ["np", [], [], 'do_np]>, "The following template using a ", <$format, ["i", [], ["simple wildcard"], 'do_i]>, " ", <$format, ["tt", [], ["\"* bar\""], 'do_tt]>, " matches any of the following strings:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["foo bar", <$format, ["br", [], [], 'do_br]>, "foo baz bar", <$format, ["br", [], [], 'do_br]>, "\"foo bar \" baz\" bar", <$format, ["br", [], [], 'do_br]>, "\"foo baz bar"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Matching against a simple wildcard produces one result per wildcard--the words that the simple wildcard matched. If the wildcard matches a quoted wildcard match, then the beginning and ending double quotes are stripped out of the result, as well as any backslashes used to escape characters inside the double quotes. ", <$format, ["np", [], [], 'do_np]>, "A ", <$format, ["i", [], ["coupled wildcard"], 'do_i]>, " is represented by the three-character sequence ", <$format, ["tt", [], ["'*=*'"], 'do_tt]>, ". It matches any sequence of words containing an equal sign (", <$format, ["tt", [], ["'='"], 'do_tt]>, "), and results in two strings, the text before the equal sign and the text after it. Any spaces surrounding the equal sign in the matched string are ignored and do not show up in the results. The text before the equal sign can be a quoted wildcard match (as before, if it begins with a double quote, then it must be a quoted wildcard match or the match fails, unless the initial double quote is escaped by a backslash). If the coupled wildcard is followed by a word pattern, then the text after the equal sign can also be a quoted wildcard match. The coupled wildcard is a special feature intended for parsing TinyMUD command formats. ", <$format, ["np", [], [], 'do_np]>, " Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["match_template(\"@descr me as foobar\", \"@desc?ribe * as *\")", <$format, ["br", [], [], 'do_br]>, "=> [\"@descr\", \"me\", \"as\", \"foobar\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_template(\"@desc \\\"as is\\\" as foobar\", \"@desc?ribe * as *\")", <$format, ["br", [], [], 'do_br]>, "=> [\"@desc\", \"as is\", \"as\", \"foobar\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_template(\"@desc \\\"as\\\" is as foobar\", \"@desc?ribe * as *\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_template(\"@desc \\\"as\" is as foobar\", \"@desc?ribe * as *\")", <$format, ["br", [], [], 'do_br]>, "=> [\"@desc\", \"\\\"as\\\" is\", \"as\", \"foobar\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_template(\"@descr me =foobar\", \"@desc?ribe *=*\")", <$format, ["br", [], [], 'do_br]>, "=> [\"@descr\", \"me\", \"foobar\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_template(\"@desc \"2+2=4\"= an equation\", \"@desc?ribe *=*\")", <$format, ["br", [], [], 'do_br]>, "=> [\"@desc\", \"2+2=4\", \"an equation\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_template(\"look at rose\", \"l?ook|ex?amine *\")", <$format, ["br", [], [], 'do_br]>, "=> [\"look\", \"at rose\"]"], 'do_dfn]>], #[['this, $help_func_match_template]]]>;
var $root inited = 1;
var $root managed = [$help_func_match_template];
var $help_node nolist = 0;


new object $help_func_pad: $help_funcs_str;

var $root manager = $help_func_pad;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "pad()", "pad()"];
var $help_node links = #[["strfmt()", $help_func_strfmt]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " pad(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER length"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING filler"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function pads or truncates the argument ", <$format, ["i", [], ["string"], 'do_i]>, " to the length given with the argument ", <$format, ["i", [], ["length"], 'do_i]>, ". If the argument ", <$format, ["i", [], ["filler"], 'do_i]>, " is specified, then it is used to pad the string, otherwise a space is used. If ", <$format, ["i", [], ["length"], 'do_i]>, " is greater than the length of ", <$format, ["i", [], ["string"], 'do_i]>, ", then ", <$format, ["i", [], ["pad"], 'do_i]>, " adds filler characters on the right. If the length is a negative amount, filler will be added on the left instead. The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_strfmt"]], ["strfmt()"], 'do_link]>], 'do_tt]>, " may also be used for string padding. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["pad(\"foo\", 6)", <$format, ["br", [], [], 'do_br]>, "=> \"foo \""], 'do_dfn]>, " ", <$format, ["dfn", [], ["pad(\"foobar\", 3)", <$format, ["br", [], [], 'do_br]>, "=> \"foo\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["pad(tostr(29), -4, \"0\")", <$format, ["br", [], [], 'do_br]>, "=> \"0029\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["pad(\"what\", 20, \"!?!\")", <$format, ["br", [], [], 'do_br]>, "=> \"what!?!!?!!?!!?!!?!!\""], 'do_dfn]>], #[['this, $help_func_pad]]]>;
var $root inited = 1;
var $root managed = [$help_func_pad];
var $help_node nolist = 0;


new object $help_func_regexp: $help_funcs_str;

var $root manager = $help_func_regexp;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "regexp()", "regexp()"];
var $help_node links = #[["ColdC Regular Expressions", $help_coldc_regexp], ["match_regexp()", $help_func_match_regexp]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " regexp(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["STRING regexp"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER cs"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function matches the regular expression argument ", <$format, ["i", [], ["regexp"], 'do_i]>, " against the argument ", <$format, ["i", [], ["str"], 'do_i]>, ". If ", <$format, ["i", [], ["cs"], 'do_i]>, " is specified and is true, the match is case-sensitive; otherwise, it is case-insensitive. If the match succeeds, ", <$format, ["tt", [], ["regexp()"], 'do_tt]>, " returns a list of the matches in ", <$format, ["i", [], ["string"], 'do_i]>, ", or zero if it did not match. If ", <$format, ["i", [], ["regexp"], 'do_i]>, " is not a valid regular expression the error ", <$format, ["tt", [], ["~regexp"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "For more information on Regular Expressions see the section ", <$format, ["link", [["node", "$help_coldc_regexp"]], ["ColdC Regular Expressions"], 'do_link]>, ". The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_match_regexp"]], ["match_regexp()"], 'do_link]>], 'do_tt]>, " is similar, and better when all that is desired is whether the regexp matches or not. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["regexp(\"fooBAR\", \"bar\")", <$format, ["br", [], [], 'do_br]>, "=> [\"BAR\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["regexp(\"Greg says, 'Hello.'\", \"^([^ ]+) says, '(.*)'$\")", <$format, ["br", [], [], 'do_br]>, "=> [\"Greg\", \"Hello.\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["regexp(\" 300 100 200 \", \"[0-9]+\")", <$format, ["br", [], [], 'do_br]>, "=> [\"300\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["regexp(\"bar\", \"foo\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>, " ", <$format, ["dfn", [], ["regexp(\"Foo\", \"foo\", 1)", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['links, #[["ColdC Regular Expressions", "$help_coldc_regexp"], ["match_regexp()", "$help_func_match_regexp"]]]]]>;
var $root inited = 1;
var $root managed = [$help_func_regexp];
var $help_node nolist = 0;


new object $help_func_strcmp: $help_funcs_str;

var $root manager = $help_func_strcmp;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "strcmp()", "strcmp()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " strcmp(", <$format, ["i", [], ["STRING str1"], 'do_i]>, ", ", <$format, ["i", [], ["STRING str2"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function compares ", <$format, ["i", [], ["str1"], 'do_i]>, " against ", <$format, ["i", [], ["str2"], 'do_i]>, " and returns zero if they are equal, greater than zero if ", <$format, ["i", [], ["string1"], 'do_i]>, " is lexically greater than ", <$format, ["i", [], ["string2"], 'do_i]>, ", and less than zero if ", <$format, ["i", [], ["string1"], 'do_i]>, " is lexically less than ", <$format, ["i", [], ["string2"], 'do_i]>, ". The comparison performed by ", <$format, ["tt", [], ["strcmp()"], 'do_tt]>, " is case-sensitive. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["strcmp(\"Foo\", \"bar\")", <$format, ["br", [], [], 'do_br]>, "=> -28"], 'do_dfn]>, " ", <$format, ["dfn", [], ["strcmp(\"cashmir\", \"cashmiR\")", <$format, ["br", [], [], 'do_br]>, "=> 32"], 'do_dfn]>, " ", <$format, ["dfn", [], ["strcmp(\"foo\", \"foo\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_strcmp]]]>;
var $root inited = 1;
var $root managed = [$help_func_strcmp];
var $help_node nolist = 0;


new object $help_func_strfmt: $help_funcs_str;

var $root manager = $help_func_strfmt;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "strfmt()", "strfmt()"];
var $help_node links = #[["using the arithmetic operator", $help_coldc_non_arith]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " strfmt(", <$format, ["i", [], ["STRING format"], 'do_i]>, ", ", <$format, ["i", [], ["ANY arg"], 'do_i]>, ", ", <$format, ["i", [], ["..."], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function formats its arguments and returns the result. How the arguments are formatted depends upon the argument ", <$format, ["i", [], ["format"], 'do_i]>, ". The format contains two types of sequences: plain characters, which are simply copied to the new string, and format specifications, each of which causes printing of the next successive argument. The format begins with a percent character (", <$format, ["tt", [], ["%"], 'do_tt]>, "), followed by:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], ["Pad Length"], 'do_dt]>, <$format, ["dd", [], ["The pad length is an integer which specifies the length of characters to pad the argument in. Pad Length is optional. Specifying a zero pad length will be ignored, and is equivalent to not specifying a pad length."], 'do_dd]>, <$format, ["dt", [], ["Precision"], 'do_dt]>, <$format, ["dd", [], ["A period (", <$format, ["tt", [], ["."], 'do_tt]>, "), followed by an integer specifies the precision, which specifies the number of digits to appear after the decimal point when printing FLOAT arguments. Precision is optional, and does not have to be specified. If it is specified it must come after the Pad Length (if specified), and before the Filler (if specified) or Format Type."], 'do_dd]>, <$format, ["dt", [], ["Filler"], 'do_dt]>, <$format, ["dd", [], ["Filler specifies what is used when padding a string within the Pad Length. Filler is specified within curly braces (", <$format, ["tt", [], ["{"], 'do_tt]>, " and ", <$format, ["tt", [], ["}"], 'do_tt]>, "). To include a curly brace in the filler prefix it with a backslash. The Filler must come after Pad Length or Precision, if they are specified, and before Format Type."], 'do_dd]>, <$format, ["dt", [], ["Format Type"], 'do_dt]>, <$format, ["dd", [], ["Format type must be specified last, and is not optional. Format Type specifies how the argument is to be handled. It is one of the following characters:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["b", [], ["d"], 'do_b]>, " or ", <$format, ["b", [], ["D"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["literal data"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["s"], 'do_b]>, " or ", <$format, ["b", [], ["S"], 'do_b]>, " or ", <$format, ["b", [], ["l"], 'do_b]>, " or ", <$format, ["b", [], ["L"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["any data, align left"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["r"], 'do_b]>, " or ", <$format, ["b", [], ["R"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["any data, align right"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["c"], 'do_b]>, " or ", <$format, ["b", [], ["C"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["any data, align centered "], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["e"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["any data, align left with an elipse"], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "If the Format Type is anything but ", <$format, ["b", [], ["d"], 'do_b]>, " or ", <$format, ["b", [], ["D"], 'do_b]>, ", the data will be converted as if it were \"added\" to a string ", <$format, ["link", [["node", "$help_coldc_non_arith"]], ["using the arithmetic operator"], 'do_link]>, ". If an uppercase character is used in the Format Type, any argument which has a length longer than the Pad Length will be truncated accordingly. Otherwise the argument will not be truncated. If an elipse is used, the argument will always be truncated three characters shorter than the Pad Length, with ", <$format, ["tt", [], ["\"...\""], 'do_tt]>, " being placed at the end."], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["strfmt(\"%r\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"test\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%l\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"test\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%c\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"test\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%d\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"\"test\"\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10r\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \" test\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10l\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"test \""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10c\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \" test \""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10{|>}r\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"|>|>|>test\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10{|>}l\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"test|>|>|>\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10{|>}c\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"|>|test|>|\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%.2l\", 1.1214)", <$format, ["br", [], [], 'do_br]>, "=> \"1.12\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10.3{0}r\", 1.1214)", <$format, ["br", [], [], 'do_br]>, "=> \"000001.121\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10.3{0}r\", 1.1214)", <$format, ["br", [], [], 'do_br]>, "=> \"1.12100000\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%5e\", \"testing\")", <$format, ["br", [], [], 'do_br]>, "=> \"te...\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%s parents: %25e\", \"$user\", [$body, $interaction, $mail_ui]);", <$format, ["br", [], [], 'do_br]>, "=> \"$user parents: [$body, $interaction, ...\""], 'do_dfn]>], #[['this, $help_func_strfmt]]]>;
var $root inited = 1;
var $root managed = [$help_func_strfmt];
var $help_node nolist = 0;


new object $help_func_strgraft: $help_funcs_str;

var $root manager = $help_func_strgraft;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "strgraft()", "strgraft()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " strgraft(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER pos"], 'do_i]>, ", ", <$format, ["i", [], ["STRING str2"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function grafts a string into another string. It will take the string specified by ", <$format, ["i", [], ["str2"], 'do_i]>, " and insert it into ", <$format, ["i", [], ["str"], 'do_i]>, ", starting at the position specified by ", <$format, ["i", [], ["pos"], 'do_i]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["strgraft(\"this string\", 6, \"is a \")", <$format, ["br", [], [], 'do_br]>, "=> \"this is a string\""], 'do_dfn]>], #[['this, $help_func_strgraft]]]>;
var $root inited = 1;
var $root managed = [$help_func_strgraft];
var $help_node nolist = 0;


new object $help_func_strlen: $help_funcs_str;

var $root manager = $help_func_strlen;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "strlen()", "strlen()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " strlen(", <$format, ["i", [], ["STRING string"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the length of ", <$format, ["i", [], ["string"], 'do_i]>, "."], #[['this, $help_func_strlen]]]>;
var $root inited = 1;
var $root managed = [$help_func_strlen];
var $help_node nolist = 0;


new object $help_func_strsed: $help_funcs_str;

var $root manager = $help_func_strsed;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "strsed()", "strsed()"];
var $help_node links = #[["Regular Expressions", $help_coldc_regexp]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STR"], 'do_i]>, " strsed(", <$format, ["i", [], ["STR rx"], 'do_i]>, ", ", <$format, ["i", [], ["STR str"], 'do_i]>, ", ", <$format, ["i", [], ["STR replace"], 'do_i]>, "[, ", <$format, ["i", [], ["STR flags"], 'do_i]>, "[, ", <$format, ["i", [], ["INT count"], 'do_i]>, "]])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This functions similar ", <$format, ["tt", [], ["sed"], 'do_tt]>, " in many unix systems. It searches for any occurances of ", <$format, ["i", [], ["regexp"], 'do_i]>, " in ", <$format, ["i", [], ["string"], 'do_i]>, " and replaces them with ", <$format, ["i", [], ["replace"], 'do_i]>, ", returning the result. The optional fourth argument is used to specify flags for sed. Flags are specified as a string containing any of the following alphabetic characters: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "5%,95%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["g"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Match the regular expression globally througout the string"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["s"], 'do_b]>, "*"], 'do_td]>, <$format, ["td", [], ["Single match--Match the first occurance only (default)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["c"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Case matters when matching"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["i"], 'do_b]>, "*"], 'do_td]>, <$format, ["td", [], ["Case doesn't matter when matching (default)"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Flags followed by an asterisk (*) represent default behaviour if no flags are specified. For more information, see the section on ", <$format, ["link", [["node", "$help_coldc_regexp"]], ["Regular Expressions"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["strsed(\"foObar\", \"o+\", \"X\")", <$format, ["br", [], [], 'do_br]>, "=> \"fXbar\" ", <$format, ["np", [], [], 'do_np]>, "strsed(\"foObar\", \"o+\", \"X\", \"c\")", <$format, ["br", [], [], 'do_br]>, "=> \"fXObar\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The string ranges matched by the regular expression n the first string may be re-inserted into the resulting string by using '%n' tokens, where n represents the branch, from one to nine. This currently only works with branched regular expressions. Future revisions will expand upon this functionality. ", <$format, ["np", [], [], 'do_np]>, "Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["strsed(\"foObar\", \"(o+)\", \"<%1>\")", <$format, ["br", [], [], 'do_br]>, "=> \"fXbar\" ", <$format, ["np", [], [], 'do_np]>, "strsed(\"foObar\", \"(o+)\", \"<%1>\", \"c\")", <$format, ["br", [], [], 'do_br]>, "=> \"fXObar\""], 'do_dfn]>, " ", <$format, ["np", [], [], 'do_np]>, "The fifth argument ", <$format, ["i", [], ["count"], 'do_i]>, " is intended to optimize the use of this function, and is generally not used. It is simply an optimizing guideline which specifies how many expected occurances of the regular expression are expected in the string. This value is used when computing the initial size of the resulting string, to lower the amount of memory allocations which may have to be performed."], #[['links, #[["Regular Expressions", "$help_coldc_regexp"]]]]]>;
var $root inited = 1;
var $root managed = [$help_func_strsed];
var $help_node nolist = 0;


new object $help_func_strsub: $help_funcs_str;

var $root manager = $help_func_strsub;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "strsub()", "strsub()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " strsub(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["STRING what"], 'do_i]>, ", ", <$format, ["i", [], ["STRING replace"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING flags"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function searches for occurances of the string ", <$format, ["i", [], ["what"], 'do_i]>, " within the string ", <$format, ["i", [], ["str"], 'do_i]>, " and replaces them with ", <$format, ["i", [], ["replace"], 'do_i]>, ". By default it will replace any occurance, and will do case-insensitive comparisons. The optional fourth argument can be any of the following characters within the string: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "5%,95%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["g"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Match globally througout the string (default)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["s"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Single match--Match the first occurance only"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["c"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Case matters when matching"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["i"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Case doesn't matter when matching (default)"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["strsub(\"fooBar\", \"bar\", \"baz\")", <$format, ["br", [], [], 'do_br]>, "=> \"foobaz\" ", <$format, ["np", [], [], 'do_np]>, "strsub(\"fooBar\", \"bar\", \"baz\", \"c\")", <$format, ["br", [], [], 'do_br]>, "=> \"fooBar\""], 'do_dfn]>], #[['this, $help_func_strsub]]]>;
var $root inited = 1;
var $root managed = [$help_func_strsub];
var $help_node nolist = 0;


new object $help_func_substr: $help_funcs_str;

var $root manager = $help_func_substr;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "substr()", "substr()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " substr(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER start"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER length"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a subrange of ", <$format, ["i", [], ["string"], 'do_i]>, ". The subrange starts at the character specified by ", <$format, ["i", [], ["start"], 'do_i]>, " and continues ", <$format, ["i", [], ["length"], 'do_i]>, " characters. If ", <$format, ["i", [], ["length"], 'do_i]>, " is unspecified it continues to the end of the string. If ", <$format, ["i", [], ["start"], 'do_i]>, " is outside of the range of the string, or ", <$format, ["i", [], ["length"], 'do_i]>, " will extend past the end of the string, the error ", <$format, ["tt", [], ["~range"], 'do_tt]>, " is thrown. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["substr(\"foobar\", 2, 3)", <$format, ["br", [], [], 'do_br]>, "=> \"oob\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["substr(\"foobar\", 3)", <$format, ["br", [], [], 'do_br]>, "=> \"obar\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["substr(\"foobar\", 7)", <$format, ["br", [], [], 'do_br]>, "=> \"\""], 'do_dfn]>], #[['this, $help_func_substr]]]>;
var $root inited = 1;
var $root managed = [$help_func_substr];
var $help_node nolist = 0;


new object $help_func_uppercase: $help_funcs_str;

var $root manager = $help_func_uppercase;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "uppercase()", "uppercase()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " uppercase(", <$format, ["i", [], ["STRING str"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function changes each character in ", <$format, ["i", [], ["str"], 'do_i]>, " to it's uppercase value and returns the result."], #[['this, $help_func_uppercase]]]>;
var $root inited = 1;
var $root managed = [$help_func_uppercase];
var $help_node nolist = 0;


new object $help_func_match_crypted: $help_funcs_str;

var $root manager = $help_func_match_crypted;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855385456;
var $root managed = [$help_func_match_crypted];
var $has_name name = ['prop, "match_crypted()", "match_crypted()"];
var $help_node links = #[["crypt()", $help_func_crypt]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " match_crypted(", <$format, ["i", [], ["STRING crypted"], 'do_i]>, ", ", <$format, ["i", [], ["STRING matchwith"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used to match strings encrypted with the ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_crypt"]], ["crypt()"], 'do_link]>], 'do_tt]>, " function. This function should be used instead of directly comparing the result, as it will take into account possible older encryption methods. It returns one if there is a correct match, or zero if there is not. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["match_crypted(\"$SHA1$dEqOGo3d$.lpP/K19QevbwpgSiCsGVnCnrv2\", \"foo\")", <$format, ["br", [], [], 'do_br]>, "=> 1"], 'do_dfn]>], #[['this, $help_func_match_crypted]]]>;
var $root inited = 1;
var $help_node index = $help_index_function;
var $help_node nolist = 0;


new object $help_func_split: $help_funcs_str;

var $root manager = $help_func_split;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855434905;
var $root managed = [$help_func_split];
var $has_name name = ['prop, "split()", "split()"];
var $help_node links = #[["regular expression", $help_coldc_regexp]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " split(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["STRING regexp"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER regexp-args"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function breaks ", <$format, ["i", [], ["string"], 'do_i]>, " into a list of strings, using the second argument ", <$format, ["i", [], ["regexp"], 'do_i]>, " (a ", <$format, ["link", [["node", "$help_coldc_regexp"]], ["regular expression"], 'do_link]>, ") as a delimiter. The third argument is optional, and is a string containing character flags which can change the behaviour of ", <$format, ["tt", [], ["split()"], 'do_tt]>, ". Flags can be any: ", <$format, ["dfn", [["ind", "4"], ["nobound", 1]], [<$format, ["table", [["cols", "5%,95%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["b"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Keep blank entries (default is to ignore)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["c"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Case sensitive match"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["i"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Case insensitive match (default)"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["split(\" foo bar baz\", \" +\")", <$format, ["br", [], [], 'do_br]>, "=> [\"foo\", \"bar\", \"baz\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["split(\"foo:bar::baz\", \":\", \"b\")", <$format, ["br", [], [], 'do_br]>, "=> [\"foo\", \"bar\", \"\", \"baz\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["split(\"fobibobIbidilly\", \"i\")", <$format, ["br", [], [], 'do_br]>, "=> [\"fob\", \"bob\", \"b\", \"d\", \"lly\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["split(\"fobIbobibidIlly\", \"i\", \"cb\")", <$format, ["br", [], [], 'do_br]>, "=> [\"fobIbob\", \"b\", \"dIlly\"]"], 'do_dfn]>], #[['this, $help_func_split]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_stridx: $help_funcs_str;

var $root manager = $help_func_stridx;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855767859;
var $root managed = [$help_func_stridx];
var $has_name name = ['prop, "stridx()", "stridx()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " stridx(", <$format, ["i", [], ["BUFFER str"], 'do_i]>, ", ", <$format, ["i", [], ["STRING what"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER origin"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the position in ", <$format, ["i", [], ["str"], 'do_i]>, " where ", <$format, ["i", [], ["what"], 'do_i]>, " exists--starting from ", <$format, ["i", [], ["origin"], 'do_i]>, "--or a zero if it does not exist. If ", <$format, ["i", [], ["origin"], 'do_i]>, " is not specified it will default to ", <$format, ["i", [], ["1"], 'do_i]>, ". The ", <$format, ["i", [], ["origin"], 'do_i]>, " represents where to start searching in the string. If it is a positive number it starts that many elements into the string. If it is a negative number it starts that many elements from the end of the string, and searches backwards--from the end of the string to the start. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["stridx(\"this test ok\", \"e\")", <$format, ["br", [], [], 'do_br]>, "=> 7 ", <$format, ["np", [], [], 'do_np]>, "stridx(\"this test ok\", \"t\", -1)", <$format, ["br", [], [], 'do_br]>, "=> 9 ", <$format, ["np", [], [], 'do_np]>, "stridx(\"this test ok\", \"t\", -5)", <$format, ["br", [], [], 'do_br]>, "=> 6 ", <$format, ["np", [], [], 'do_np]>, "stridx(\"this test ok\", \"alf\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_stridx]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_funcs_num: $help_coldc_func;

var $root manager = $help_funcs_num;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Numeric", "Numeric"];
var $help_node links = #[["abs()", $help_func_abs], ["acos()", $help_func_math], ["asin()", $help_func_math], ["atan()", $help_func_math], ["atan2()", $help_func_math], ["cos()", $help_func_math], ["exp()", $help_func_math], ["log()", $help_func_math], ["Math", $help_func_math], ["max()", $help_func_max], ["min()", $help_func_min], ["pow()", $help_func_math], ["random()", $help_func_random], ["sin()", $help_func_math], ["sqrt()", $help_func_math], ["tan()", $help_func_math]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "16%,16%,16%,16%,16%,16%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_abs"]], ["abs()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["acos()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["asin()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["atan()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["atan2()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["cos()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["exp()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["log()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["Math"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_max"]], ["max()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_min"]], ["min()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["pow()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_random"]], ["random()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["sin()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["sqrt()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["tan()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_num]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_num];
var $help_node nolist = 0;


new object $help_func_abs: $help_funcs_num;

var $root manager = $help_func_abs;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384033;
var $has_name name = ['prop, "abs()", "abs()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER|FLOAT"], 'do_i]>, " abs(", <$format, ["i", [], ["INTEGER|FLOAT number"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the absolute value of ", <$format, ["i", [], ["number"], 'do_i]>, ", where ", <$format, ["i", [], ["number"], 'do_i]>, " can be either a float or an integer (and the same type of value is returned). Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["abs(-6)", <$format, ["br", [], [], 'do_br]>, "=> 6 ", <$format, ["np", [], [], 'do_np]>, "abs(7)", <$format, ["br", [], [], 'do_br]>, "=> 7 ", <$format, ["np", [], [], 'do_np]>, "abs(-000.12)", <$format, ["br", [], [], 'do_br]>, "=> 0.120000"], 'do_tt]>], 'do_dfn]>], #[['this, $help_func_abs]]]>;
var $root inited = 1;
var $root managed = [$help_func_abs];
var $help_node nolist = 0;


new object $help_func_math: $help_funcs_num;

var $root manager = $help_func_math;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384130;
var $has_name name = ['prop, "Math|sin()|exp()|log()|cos()|tan()|sqrt()|asin()|acos()|atan()|pow()|atan2()", "Math|sin()|exp()|log()|cos()|tan()|sqrt()|asin()|acos()|atan()|pow()|atan2()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["FLOAT"], 'do_i]>, " sin(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " exp(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " log(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " cos(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " tan(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " sqrt(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " asin(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " acos(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " atan(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " pow(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ", ", <$format, ["i", [], ["FLOAT y"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " atan2(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ", ", <$format, ["i", [], ["FLOAT y"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "These functions perform the relevant mathematic function on the argument(s) and returns the result. Further information on each function can be found in the unix man page on the same relative function, in C. The precision of the function may vary by the implementation. If a floating point exception occurs, the error ~fpe is thrown."], #[]]>;
var $root inited = 1;
var $root managed = [$help_func_math];
var $help_node nolist = 0;


new object $help_func_max: $help_funcs_num;

var $root manager = $help_func_max;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "max()", "max()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " max(", <$format, ["i", [], ["ANY arg"], 'do_i]>, ", ", <$format, ["i", [], ["..."], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the maximum of its arguments. All of the arguments must be of the same type, and must be integers, floats, or strings.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["max(3, 7, 9, 5)", <$format, ["br", [], [], 'do_br]>, "=> 9"], 'do_dfn]>, " ", <$format, ["dfn", [], ["max(\"Foo\", \"aardvark\", \"bar\", \"Quux\")", <$format, ["br", [], [], 'do_br]>, "=> \"Quux\""], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_func_max];
var $help_node nolist = 0;


new object $help_func_min: $help_funcs_num;

var $root manager = $help_func_min;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "min()", "min()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " min(", <$format, ["i", [], ["ANY arg"], 'do_i]>, ", ", <$format, ["i", [], ["..."], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the minimum of its arguments. All of the arguments must be of the same type, and must be integers, floats, or strings.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["min(3, 7, 9, 5)", <$format, ["br", [], [], 'do_br]>, "=> 3"], 'do_dfn]>, " ", <$format, ["dfn", [], ["min(\"Foo\", \"aardvark\", \"bar\", \"Quux\")", <$format, ["br", [], [], 'do_br]>, "=> \"aardvark\""], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_func_min];
var $help_node nolist = 0;


new object $help_func_random: $help_funcs_num;

var $root manager = $help_func_random;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "random()", "random()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " random(", <$format, ["i", [], ["INTEGER max"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a random integer between one and ", <$format, ["i", [], ["max"], 'do_i]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["random(10)", <$format, ["br", [], [], 'do_br]>, "=> 3"], 'do_dfn]>], #[['this, $help_func_random]]]>;
var $root inited = 1;
var $root managed = [$help_func_random];
var $help_node nolist = 0;


new object $help_coldc_native: $help_coldc;

var $root manager = $help_coldc_native;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058134;
var $has_name name = ['prop, "Native Method Reference", "Native Method Reference"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[['this, $help_coldc_native]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_native];
var $help_node nolist = 0;


new object $help_reference: $help_coldcore;

var $root manager = $help_reference;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847916304;
var $has_name name = ['prop, "Reference Library", "Reference Library"];
var $help_node links = #[["Subsystem", $help_index_subsystem], ["Object", $help_index_objects]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Nodes from this point down are for core subsystem documentation and documentation on specific objects.", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_index_subsystem"]], ["Subsystem"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Subsystems Index"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_index_objects"]], ["Object"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Core Objects Index"], 'do_dd]>], 'do_dl]>], #[['this, $help_reference]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_reference];
var $help_node nolist = 0;


new object $help_updates: $help_coldcore;

var $root manager = $help_updates;
var $help_updates dirty = 2;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848537316;
var $help_node index = $help_index_subsystem;
var $has_name name = ['prop, "Updates", "Updates"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[], #[]]>;
var $root inited = 1;
var $help_updates update_list = [[1011855600, [$help_theme]]];
var $help_updates cleanup_time = 2592000;
var $root trusted = [$help_node];
var $root managed = [$help_updates];
var $help_node nolist = 0;

public method .touched() {
    var i, j, t;
    
    (> .perms(caller(), 'trusts) <);
    dirty++;
    t = localtime();
    t = (((t[1]) - (t[2])) - (60 * (t[3]))) - (3600 * (t[4]));
    if ((i = t in (update_list.slice(1))))
        update_list = update_list.replace(i, [(update_list[i])[1], ((update_list[i])[2]).setadd(sender())]);
    else
        update_list += [[t, [sender()]]];
    update_list = map i in (update_list || []) to ([i[1], filter j in (i[2]) where ((| j.has_ancestor($help_node) |))]);
    update_list = filter i in (update_list || []) where ((i[2]) && ((i[1]) > (t - cleanup_time)));
};

public method .body() {
    var i, j, out, body, cleaned;
    
    body = pass();
    if (dirty || (!body)) {
        if (!update_list) {
            out = ["There weren't any recent updates."];
        } else {
            out = ["{dl:"];
            for i in (update_list) {
                // sometimes help nodes which are deleted end up in this list..
                cleaned = filter j in (i[2]) where (valid(j));
    
                // now use the cleaned version...
                j = map j in (cleaned) to ([j.name(), "" + j]).sort();
                out += [((("{dt:" + ($time.format("%d-%b-%Y", i[1]))) + "}{dd:") + (map j in (j) to (strfmt("{link node=%l:%l}", j[2], j[1])).to_english())) + "}"];
            }
            out += ["}"];
        }
        .set_body(out);
        body = pass();
        dirty = 0;
    }
    return body;
};

root method .core_help_updates() {
    dirty = 1;
    update_list = [];
    .set_body([]);
};


new object $help_admin: $help_coldcore;

var $root manager = $help_admin;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 868128023;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Administration", "Administration"];
var $help_node links = #[["Traceback Recording", $help_traceback_recording]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Unfortunately, this document is still in development. For now, see:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["web", [["src", "http://www.cold.org/coldcore/newadmin.html"], ["name", "Admin Guide"]], [], 'do_web]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In addition, the following documents are also defined:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_traceback_recording"]], ["Traceback Recording"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How tracebacks from core objects are handled"], 'do_dd]>], 'do_dl]>], #[['links, #[["Traceback Recording", "$help_traceback_recording"]]]]]>;
var $root inited = 1;
var $root managed = [$help_admin];


new object $help_admin_commands: $help_admin;

var $root manager = $help_admin_commands;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 889749740;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Admin Commands", "Admin Commands"];
var $help_node links = #[["@adjust", $help_cmd_adjust], ["@core", $help_cmd_core], ["@kick", $help_cmd_kick], ["@new-password", $help_cmd_newpwd], ["@quota", $help_cmd_quota], ["@rehash-all", $help_cmd_rehashall], ["@task?s", $help_cmd_tasks], ["@backup", $help_cmd_backup], ["@kill", $help_cmd_kill], ["@mojo", $help_cmd_mojo], ["@reap", $help_cmd_reap], ["@shutdown", $help_cmd_shutdown]];
var $help_node body = <$ctext_frob, [[<$format, ["b", [], ["Administrative Commands Listing"], 'do_b]>, " ", <$format, ["np", [], [], 'do_np]>, "The following commands are available for administrators: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "30%,70%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_adjust"]], ["@adjust"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Promotes a user to builder, programmer, or admin."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_core"]], ["@core"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Makes the object a core object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_kick"]], ["@kick"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["\"Kicks\" a user off the server."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_newpwd"]], ["@new-password"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Makes a new password for a user."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_quota"]], ["@quota"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Changes a users quota."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_rehashall"]], ["@rehash-all"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Updates ALL command caches in memory."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_tasks"]], ["@task?s"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Shows Database and Driver tasks (processes)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_backup"]], ["@backup"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Starts the database backup process."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_kill"]], ["@kill"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Kills a task."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_mojo"]], ["@mojo"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Turns on or off mojo. (full system priveledges)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_reap"]], ["@reap"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Used to show players who have not logged on for a specified amount of time. (default 3 months)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_shutdown"]], ["@shutdown"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Shutsdown the game. Can be time delayed."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["@adjust", "$help_cmd_adjust"], ["@core", "$help_cmd_core"], ["@kick", "$help_cmd_kick"], ["@new-password", "$help_cmd_newpwd"], ["@quota", "$help_cmd_quota"], ["@rehash-all", "$help_cmd_rehashall"], ["@task?s", "$help_cmd_tasks"], ["@backup", "$help_cmd_backup"], ["@kill", "$help_cmd_kill"], ["@mojo", "$help_cmd_mojo"], ["@reap", "$help_cmd_reap"], ["@shutdown", "$help_cmd_shutdown"]]]]]>;
var $root inited = 1;
var $root managed = [$help_admin_commands];


new object $help_traceback_recording: $help_admin;

var $root manager = $help_traceback_recording;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 909407321;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Traceback Recording", "Traceback Recording"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Tracebacks are recorded when they arise from certain actions, including all tracebacks caused by a command, and all tracebacks during creation and destruction of an object. The traceback is stored along with relevant information on the administrator-only mail list *tracebacks (limited to administrators because it may contain privileged information, such as commands typed by users). ", <$format, ["np", [], [], 'do_np]>, "To receive notification of the tracebacks as they occur, make sure to subscribe to the *tracebacks mailing list. ", <$format, ["np", [], [], 'do_np]>, "Whether a user see's tracebacks or not depends upon what their user class is, in relation to the system setting:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["$sys:traceback-for"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Which is a user class specifying what classes will see real tracebacks. If the user is not a descendant of this class, they will instead receive a polite message about the error."], #[]]>;
var $root inited = 1;
var $root managed = [$help_traceback_recording];


new object $help_administrators: $help_coldcore;

var $root manager = $help_administrators;
var $help_node index = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 887666903;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Administrators|Admins", "Administrators|Admins"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[]]>;
var $root inited = 1;
var $root managed = [$help_administrators];

public method .body() {
    arg @ignored;
    var admins, a, output, def, role, c1, c2, o;
    
    admins = [];
    def = "General Administrator";
    for a in ($sys.admins()) {
        role = a.get_setting("admin-role", $admin);
        if (match_begin(role, "Arch"))
            role = "0 " + role;
        else if (role && ((role[1]) in ($string.alphabet())))
            role = "00 " + role;
        else if (!role)
            role = "000 " + def;
        admins += [[role, a]];
    }
    output = [];
    for a in (admins.sort()) {
        o = $cml_lib.format_obj_tag('look, a[2], (a[2]).name());
        c1 = $cml_lib.format_td_tag(o);
        role = strsed(a[1], "^0+ ", "");
        c2 = $cml_lib.format_td_tag(role);
        output += [$cml_lib.format_tr_tag(c1, c2)];
    }
    return $ctext_frob.new_with([$cml_lib.format_dfn_tag(["Administrators:", $cml_lib.format_p_tag(), $cml_lib.format_table_tag("25%,75%", @output)])]);
};


new object $help_credit: $help_coldcore;

var $root manager = $help_credit;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 887776030;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Credit", "Credit"];
var $help_node links = #[["COPYRIGHT for ColdCore", $help_copyright]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdCore is authored by many people. Although most if not all of the core has been rewritten from its origins in Cold World, the following is a list of primary contributors from the beginning--in alphabetical order: ", <$format, ["dfn", [], [<$format, ["ul", [], [<$format, ["li", [], ["Jeff Bellgarde"], 'do_li]>, <$format, ["li", [], ["Robert de Forest"], 'do_li]>, <$format, ["li", [], ["Brandon Gillespie"], 'do_li]>, <$format, ["li", [], ["Greg Hudson"], 'do_li]>, <$format, ["li", [], ["Wyatt Miler"], 'do_li]>, <$format, ["li", [], ["Bruce Mitchener"], 'do_li]>, <$format, ["li", [], ["Brad Roberts"], 'do_li]>, <$format, ["li", [], ["Miroslav Silovic"], 'do_li]>, <$format, ["li", [], ["Alex Stewart"], 'do_li]>], 'do_ul]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In addition, the following people may have--in some way or another--also helped with ColdCore:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Jon Lambert, Brian Buchanan, Ken Brush, Ted Kanzinsky, Jeff Kesselman, Dancer, Jordan Baker, Colin McCormack."], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Because Copyrights must be held by a legal entity, the ", <$format, ["link", [["node", "$help_copyright"]], ["COPYRIGHT for ColdCore"], 'do_link]>, " is held by Brandon Gillespie."], #[['links, #[["COPYRIGHT for ColdCore", "$help_copyright"]]]]]>;
var $root inited = 1;
var $root managed = [$help_credit];


new object $help_copyright: $help_credit;

var $root manager = $help_copyright;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 887776128;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "COPYRIGHT", "COPYRIGHT"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdCore is authored by many people, and is Copyright 1994-2002 by Brandon Gillespie, unless otherwise stated on a specific method or object. ", <$format, ["np", [], [], 'do_np]>, "The following terms apply to all objects associated with ColdCore unless explicitly disclaimed. ", <$format, ["np", [], [], 'do_np]>, "The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided that existing copyright notices are retained in all copies and that this notice is included verbatim in any distributions. Notices must be displayed or provided as appropriate, to avoid mis-representation when alterations and personal enhancements are made to the core. No written agreement, license, or royalty fee is required for any of the authorized uses. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated on each object or method where they apply. ", <$format, ["np", [], [], 'do_np]>, "IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ", <$format, ["np", [], [], 'do_np]>, "THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."], #[]]>;
var $root inited = 1;
var $root managed = [$help_copyright];


new object $help_theme: $help_coldcore;

var $root manager = $help_theme;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847060976;
var $has_name name = ['prop, "Theme", "Theme"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node needs to be written, use @help-list and @help-write"], #[]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_theme];
var $help_node nolist = 0;

root method .core_help_theme() {
    .set_body(["This node needs to be written, use @help-list and @help-write"]);
};


new object $help_core: $help_node;

var $root manager = $help_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848184185;
var $has_name name = ['prop, "Core Help Root", "Core Help Root"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[['this, $help_core]]]>;
var $root inited = 1;
var $root managed = [$help_core];
var $help_node holder = 1;
var $help_node nolist = 1;

public method .node_name() {
    var name;
    
    // just reprog this for now, later we should have a 'top of tree' setting
    if (this() == definer())
        return "";
    name = ((.parents())[1]).node_name();
    if (!name)
        return (.name()).word(1, "|");
    return (name + ": ") + ((.name()).word(1, "|"));
};


new object $help_cmds: $help_core;

var $root manager = $help_cmds;
var $root flags = ['variables, 'methods, 'code, 'core, 'fertile];
var $root created_on = 847128224;
var $has_name name = ['prop, "Commands", "Commands"];
var $root managed = [$help_cmds];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node is simply a place holder, and should not be linked in through an index or anything. If you see it, something has gone wrong."], #[['this, $help_cmds]]]>;
var $root inited = 1;
var $help_node group = 1;
var $help_node nolist = 1;
var $help_node holder = 1;

public method .nolist() {
    arg @args;
    
    // all 'command' nodes are nolist
    return 1;
};

public method .top_of_help_heirarchy() {
    return definer() == this();
};


new object $help_cmd_say: $help_cmds;

var $root manager = $help_cmd_say;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043470;
var $has_name name = ['prop, "say", "say"];
var $root managed = [$help_cmd_say];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The interaction command ", <$format, ["tt", [], ["say"], 'do_tt]>, " is used to speak and talk to others. For convenience, the double-quote character may also be used as a shortcut. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> say Hi", <$format, ["br", [], [], 'do_br]>, "Brandon says, \"Hi\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["> \"whats up?", <$format, ["br", [], [], 'do_br]>, "Brandon says, \"whats up?\""], 'do_dfn]>], #[['this, $help_cmd_say]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_emote: $help_cmds;

var $root manager = $help_cmd_emote;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043476;
var $has_name name = ['prop, "emote", "emote"];
var $root managed = [$help_cmd_emote];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The interaction command ", <$format, ["tt", [], ["emote"], 'do_tt]>, " is used for free-form actions. For convenience, the colon character may also be used as a shortcut. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> emote waves to everybody", <$format, ["br", [], [], 'do_br]>, "Brandon waves to everybody"], 'do_dfn]>, " ", <$format, ["dfn", [], ["> :jumps up and down", <$format, ["br", [], [], 'do_br]>, "Brandon jumps up and down"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "You can get rid of the space after your name, by doubling up the colon:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> ::'s head hurts", <$format, ["br", [], [], 'do_br]>, "Brandon's head hurts"], 'do_dfn]>], #[['this, $help_cmd_emote]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_tosay: $help_cmds;

var $root manager = $help_cmd_tosay;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043714;
var $has_name name = ['prop, "to say", "to say"];
var $root managed = [$help_cmd_tosay];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["to <target> say <anything>"], 'do_tt]>, <$format, ["np", [], [], 'do_np]>, "The interaction command ", <$format, ["tt", [], ["to"], 'do_tt]>, " is used to speak and talk to a specific person (<target>). For convenience, the single-quote character may be used as a shortcut. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> to Miro say Hi", <$format, ["br", [], [], 'do_br]>, "Brandon (to Miro) says, \"Hi\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["> 'Miro whats up?", <$format, ["br", [], [], 'do_br]>, "Brandon (to Miro) says, \"whats up?\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "As with any directed interaction command, you can double up the shortcut character to send to the last person you directed to. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> 'Miro say Hi", <$format, ["br", [], [], 'do_br]>, "Brandon (to Miro) says, \"Hi\"", <$format, ["br", [], [], 'do_br]>, "> ''how is the weather?", <$format, ["br", [], [], 'do_br]>, "Brandon (to Miro) asks, \"How is the weather?\""], 'do_dfn]>], #[['this, $help_cmd_tosay]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_whisper: $help_cmds;

var $root manager = $help_cmd_whisper;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043723;
var $has_name name = ['prop, "whisper", "whisper"];
var $root managed = [$help_cmd_whisper];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["whisper <anything> to <target>"], 'do_tt]>, <$format, ["np", [], [], 'do_np]>, "The interaction command ", <$format, ["tt", [], ["whisper"], 'do_tt]>, " is used to speak and talk privately to a specific person (<target>). Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> whisper the Red Man is in Tibet to Brian", <$format, ["br", [], [], 'do_br]>, "You whisper, \"the Red Man is in Tibet\" to Brian"], 'do_dfn]>], #[['this, $help_cmd_whisper]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_page: $help_cmds;

var $root manager = $help_cmd_page;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043729;
var $has_name name = ['prop, "@page", "@page"];
var $root managed = [$help_cmd_page];
var $help_node links = #[["say", $help_cmd_say], ["emote", $help_cmd_emote]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@page <who>[,<who>..] with <anything>"], 'do_tt]>, <$format, ["np", [], [], 'do_np]>, "The non-VR interaction command ", <$format, ["tt", [], ["@page"], 'do_tt]>, " is used to interact with one or more people not in the room. For convenience, the dash character may also be used as a shortcut. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> @page Amy with dinner tonight?", <$format, ["br", [], [], 'do_br]>, "[to Amy] Brandon says, \"dinner tonight?\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["> -Miro Hi", <$format, ["br", [], [], 'do_br]>, "[to Miro] Brandon says, \"Hi\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The people receiving the message see your location inside the square brackets, instead of who it is being directed to, such as [from The Pit] instead of [to Amy]. The default style of interaction is speach (similar to ", <$format, ["link", [["node", "$help_cmd_say"]], ["say"], 'do_link]>, "), you can also ", <$format, ["link", [["node", "$help_cmd_emote"]], ["emote"], 'do_link]>, " in page, by beginning your message with a colon:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> @page Brian with :waves", <$format, ["br", [], [], 'do_br]>, "[to Brian] Brandon waves"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "As with any directed interaction command, you can double up the shortcut character to send to the last person you directed to. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> -Brian :waves", <$format, ["br", [], [], 'do_br]>, "[to Brian] Brandon waves", <$format, ["br", [], [], 'do_br]>, "> --how goes it?", <$format, ["br", [], [], 'do_br]>, "[to Brian] Brandon says, \"how goes it?\""], 'do_dfn]>], #[['this, $help_cmd_page]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_think: $help_cmds;

var $root manager = $help_cmd_think;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043935;
var $has_name name = ['prop, "think", "think"];
var $root managed = [$help_cmd_think];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The interaction command ", <$format, ["tt", [], ["think"], 'do_tt]>, " is used to think something out loud. For convenience, the percent character may also be used as a shortcut. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> think oops", <$format, ["br", [], [], 'do_br]>, "Brandon . o O ( oops )"], 'do_dfn]>, " ", <$format, ["dfn", [], ["> %I think everybody can see my thoughts", <$format, ["br", [], [], 'do_br]>, "Brandon . o O ( I think everybody can see my thoughts )"], 'do_dfn]>], #[['this, $help_cmd_think]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_spoof: $help_cmds;

var $root manager = $help_cmd_spoof;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043939;
var $has_name name = ['prop, "spoof", "spoof"];
var $root managed = [$help_cmd_spoof];
var $help_node links = #[["emote", $help_cmd_emote]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The interaction command ", <$format, ["tt", [], ["spoof"], 'do_tt]>, " is used similar to ", <$format, ["link", [["node", "$help_cmd_emote"]], ["emote"], 'do_link]>, ", except your name does not start the line. This is usually used to format your actions in a different way, but can be used to 'spoof' actions from other players--which can be considered rude (be careful when using it so as to not offend anybody). If your name does not appear as a word in the line, it will be appended for attribution. For convenience, the exclaimation point may also be used as a shortcut. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> spoof Miro slips and falls.", <$format, ["br", [], [], 'do_br]>, "Miro slips and falls. -- Brandon"], 'do_dfn]>, " ", <$format, ["dfn", [], ["> !The big beast pounces on Brandon, pummelling him silly", <$format, ["br", [], [], 'do_br]>, "The big beast pounces on Brandon, pummelling him silly"], 'do_dfn]>], #[['links, #[["emote", "$help_cmd_emote"]]]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_paste: $help_cmds;

var $root manager = $help_cmd_paste;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847044098;
var $has_name name = ['prop, "@paste|@paste-to", "@paste|@paste-to"];
var $root managed = [$help_cmd_paste];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@paste [to <target>]"], 'do_tt]>, <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "The non-VR interaction command ", <$format, ["tt", [], ["@paste"], 'do_tt]>, " is used to display blocks of text either to the room or to a specific person (<target>). If no target is specified, it is displayed to the room. You will be prompted for the text. When you are finished typing in the text, type a period at the beginning of a line, followed by no other characters. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["> @paste\nReceiving input. Enter \".\" to finish or \"@abort\" to abort.\n> USER     PID   %CPU %MEM   VSZ  RSS  COMMAND\n> brandon  10267  0.0 19.4  5800 5928  ./genesis\n> .\n-------------- Brandon (@paste's) ---------------\nUSER     PID   %CPU %MEM   VSZ  RSS  COMMAND\nbrandon  10267  0.0 19.4  5800 5928  ./genesis\n------------------- + Finis + -------------------\n2 lines of text pasted"], 'do_quote]>], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_shortcuts: $help_cmds;

var $root manager = $help_cmd_shortcuts;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847044102;
var $has_name name = ['prop, "Unnamed Interaction Shortcuts", "Unnamed Interaction Shortcuts"];
var $root managed = [$help_cmd_shortcuts];
var $help_node links = #[["say", $help_cmd_say]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "In addition to the standard interaction commands there are also a few which do not have names: ", <$format, ["dfn", [["ind", "4"], ["nobound", 1]], [<$format, ["table", [["cols", "10%,90%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], [<$format, ["tt", [], ["|"], 'do_tt]>], 'do_b]>], 'do_td]>, <$format, ["td", [], ["This is used to display one line of information, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> |test", <$format, ["br", [], [], 'do_br]>, "Brandon | test"], 'do_dfn]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], [<$format, ["tt", [], [",,"], 'do_tt]>], 'do_b]>], 'do_td]>, <$format, ["td", [], ["This is like ", <$format, ["link", [["node", "$help_cmd_say"]], ["say"], 'do_link]>, ", but it lets you put your own text before what you say, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> ,nods, That is correct", <$format, ["br", [], [], 'do_br]>, "Brandon nods, \"That is correct\""], 'do_dfn]>], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['this, $help_cmd_shortcuts]]]>;
var $root inited = 1;


new object $help_cmd_display: $help_cmds;

var $root manager = $help_cmd_display;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "@display", "@display"];
var $help_node links = #[["setting", $help_settings]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@d?isplay <objref> [options]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Shows general information about an object, including it's size, owner, parents, location, and what permissions it has. You can optionally have it list all the public methods you have defined on an object, or all the variables, and which object defines them as below. ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Example:"], 'do_b]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@display $vampire\nObject:   $vampire (Vampire)\nCreated:  Mon Jan 13 18:19:17 1997\nQuota:    75000 bytes\nPerms:\nSize:     6,132 bytes (on disk)\nManager:  $vampire (Vampire)\nWriters:  (none)\nParents:  $admin (Generic Admin) and $antisocial\nLocation: $the_pit (The Pit)\n---"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@display $vampire,\nObject Variables matching \"*\"\n  ,test_dict: #[]\n  ,test: 0\n"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@display $vampire.\nPublic Methods matching \"*\":\n ----   34 .edit_cmd(cmdstr, com, args)\n ----   14 .quit_editor()\n ----   49 .pulse()\n ----   24 .startup()\n ----    8 .dict_test(cmdstr, cmd, @str)\n ----   51 .tmp_pulse()\n"], 'do_quote]>], 'do_dfn]>, " Options can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+c?hop"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Chops lines longer than the players cols ", <$format, ["link", [["node", "$help_interface_settings"]], ["setting"], 'do_link]>, "."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+g?enerations"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Sets which object to go back from."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["setting", "$help_interface_settings"]]]]]>;
var $root managed = [$help_cmd_display];
var $help_node index = $help_index_cmds;


new object $help_cmd_program: $help_cmds;

var $root manager = $help_cmd_program;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 838059477;
var $has_name name = ['prop, "@program", "@program"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax ", <$format, ["tt", [], ["@program <objref>.<method> [options] [with <any>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Sets the code for <method> on <object>. ", <$format, ["np", [], [], 'do_np]>, " Options can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "30%,70%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+warnings"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Do not warn about recursion."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+edited[=message]"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Set or override the edited comment. (admin only)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+access=permission"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Set the method access to one of public, protected, private, root or driver."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+flags=flags"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Set the flags to some of nooverride, locked, fork or native."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Optionally, 'with' preposition causes it to read the code from the command line instead of prompting the user for it."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_program];
var $help_node index = $help_index_cmds;


new object $help_cmd_set: $help_cmds;

var $root manager = $help_cmd_set;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847776342;
var $has_name name = ['prop, "@set", "@set"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@set [options] [<target>:][<name>[=<value>]]"], 'do_tt]>, <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "This command is used to display and change configurable settings on objects. If <target> is left unspecified it will default to you. To view all settings on an object do not specify a setting name or value, such as either of the following two:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set", <$format, ["br", [], [], 'do_br]>, "@set here:"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The first example will show all settings on you. The second example will show all settings on ", <$format, ["i", [], ["here"], 'do_i]>, ". To change a setting include the setting name after the target followed by an equals sign and a value, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set here:realm=Taobh Thiar"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If the option ", <$format, ["tt", [], ["+definer"], 'do_tt]>, " is given, it will list all of the definers for each setting instance. If a value for definer is given it will only list instances of the settings defined by the given objref, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set +definer=$place here:"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Which will only show the settings defined on ", <$format, ["tt", [], ["here"], 'do_tt]>, " and defined by ", <$format, ["tt", [], ["place"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "If the option ", <$format, ["tt", [], ["+clear"], 'do_tt]>, " is given, it will ignore any value specified for the setting and will instead clear the value, reverting it to its original default."], #[['this, $help_cmd_set]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;
var $root managed = [$help_cmd_set];


new object $help_cmd_adjust: $help_cmds;

var $root manager = $help_cmd_adjust;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119776;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@adjust", "@adjust"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@adjust|@promote <user> to <any>"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Used to change a user's class from/to any of the following: ", <$format, ["ul", [], [<$format, ["li", [], ["user"], 'do_li]>, <$format, ["li", [], ["builder"], 'do_li]>, <$format, ["li", [], ["programmer"], 'do_li]>, <$format, ["li", [], ["admin"], 'do_li]>], 'do_ul]>, " ", <$format, ["p", [], [], 'do_p]>, "Example: ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["@promote Bob to a programmer"], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "If the user was originally a guest it will create a password and email it to the user. It uses the email address they specified upon guest connect."], #[['this, $help_cmd_adjust]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_adjust];


new object $help_cmd_mojo: $help_cmds;

var $root manager = $help_cmd_mojo;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119784;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@mojo", "@mojo"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@mojo on|off"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Used by an administrator to enable full system priveliges."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_mojo];


new object $help_cmd_newpwd: $help_cmds;

var $root manager = $help_cmd_newpwd;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119794;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@new-password|@newpwd", "@new-password|@newpwd"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@new-password|@newpw?d <user>"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Used to generate a new random password for the specified user. The password is printed to the admin running the command, and is emailed to the user. Example: ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["@newpw Billy Bob"], 'do_dfn]>], #[['this, $help_cmd_newpwd]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_newpwd];


new object $help_cmd_rehashall: $help_cmds;

var $root manager = $help_cmd_rehashall;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119800;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@rehash-all", "@rehash-all"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["Syntax: @rehash-all [-purge]"], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Commands are cached for fast lookup. Because of this if a command is added to an object other than your object (such as $user), the global cache needs to be updated. This command will clear all caches and update them as needed. ", <$format, ["p", [], [], 'do_p]>, "If the +purge option is specified it will purge ALL caches in the database before rehashing. This does not happen by default."], #[['this, $help_cmd_rehashall]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_rehashall];


new object $help_cmd_backup: $help_cmds;

var $root manager = $help_cmd_backup;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119816;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@backup", "@backup"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: @backup"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Start an asynchronous backup of the binary database."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_backup];


new object $help_cmd_shutdown: $help_cmds;

var $root manager = $help_cmd_shutdown;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119822;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@shutdown", "@shutdown"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@shutdown [-t?ime=xx] [reason]"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Shutdown the server, the time defaults to five minutes, if left unspecified. The time specified is in minutes, so -time=10 would be ten minutes, not ten seconds. Example: ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@shutdown -t=0 Upgrading Driver, Should be back online soon"], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Would shutdown immediately (zero minutes)."], #[['this, $help_cmd_shutdown]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_shutdown];


new object $help_cmd_tasks: $help_cmds;

var $root manager = $help_cmd_tasks;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119825;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@tasks", "@tasks"];
var $help_node links = #[["@kill", $help_cmd_kill]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@task?s [task [task [...]]]"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Briefly list all Database and Driver tasks, or list full details on the specified tasks (as with ", <$format, ["link", [["node", "$help_cmd_kill"]], ["@kill"], 'do_link]>, ") system tasks are directly specified by prefixing them with an asterisk). Examples: ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["@tasks"], 'do_dfn]>, " ", <$format, ["dfn", [], ["@tasks *10204"], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Note: does not show currently executing task."], #[['this, $help_cmd_tasks]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_tasks];


new object $help_cmd_kill: $help_cmds;

var $root manager = $help_cmd_kill;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119831;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@kill", "@kill"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@del-t?ask|@kill [task [task [...]]]"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Kill the specified task. System tasks are directly specified by prefixing them with an asterisk. In general you should kill the related database task and let it kill the system task (if applicable). ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["@kill *10204", <$format, ["br", [], [], 'do_br]>, "@kill 12 *1241"], 'do_dfn]>], #[['this, $help_cmd_kill]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_kill];


new object $help_cmd_addcmd: $help_cmds;

var $root manager = $help_cmd_addcmd;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119837;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@add-command|@ac", "@add-command|@ac"];
var $help_node links = #[["Enhanced Command Template", $help_commands_enhanced], ["Matching Conventions", $help_commands_matching], ["@rehash", $help_cmd_rehash], ["@rehash-all", $help_cmd_rehashall]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@add-c?ommand|@ac \"<Command Template>\" [to|for] <objref>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Used to add a command. The method called if the command matches must be specified. The command template must be an ", <$format, ["link", [["node", "$help_commands_enhanced"]], ["Enhanced Command Template"], 'do_link]>, ". Arguments send to the method are always ordered the same, the first argument is always the command string, followed by subsequent arguments relative to how the command template would match using template matching (see ", <$format, ["link", [["node", "$help_commands_matching"]], ["Matching Conventions"], 'do_link]>, ").", <$format, ["p", [], [], 'do_p]>, "For instance, the following enhanced command template:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["\"@get <any> from <this>\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Would evaluate to the following standard template:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["\"@get * from *\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "From this point, you can simply evaluate the template matching to see how its results would be ordered:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [";match_template(\"@get something from nothing\", \"@get * from *\")", <$format, ["br", [], [], 'do_br]>, "=> [\"@get\", \"something\", \"from\", \"nothing\"]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Based off these results the arg definition for your method could be:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["arg cmdstr, cmd, arg1, prep, arg2;"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When a command is added it will not immediately begin working. Command caches must be updated first. There are three different situations that will arise when adding a command:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], ["Adding a local command to yourself"], 'do_dt]>, <$format, ["dd", [], [<$format, ["p", [], [], 'do_p]>, "This situation is the simplest to update. If you have added a command to yourself simply type ", <$format, ["link", [["node", "$help_cmd_rehash"]], ["@rehash"], 'do_link]>, ", and your local caches will be updated.", <$format, ["p", [], [], 'do_p]>], 'do_dd]>, <$format, ["dt", [], ["Adding a remote command to an object"], 'do_dt]>, <$format, ["dd", [], [<$format, ["p", [], [], 'do_p]>, "When adding a remote command to something you can rehash the remote caches by simply dropping the item and picking it back up.", <$format, ["p", [], [], 'do_p]>], 'do_dd]>, <$format, ["dt", [], ["Adding a local command to another object"], 'do_dt]>, <$format, ["dd", [], [<$format, ["p", [], [], 'do_p]>, "If you are adding a local command to an object other than yourself, you will have to rehash the entire system's caches. This is done with the command ", <$format, ["link", [["node", "$help_cmd_rehashall"]], ["@rehash-all"], 'do_link]>, ", which is an administrative command."], 'do_dd]>], 'do_dl]>], #[['links, #[["Enhanced Command Template", "$help_commands_enhanced"], ["Matching Conventions", "$help_commands_matching"], ["@rehash", "$help_cmd_rehash"], ["@rehash-all", "$help_cmd_rehashall"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_addcmd];


new object $help_cmd_reap: $help_cmds;

var $root manager = $help_cmd_reap;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848426641;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@reap", "@reap"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@reap [options] [<user>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Used in reaping users. Can have various possible behaviours. If only a user is given (no options), @reap will enter an interactive user reaping system. At any time during the reaping process you can use @abort to cancel any further actions. ", <$format, ["np", [], [], 'do_np]>, "If no user is given, it will list all reap possibilities, where possibilities are considered after the user has not logged in for three months. This time can be changed with the ", <$format, ["tt", [], ["time"], 'do_tt]>, " option, which is given as an english explanation of the time, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> @reap +time=\"1 month\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In the listing the column ", <$format, ["tt", [], ["E"], 'do_tt]>, " will have an exclamation point if the user's email address is invalid. The column ", <$format, ["tt", [], ["MNG"], 'do_tt]>, " represents how many objects the user manages (always at least one). The column ", <$format, ["tt", [], ["Notified"], 'do_tt]>, " shows if and when the last reap notification was mailed, using the ", <$format, ["tt", [], ["mail"], 'do_tt]>, " option. The columns ", <$format, ["tt", [], ["Last On"], 'do_tt]>, " and ", <$format, ["tt", [], ["Age"], 'do_tt]>, " represent when the user was last connected, and how long it has been since they were created. ", <$format, ["np", [], [], 'do_np]>, "If the ", <$format, ["tt", [], ["mail"], 'do_tt]>, " option is given, instead of reaping it will send a message to the user's email address, notifying them of the imminent reaping. The ", <$format, ["tt", [], ["time"], 'do_tt]>, " option can also be used to change the grace period, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> @reap Bob +mail +time=\"5 days\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "A user is automatically removed from reapable status when they connect. The grace period is enforcable only by the administrations. This command does not make any assumptions, and an administrator will have to followup with a full reaping at the end of the grace period."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_reap];


new object $help_cmd_core: $help_cmds;

var $root manager = $help_cmd_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848468664;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@core", "@core"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@core <object>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Setup the specified object as a core object. This is used primarily for core development. It adds the ", <$format, ["tt", [], ["'core"], 'do_tt]>, " flag to the object, sets the object as its own manager and writer and removes any additional ownership."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_core];


new object $help_cmd_delcmd: $help_cmds;

var $root manager = $help_cmd_delcmd;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854543905;
var $root managed = [$help_cmd_delcmd];
var $has_name name = ['prop, "@del-command|@dc", "@del-command|@dc"];
var $help_node links = #[["@add-command", $help_cmd_addcmd]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@del-c?command|@dc \"<Command Template>\" [from] <objref>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Reverses the effects of @add-command. The command template must be identical to the one with which the command was added. The rehashing issues discussed in ", <$format, ["link", [["node", "$help_cmd_addcmd"]], ["@add-command"], 'do_link]>, " apply here (in other words, you may have to do a few tricks to update command caches)."], #[['this, $help_cmd_delcmd]]]>;
var $root inited = 1;


new object $help_cmd_descendants: $help_cmds;

var $root manager = $help_cmd_descendants;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855119873;
var $has_name name = ['prop, "@descendants", "@descendants"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: `", <$format, ["tt", [], ["@descend <object> [options]"], 'do_tt]>, "`"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Options can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+", <$format, ["i", [], ["N"], 'do_i]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Descend ", <$format, ["i", [], ["N"], 'do_i]>, " levels (zero or more)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+a?ll"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Descend all levels"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+o?nly"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Only show objects with the specified flags"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+n?ot"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Only show objects that do not have the specified flags"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+r?edundant"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Redundantly show objects in the heirarchy"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_descendants];


new object $help_cmd_describe: $help_cmds;

var $root manager = $help_cmd_describe;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856029245;
var $root managed = [$help_cmd_describe];
var $has_name name = ['prop, "@describe", "@describe"];
var $help_node links = #[["CML", $help_cml], ["@edit", $help_cmd_edit]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@desc?ribe|@prose <what> [as <description>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Sets the description (prose) for an object. If nothing other than the target object is given on the command line, you will be prompted for the description. Otherwise it will take anything after the preposition '", <$format, ["i", [], ["as"], 'do_i]>, "' as the description. ", <$format, ["np", [], [], 'do_np]>, "The description is not written in plaintext, but is in ", <$format, ["link", [["node", "$help_cml"]], ["CML"], 'do_link]>, ". Because of this, all plaintext formatting you include will be disregarded. Use CML tags for any desired formatting. ", <$format, ["np", [], [], 'do_np]>, "Note: This will overwrite the current description. To edit the description on the object, use the ", <$format, ["link", [["node", "$help_cmd_edit"]], ["@edit"], 'do_link]>, " command."], #[['links, #[["CML", "$help_cml"], ["@edit", "$help_cmd_edit"]]]]]>;
var $root inited = 1;


new object $help_cmd_new: $help_cmds;

var $root manager = $help_cmd_new;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856032830;
var $root managed = [$help_cmd_new];
var $has_name name = ['prop, "@new", "@new"];
var $help_node links = #[["Frob", $help_coldc_types_frobs], ["@spawn", $help_cmd_spawn], ["@destroy", $help_cmd_destroy]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@new <parent> [named <name>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Creates a new VR object with the given parent, and optionally set the name. This command is preferred when working with VR objects, as it will correctly handle both real and ", <$format, ["link", [["node", "$help_coldc_types_frobs"]], ["Frob"], 'do_link]>, " instances. The alternative is ", <$format, ["link", [["node", "$help_cmd_spawn"]], ["@spawn"], 'do_link]>, " which will always create new objects. If you want to create a new non-VR object, use @spawn or call the parent's .new() method.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_destroy"]], ["@destroy"], 'do_link]>], #[['links, #[["Frob", "$help_coldc_types_frobs"], ["@spawn", "$help_cmd_spawn"], ["@destroy", "$help_cmd_destroy"]]]]]>;
var $root inited = 1;


new object $help_cmd_wear: $help_cmds;

var $root manager = $help_cmd_wear;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856032839;
var $root managed = [$help_cmd_wear];
var $has_name name = ['prop, "wear|shed|remove", "wear|shed|remove"];
var $help_node links = #[["@new", $help_cmd_new]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["wear <article>"], 'do_tt]>, " OR ", <$format, ["tt", [], ["shed|remove <article>"], 'do_tt]>, " ", <$format, ["np", [], [], 'do_np]>, "Wear or remove an article of clothing. You must be holding (or wearing, as applicable) the article of clothing. The clothing must also be a $wearable_frob. You can create clothing with the ", <$format, ["link", [["node", "$help_cmd_new"]], ["@new"], 'do_link]>, " cmd. For example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@new $wearable_frob named Trenchcoat", <$format, ["br", [], [], 'do_br]>, "wear trenchcoat", <$format, ["br", [], [], 'do_br]>, "shed trenchcoat"], 'do_dfn]>], #[['this, $help_cmd_wear]]]>;
var $root inited = 1;


new object $help_cmd_spawn: $help_cmds;

var $root manager = $help_cmd_spawn;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856034653;
var $root managed = [$help_cmd_spawn];
var $has_name name = ['prop, "@spawn", "@spawn"];
var $help_node links = #[["@new", $help_cmd_new]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@spawn <parent>[named <name>]"], 'do_tt]>, " ", <$format, ["np", [], [], 'do_np]>, "Create a new object with the given parent, and optionally set the name. This command is generally used only by programmers, as it always creates a real object and does not create a frob instance, and it will create any type of object, not just a VR object. In general the command ", <$format, ["link", [["node", "$help_cmd_new"]], ["@new"], 'do_link]>, " is used instead."], #[['links, #[["@new", "$help_cmd_new"]]]]]>;
var $root inited = 1;


new object $help_cmd_nh: $help_cmds;

var $root manager = $help_cmd_nh;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856455556;
var $root managed = [$help_cmd_nh];
var $has_name name = ['prop, "@nh|@new-help-node", "@nh|@new-help-node"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: `", <$format, ["tt", [], ["@nh [<node>] [options]"], 'do_tt]>, "` ", <$format, ["np", [], [], 'do_np]>, "The argument ", <$format, ["i", [], ["node"], 'do_i]>, " is the parent node to descend from, or if unspecified it will default to the current node. Options can be:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["+i?ndex=index", <$format, ["br", [], [], 'do_br]>, "+o?bjname=objname", <$format, ["br", [], [], 'do_br]>, "+n?ame=\"name of node\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "A seperate entry is made in the index for each branch in the name (seperated by the | character)."], #[]]>;
var $root inited = 1;


new object $help_cmd_rename: $help_cmds;

var $root manager = $help_cmd_rename;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856649394;
var $root managed = [$help_cmd_rename];
var $has_name name = ['prop, "@rename", "@rename"];
var $help_node links = #[["Name templates", $help_app_names], ["Template Matching", $help_commands_matching], ["@add-name-template", $help_cmd_ant], ["@del-name-template", $help_cmd_dnt]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: `", <$format, ["tt", [], ["@rename <target> [to] \"<newname>\""], 'do_tt]>, "` ", <$format, ["np", [], [], 'do_np]>, "Used to change the ", <$format, ["i", [], ["target"], 'do_i]>, " object's name or object name. Quotes may be used, but are not required. ", <$format, ["link", [["node", "$help_app_names"]], ["Name templates"], 'do_link]>, " may also be specified with the new name, by seperating them from the name with commas, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@rename exit to Gilded Door, w?est, o?ut"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Keep in mind that the name is matched using the beginning of each word, where the templates are mached with ", <$format, ["link", [["node", "$help_commands_matching"]], ["Template Matching"], 'do_link]>, ". Name templates can also be changed with the commands ", <$format, ["link", [["node", "$help_cmd_ant"]], ["@add-name-template"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_cmd_dnt"]], ["@del-name-template"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "The object name can also be changed, by specifying a valid object name as the new name, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@rename $thing_152 to $my_lamp"], 'do_dfn]>], #[['this, $help_cmd_rename]]]>;
var $root inited = 1;


new object $help_cmd_ant: $help_cmds;

var $root manager = $help_cmd_ant;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856650064;
var $root managed = [$help_cmd_ant];
var $has_name name = ['prop, "@ant|@add-name-template", "@ant|@add-name-template"];
var $help_node links = #[["Template Matching", $help_commands_matching], ["@rename", $help_cmd_rename], ["Names", $help_app_names]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: `", <$format, ["tt", [], ["@ant|@add-name-template <template> [to] <target>"], 'do_tt]>, "` ", <$format, ["np", [], [], 'do_np]>, "Add the given name template to the target object. The template uses ", <$format, ["link", [["node", "$help_commands_matching"]], ["Template Matching"], 'do_link]>, ". If the template is redundant and conflicts with the current name, an error will be returned and the template will not be added. ", <$format, ["np", [], [], 'do_np]>, "The command ", <$format, ["link", [["node", "$help_cmd_rename"]], ["@rename"], 'do_link]>, " may also be used to specify the name templates. The section ", <$format, ["link", [["node", "$help_app_names"]], ["Names"], 'do_link]>, " explains more about names and name templates."], #[['this, $help_cmd_ant]]]>;
var $root inited = 1;


new object $help_cmd_dnt: $help_cmds;

var $root manager = $help_cmd_dnt;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856650064;
var $root managed = [$help_cmd_dnt];
var $has_name name = ['prop, "@dnt|@del-name-template", "@dnt|@del-name-template"];
var $help_node links = #[["Names", $help_app_names]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: `", <$format, ["tt", [], ["@dnt|@del-name-template <template> [from] <target>"], 'do_tt]>, "` ", <$format, ["np", [], [], 'do_np]>, "Remove the given name template from the target object. The section ", <$format, ["link", [["node", "$help_app_names"]], ["Names"], 'do_link]>, " explains more about names and name templates."], #[['this, $help_cmd_dnt]]]>;
var $root inited = 1;


new object $help_cmd_remember: $help_cmds;

var $root manager = $help_cmd_remember;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856651645;
var $root managed = [$help_cmd_remember];
var $has_name name = ['prop, "@remember", "@remember"];
var $help_node links = #[["@remembered", $help_cmd_remembered]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@remember <item> as <what>"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["np", [], [], 'do_np]>, "Using this command you can alias something which is either hard to type or hard to remember, so that later you can reference it with the new alias you set to it, rather than it's full name. Remembered items do not have to be in the environment for them to be matched. This is also useful, as you do not need to remember full object names. An example would be:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@remember $robot_1512 as fred"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If you do this, you will be able to reference ", <$format, ["tt", [], ["$robot_1512"], 'do_tt]>, " as ", <$format, ["tt", [], ["fred"], 'do_tt]>, ", even if it is not in your environment. This can potentially cause conflicts, as anything remembered is given priority over anything in your environment.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_remembered"]], ["@remembered"], 'do_link]>], #[['links, #[["@remembered", "$help_cmd_remembered"]]]]]>;
var $root inited = 1;


new object $help_mail: $help_cmds;

var $root manager = $help_mail;
var $help_node index = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863993835;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Mail System", "Mail System"];
var $help_node links = #[["@mail", $help_mail_mail], ["@nn|@next-new", $help_mail_next_new], ["@remove-m?ail|@rmm?ail", $help_mail_rmmail], ["@sub?scribed", $help_mail_subscribe], ["@reply", $help_mail_reply], ["@mail-list?s", $help_mail_mail_lists], ["@read", $help_mail_read], ["@send", $help_mail_send], ["@unsub?scribed", $help_mail_unsubscribe], ["Mail Lists", $help_obj_mail_list]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The mail system built into ColdCore is a fairly basic one which allows each user to have their own mailbox and for there to exist various mailing lists which can be publicly accessible or have those who are able to send to the list or those able to read the list limited. ", <$format, ["np", [], [], 'do_np]>, "The commands to the ColdCore mail system are defined on object $mail_ui. ", <$format, ["np", [], [], 'do_np]>, "The following commands are available:", <$format, ["table", [["cols", "50%,50%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_mail_mail"]], ["@mail"], 'do_link]>, " <any>"], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_mail_next_new"]], ["@nn|@next-new"], 'do_link]>, " <any>"], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_mail_rmmail"]], ["@remove-m?ail|@rmm?ail"], 'do_link]>, " <any>"], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_mail_subscribe"]], ["@sub?scribed"], 'do_link]>, " <any>"], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_mail_reply"]], ["@reply"], 'do_link]>, " <any>"], 'do_li]>], 'do_ul]>], 'do_td]>, <$format, ["td", [], [<$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_mail_mail_lists"]], ["@mail-list?s"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_mail_read"]], ["@read"], 'do_link]>, " <any>"], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_mail_send"]], ["@send"], 'do_link]>, " <any>"], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_mail_unsubscribe"]], ["@unsub?scribed"], 'do_link]>, " <any>"], 'do_li]>], 'do_ul]>], 'do_td]>], 'do_tr]>], 'do_table]>, <$format, ["p", [], [], 'do_p]>, "To learn more about creating a mailing list, see ", <$format, ["link", [["node", "$help_obj_mail_list"]], ["Mail Lists"], 'do_link]>, "."], #[['links, #[["@mail", "$help_mail_mail"], ["@nn|@next-new", "$help_mail_next_new"], ["@remove-m?ail|@rmm?ail", "$help_mail_rmmail"], ["@sub?scribed", "$help_mail_subscribe"], ["@reply", "$help_mail_reply"], ["@mail-list?s", "$help_mail_mail_lists"], ["@read", "$help_mail_read"], ["@send", "$help_mail_send"], ["@unsub?scribed", "$help_mail_unsubscribe"], ["Mail Lists", "$help_obj_mail_list"]]]]]>;
var $root inited = 1;
var $help_node holder = 1;
var $root managed = [$help_mail];


new object $help_mail_read: $help_mail;

var $root manager = $help_mail_read;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 865084621;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@read", "@read"];
var $help_node links = #[["range", $help_ranges]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The @read command allows you to read your mail messages.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@read <range> on <*list-name> "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command form will display each message in ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_ranges"]], ["range"], 'do_link]>], 'do_tt]>, " from the specified mail list.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@read <range> "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command form will display each message in ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_ranges"]], ["range"], 'do_link]>], 'do_tt]>, " from the current mail list (the last one accessed with a mail command).", <$format, ["p", [], [], 'do_p]>, <$format, ["np", [], [], 'do_np]>, "Note: In either case, the ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_ranges"]], ["range"], 'do_link]>], 'do_tt]>, " may be given as '", <$format, ["tt", [], ["next"], 'do_tt]>, "' or '", <$format, ["tt", [], ["prev"], 'do_tt]>, "' which will correspondingly read the next or previous message on the list."], #[['links, #[["range", "$help_ranges"]]]]]>;
var $root inited = 1;
var $root managed = [$help_mail_read];


new object $help_mail_mail: $help_mail;

var $root manager = $help_mail_mail;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 865084822;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@mail", "@mail"];
var $help_node links = #[["range", $help_ranges], ["@set", $help_settings]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "To determine what mail is on a mail list, the ", <$format, ["tt", [], ["@mail"], 'do_tt]>, " command has been provided.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@mail <range> on <*list-name> "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command form will return the list of mail messages on the mail list from the beginning to the end of the specified ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_ranges"]], ["range"], 'do_link]>], 'do_tt]>, ". If the ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_ranges"]], ["range"], 'do_link]>], 'do_tt]>, " is not specified, it defaults to a value based on the number of rows you have told Cold (via ", <$format, ["link", [["node", "$help_interface_settings"]], ["@set"], 'do_link]>, " cols) exist on your screen.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@mail <*list-name> "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command form will return the same list of messages as the form above, but assumes the default ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_ranges"]], ["range"], 'do_link]>], 'do_tt]>, "."], #[['links, #[["range", "$help_ranges"], ["@set", "$help_interface_settings"]]]]]>;
var $root inited = 1;
var $root managed = [$help_mail_mail];


new object $help_mail_subscribe: $help_mail;

var $root manager = $help_mail_subscribe;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 865085006;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@subscribe", "@subscribe"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Once you know about the mailing lists available, you may wish to subscribe to some of them. For this you use the ", <$format, ["tt", [], ["@subscribe"], 'do_tt]>, " command.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@subscribe <*list-name> "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This checks that you may read the list, and will then subscribe you. This command has a couple of other useful forms also however:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@subscribe +new "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This is the command form used to determine on what lists you have new mail.", <$format, ["p", [], [], 'do_p]>, <$format, ["np", [], [], 'do_np]>, "And finally:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@subscribe "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This merely prints out the list of mail lists you are currently subscribed to."], #[]]>;
var $root inited = 1;
var $root managed = [$help_mail_subscribe];


new object $help_mail_unsubscribe: $help_mail;

var $root manager = $help_mail_unsubscribe;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 865085169;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@unsubscribe", "@unsubscribe"];
var $help_node links = #[["@mail-lists", $help_mail_mail_lists]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "To remove yourself from a mail list, you use the ", <$format, ["tt", [], ["@unsubscribe"], 'do_tt]>, " command.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@unsubscribe <*list-name> "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "That command form will unsubscribe you from the mail list assuming that you were already subscribed. Only typing:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@unsubscribe "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "will return the same output as ", <$format, ["link", [["node", "$help_mail_mail_lists"]], ["@mail-lists"], 'do_link]>, "."], #[['links, #[["@mail-lists", "$help_mail_mail_lists"]]]]]>;
var $root inited = 1;
var $root managed = [$help_mail_unsubscribe];


new object $help_mail_mail_lists: $help_mail;

var $root manager = $help_mail_mail_lists;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 865085218;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@mail-lists", "@mail-lists"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A mail list's name will always begin with the character '*' to differentiate it from other names. To get a list of mail lists on the system you are using, use:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@mail-lists "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This will print out each mail list and inform you of whether or not you may send to the list or read the mail on the list. It lists mail lists which you can not send to, as you may still read them and they are often used for dispersal of important information. An example of a list like this would be *news. It also lists the mail-lists that you can send to, but may not read from. An example of a list like this would be *admins, which exists for discussion between the admins, but a normal user might want to send mail to there to attract their attention to a particular issue."], #[]]>;
var $root inited = 1;
var $root managed = [$help_mail_mail_lists];


new object $help_mail_send: $help_mail;

var $root manager = $help_mail_send;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 865088462;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@send", "@send"];
var $help_node links = #[["CML", $help_cml]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "To send mail to another user or to a mail list, you use the ", <$format, ["tt", [], ["@send"], 'do_tt]>, " command.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@send <*list-name or user> "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command form will prompt you for the text of the message and the subject and then send the mail message to the specified mail list or user.", <$format, ["p", [], [], 'do_p]>, <$format, ["np", [], [], 'do_np]>, "Note: In the near future, this command will gain a few options to allow it to drop you into an editor and to support ", <$format, ["link", [["node", "$help_cml"]], ["CML"], 'do_link]>, " based mail messages.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@send <note> to <*list-name or user> "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command form will allow you to send the text of the ", <$format, ["tt", [], ["note"], 'do_tt]>, " to the specified mail list or user."], #[['links, #[["CML", "$help_cml"]]]]]>;
var $root inited = 1;
var $root managed = [$help_mail_send];


new object $help_mail_next_new: $help_mail;

var $root manager = $help_mail_next_new;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 865089561;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@nn", "@nn"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "To provide an easier way to cycle through a larger quantity of unread mail, the ", <$format, ["tt", [], ["@nn"], 'do_tt]>, " command was written.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@nn <*list-name> "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command form displays the next new message from the specified mail list. By leaving off the mail list identifier, it will cycle through each list you are subscribed to, displaying the unread mail."], #[]]>;
var $root inited = 1;
var $root managed = [$help_mail_next_new];


new object $help_mail_rmmail: $help_mail;

var $root manager = $help_mail_rmmail;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 865091839;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@rmmail", "@rmmail"];
var $help_node links = #[["range", $help_ranges]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Deleting your mail is easily accomplished with the ", <$format, ["tt", [], ["@rmmail"], 'do_tt]>, " command.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@rmmail <range> from <$list-name or me> "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command form will delete the messages in the ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_ranges"]], ["range"], 'do_link]>], 'do_tt]>, " from the specified mail list if you have the proper permissions, or from your own mailbox if you specify ", <$format, ["tt", [], ["me"], 'do_tt]>, "."], #[['links, #[["range", "$help_ranges"]]]]]>;
var $root inited = 1;
var $root managed = [$help_mail_rmmail];


new object $help_mail_reply: $help_mail;

var $root manager = $help_mail_reply;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 865092817;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@reply", "@reply"];
var $help_node links = #[["editor", $help_sys_editor], ["send", $help_node_editor_commands]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "To reply to a message, you use the ", <$format, ["tt", [], ["@reply"], 'do_tt]>, " command.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@reply to <number> "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command form will reply to the mail message ", <$format, ["tt", [], ["number"], 'do_tt]>, " on the current mail list.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@reply <number> on <list> "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command form will reply to the mail message ", <$format, ["tt", [], ["number"], 'do_tt]>, " on the specified mail list.", <$format, ["p", [], [], 'do_p]>, <$format, ["np", [], [], 'do_np]>, "Either form of the ", <$format, ["tt", [], ["@reply"], 'do_tt]>, " command will drop you into the ", <$format, ["link", [["node", "$help_sys_editor"]], ["editor"], 'do_link]>, " to compose your reply. When you have finished your reply, just type '", <$format, ["link", [["node", "$help_node_editor_commands"]], ["send"], 'do_link]>, "' and the message will be sent, and the ", <$format, ["link", [["node", "$help_sys_editor"]], ["editor"], 'do_link]>, " will exit."], #[['links, #[["editor", "$help_sys_editor"], ["send", "$help_node_editor_commands"]]]]]>;
var $root inited = 1;
var $root managed = [$help_mail_reply];


new object $help_cmd_list: $help_cmds;

var $root manager = $help_cmd_list;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 865217221;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@list", "@list"];
var $help_node links = #[["textdump", $help_coldc_textdump], ["@program", $help_cmd_program]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax ", <$format, ["tt", [], ["@list <objref> [options]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Lists the source code for a particular method. ", <$format, ["np", [], [], 'do_np]>, " Options can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+n?umbers"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Displays line numbers next to each line of source."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+t?extdump"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Lists the code in ", <$format, ["link", [["node", "$help_coldc_textdump"]], ["textdump"], 'do_link]>, " format rather than ", <$format, ["link", [["node", "$help_cmd_program"]], ["@program"], 'do_link]>, " format."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["textdump", "$help_coldc_textdump"], ["@program", "$help_cmd_program"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_list];


new object $help_cmd_show: $help_cmds;

var $root manager = $help_cmd_show;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 869285903;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@show", "@show"];
var $help_node links = #[["@list", $help_cmd_list], ["setting", $help_settings]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@show <objref> [options]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "@show displays an object's methods and variables, as long as you are either the owner, are trusted by the object, or the object is set visible. To see the contents of the methods, you will need to use ", <$format, ["link", [["node", "$help_cmd_list"]], ["@list"], 'do_link]>, " You can optionally have @show list all the public methods you have defined on an object, or all the variables, and which object defines them as below. ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@show me.\nObject:  $vampire [6,146 bytes]\nParents: $admin, $antisocial\nPublic methods matching \"*\":\n  .pulse()\n  .startup()\n"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@show me,\nObject:  $vampire [6,146 bytes]\nParents: $admin, $antisocial\n$root variables matching \"*\":\n  manager: $vampire\n  managed: [$vampire]\n  inited: 1\n  writes: []\n$user variables matching \"*\":\n  task_connections: #[[54965, $login_connection_23564]]\n"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["np", [], [], 'do_np]>, "Options can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+c?hop"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Chops lines longer than the players cols ", <$format, ["link", [["node", "$help_interface_settings"]], ["setting"], 'do_link]>, "."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["@list", "$help_cmd_list"], ["setting", "$help_interface_settings"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_show];
var $help_node index = $help_index_cmds;
var $help_node nolist = 0;


new object $help_cmd_hlist: $help_cmds;

var $root manager = $help_cmd_hlist;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 869368081;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@help-list|@hlist|@hl", "@help-list|@hlist|@hl"];
var $help_node links = #[["CML", $help_cml]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@help-list|@hl [<objref> | <help node>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "@help-list allows you to view the ", <$format, ["link", [["node", "$help_cml"]], ["CML"], 'do_link]>, " text of the last help entry you viewed, unless you selected an objref or help node when you entered the command."], #[['links, #[["CML", "$help_cml"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_hlist];
var $help_node index = $help_index_cmds;


new object $help_cmd_hwrite: $help_cmds;

var $root manager = $help_cmd_hwrite;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 869368839;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@help-write|@hwrite|@hw", "@help-write|@hwrite|@hw"];
var $help_node links = #[["CML", $help_cml]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@help-write|@hw?rite [<help node>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "@help-write sets the ", <$format, ["link", [["node", "$help_cml"]], ["CML"], 'do_link]>, " text of a help node. Without any arguments, @hwrite will attempt to set the text on the last help node you viewed. With an argument of <help node>, the command will set the text for that help entry if possible."], #[['links, #[["CML", "$help_cml"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_hwrite];
var $help_node index = $help_index_cmds;


new object $help_cmd_add_parent: $help_cmds;

var $root manager = $help_cmd_add_parent;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 869369522;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@add-parent", "@add-parent"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@add-p?arent|@ap <parent> [to] <object>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "@add-parent adds <parent> to the list of parents that the object has."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_add_parent];


new object $help_cmd_boot: $help_cmds;

var $root manager = $help_cmd_boot;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870563995;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@boot", "@boot"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@boot <objref> | <player>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "@boot notifies the player or object specified that it is being returned to it's home, and does so if the player that invoked the command is allowed to do the action."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_boot];


new object $help_cmd_rehash: $help_cmds;

var $root manager = $help_cmd_rehash;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870565149;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@rehash", "@rehash"];
var $help_node links = #[["@rehash-all", $help_cmd_rehashall]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: @rehash"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Commands are cached for fast lookup. Because of this, if a command is added to an object other than your object (such as $user), your user's cache needs to be updated. This command will clear your user's cache and update it as needed. See also ", <$format, ["link", [["node", "$help_cmd_rehashall"]], ["@rehash-all"], 'do_link]>, "."], #[['links, #[["@rehash-all", "$help_cmd_rehashall"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_rehash];


new object $help_cmd_which: $help_cmds;

var $root manager = $help_cmd_which;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870565854;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@which", "@which"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@which <text>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "@which searches for any command in your caches which has <text> in the command name. The full template and method is printed for each match found. ", <$format, ["np", [], [], 'do_np]>, "Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["> @which help\nCommands matching the template \"help\":\n  @hl?ist|@help-list <any>           $programmer.help_list_cmd()\n  @hw?rite|@help-write <any>         $programmer.help_write_cmd()\n  @nh?n|@new-help-node <any:+n?      $programmer.new_help_node_cmd()\n  help <any>                         $bad_commands.old_command_cmd()\n  @help <any>                        $help_ui.help_cmd()\n"], 'do_quote]>], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_which];


new object $help_cmd_dump: $help_cmds;

var $root manager = $help_cmd_dump;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870580692;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@dump", "@dump"];
var $help_node links = #[["textdump", $help_coldc_textdump], ["@program", $help_cmd_program]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax ", <$format, ["tt", [], ["@dump <objref> [options]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Dumps the source code for a particular object, such that you can upload it to another server. When you @dump an object, all of the information about the object required to reproduce it is dumped to the screen. ", <$format, ["np", [], [], 'do_np]>, " Options can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+t?extdump"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Lists the code in ", <$format, ["link", [["node", "$help_coldc_textdump"]], ["textdump"], 'do_link]>, " format rather than ", <$format, ["link", [["node", "$help_cmd_program"]], ["@program"], 'do_link]>, " format."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+m?ethods"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Lists methods."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+v?ariables"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Lists variables."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+h?eader"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Lists headers."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["textdump", "$help_coldc_textdump"], ["@program", "$help_cmd_program"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_dump];


new object $help_cmd_move: $help_cmds;

var $root manager = $help_cmd_move;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870580758;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@move|@mv|@copy|@cp", "@move|@mv|@copy|@cp"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["BUILDER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@move|@mv <objref> to <location>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["nobound", 1]], ["Syntax: ", <$format, ["tt", [], ["@move|@mv <objref>.<method1> to <objref>.<method2> [options]"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@copy|@cp <objref>.<method1> to <objref>.<method2> [options]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If you are a builder, @move will transport <objref> to <location>, assuming you pass all the permission checks. You can not, however, move a user into an object, although you can move an object into a user. ", <$format, ["np", [], [], 'do_np]>, "For programmers, @move moves <method1> to <method2> removing <method1> from it's original location. @copy copies <method1> to <method2> without removing <method1> from it's original location. ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Example:"], 'do_b]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], ["\n>@move Help TODO to $courtyard\nHelp TODO suddenly disappears.\nYou move Help TODO from The Pit to the Courtyard.\n\n>@move $vampire.pulse to $vampire.old_pulse\nYou move $vampire.pulse() to $vampire.old_pulse().\n\n>@copy $vampire.smurf_cmd to $vampire.tmp_smurf_cmd\nYou copy $vampire.smurf_cmd() to $vampire.tmp_smurf_cmd().\n\n"], 'do_quote]>], 'do_dfn]>, " Options can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+c?omment"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Sets the comment for the copy or move."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_move];


new object $help_cmd_chparent: $help_cmds;

var $root manager = $help_cmd_chparent;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870586634;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@chparents", "@chparents"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@chpar?ents <obj> to <parent> [, <parent>,...] "], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Changes the parents for <obj>."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_chparent];


new object $help_cmd_addparent: $help_cmds;

var $root manager = $help_cmd_addparent;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870589057;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@add-parent|@ap", "@add-parent|@ap"];
var $help_node links = #[["@del-p?arent", $help_cmd_delparent]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@add-p?arent|@ap <parent> to <objref>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Adds an additional <parent> to <objref>. This command does not remove any existing parents from the <objref>. See also ", <$format, ["link", [["node", "$help_cmd_delparent"]], ["@del-p?arent"], 'do_link]>, "."], #[['links, #[["@del-p?arent", "$help_cmd_delparent"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_addparent];


new object $help_cmd_addshortcut: $help_cmds;

var $root manager = $help_cmd_addshortcut;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870589235;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@add-shortcut|@as", "@add-shortcut|@as"];
var $help_node links = #[["@add-command", $help_cmd_addcmd], ["@del-shortcut", $help_cmd_delshortcut], ["@add-command-alias", $help_cmd_aca], ["@del-command-alias", $help_cmd_dca]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@add-s?hortcut|@as \"<shortcut>\" [to] \"<command>\" [on] <objref>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command adds a shortcut to a <command> on <object>. This is similar to the ", <$format, ["link", [["node", "$help_cmd_addcmd"]], ["@add-command"], 'do_link]>, " command, however, @add-shortcut allows you to add a shortcut to an existing command, with a different name or syntax. The scope of shortcuts is global, depending upon where it is added. A shortcut added to a command-ui object which others also use will be inherited by the other users (this is the primary difference between command shortcuts and command aliases). ", <$format, ["np", [], [], 'do_np]>, "The shortcut may include wildcards for where arguments are accepted (where it will match anything). These wildcards are defined using an ordered mechanism of a percent-sign and a number. An example would be the following shortcut, which defines two ordered wildcards of %1 and %2:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["\"page %1 with %2\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The command side of the definition must also include equivalent ordered wildcards, matching the same cards defined on the shortcut (but not necessarily in the same order). You can leave out wildcards on the command side. Wildcards on the shortcut side must be defined in order, starting from one. ", <$format, ["np", [], [], 'do_np]>, "A full example would be the shortcut of a dash (-) for paging:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@as \"-%1 %2\" to \"@page %1 with %2\" on $user.page_cmd"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_delshortcut"]], ["@del-shortcut"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_aca"]], ["@add-command-alias"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_dca"]], ["@del-command-alias"], 'do_link]>], #[['links, #[["@add-command", "$help_cmd_addcmd"], ["@del-shortcut", "$help_cmd_delshortcut"], ["@add-command-alias", "$help_cmd_aca"], ["@del-command-alias", "$help_cmd_dca"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_addshortcut];


new object $help_cmd_addvariable: $help_cmds;

var $root manager = $help_cmd_addvariable;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870589271;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@add-v?ariable|@av", "@add-v?ariable|@av"];
var $help_node links = #[["@del-v?ariable", $help_cmd_delvariable]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax ", <$format, ["tt", [], ["@add-v?ariable|@av <objref>,<variable> [=<default>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The purpose of @add-variable is to add variables to an <objref>, and optionally, set the variable's default value or type.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_delvariable"]], ["@del-v?ariable"], 'do_link]>, " ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@av $vampire,silly_names = [\"Brad\", \"Bruce\", \"Miro\", \"Brandon\"];\n"], 'do_quote]>], 'do_dfn]>], #[['links, #[["@del-v?ariable", "$help_cmd_delvariable"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_addvariable];


new object $help_cmd_delparent: $help_cmds;

var $root manager = $help_cmd_delparent;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870639383;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@del-parent|@dp", "@del-parent|@dp"];
var $help_node links = #[["@add-p?arent", $help_cmd_addparent]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax ", <$format, ["tt", [], ["@del-p?arent|@dp <parent> from <objref>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Deletes a <parent> from <objref>. This command does not remove any other existing parents from the <objref>. See also ", <$format, ["link", [["node", "$help_cmd_addparent"]], ["@add-p?arent"], 'do_link]>, "."], #[['links, #[["@add-p?arent", "$help_cmd_addparent"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_delparent];


new object $help_cmd_delvariable: $help_cmds;

var $root manager = $help_cmd_delvariable;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870645893;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@del-variable|@dv", "@del-variable|@dv"];
var $help_node links = #[["@add-v?ariable", $help_cmd_addvariable]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax ", <$format, ["tt", [], ["@del-v?ariable|@dv <objref>,<variable>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The purpose of @del-variable is to remove variables from an <objref>.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_addvariable"]], ["@add-v?ariable"], 'do_link]>], #[['links, #[["@add-v?ariable", "$help_cmd_addvariable"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_delvariable];


new object $help_cmd_ancestors: $help_cmds;

var $root manager = $help_cmd_ancestors;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870646587;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@ancestors", "@ancestors"];
var $help_node links = #[["@descendants", $help_cmd_descendants]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@ancestors <objref> [<levels>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command shows an object's ancestors. If <level> is present, it will additionally recursively show the ancestors of each parent an object has, to the depth specified by <levels>.", <$format, ["p", [], [], 'do_p]>, "See also ", <$format, ["link", [["node", "$help_cmd_descendants"]], ["@descendants"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@ancestors $vampire 2\nAncestors of $vampire:2 levels:\n$vampire [-----] (MI)\n  $admin [*-mvcC]\n    $programmer [*-mvcC] (MI)\n  $antisocial [*fmvcC]\n    $user_interfaces [*fmvc]\n"], 'do_quote]>], 'do_dfn]>], #[['links, #[["@descendants", "$help_cmd_descendants"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_ancestors];


new object $help_cmd_delshortcut: $help_cmds;

var $root manager = $help_cmd_delshortcut;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870646752;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@del-shortcut|@ds", "@del-shortcut|@ds"];
var $help_node links = #[["@add-shortcut", $help_cmd_addshortcut], ["@add-command-alias", $help_cmd_aca], ["@del-command-alias", $help_cmd_dca]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@ds \"<shortcut>\" [from] <objref>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Removes an existing shortcut from an object. ", <$format, ["np", [], [], 'do_np]>, "See also: ", <$format, ["link", [["node", "$help_cmd_addshortcut"]], ["@add-shortcut"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_aca"]], ["@add-command-alias"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_dca"]], ["@del-command-alias"], 'do_link]>], #[['links, #[["@add-shortcut", "$help_cmd_addshortcut"], ["@add-command-alias", "$help_cmd_aca"], ["@del-command-alias", "$help_cmd_dca"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_delshortcut];


new object $help_cmd_chmod: $help_cmds;

var $root manager = $help_cmd_chmod;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870646867;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@chmod|@mmod|@omod|@chflags", "@chmod|@mmod|@omod|@chflags"];
var $help_node links = #[["access", $help_coldc_methods_access], ["behavior", $help_coldc_methods_flags]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["nobound", 1]], ["Syntax: ", <$format, ["tt", [], ["@mmod <flags> <method> [<method ..]"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["dfn", [["nobound", 1]], ["Syntax: ", <$format, ["tt", [], ["@omod <flags> <object> [<object ..]"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["dfn", [["nobound", 1]], ["Syntax: ", <$format, ["tt", [], ["@chmod <flags> <object> [<object .]"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@chflag <flags> <object> [<object ..]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "These commands modify access flags on the object or method speficied. All of these are effectively aliases of each other, and are named for easy rememberance as to their function. For the purposes of this help, @chflag will be used, but all the other commands operate the same way. ", <$format, ["np", [], [], 'do_np]>, "The following table lists which flags may be used with each type of object or method. ", <$format, ["np", [], [], 'do_np]>, " Flags can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "30%,70%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["method ", <$format, ["link", [["node", "$help_coldc_methods_access"]], ["access"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["d?river, pri?vate, pro?tected, pu?blic, r?oot, fr?ob"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["method ", <$format, ["link", [["node", "$help_coldc_methods_flags"]], ["behavior"], 'do_link]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["no?override, l?ocked, na?tive, fo?rked"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["objects"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["cod?e, cor?e, fe?rtile, m?ethods, v?ariables"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["access", "$help_coldc_methods_access"], ["behavior", "$help_coldc_methods_flags"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_chmod];


new object $help_cmd_delmethod: $help_cmds;

var $root manager = $help_cmd_delmethod;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870646953;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@del-method|@dm", "@del-method|@dm"];
var $help_node links = #[["@del-command", $help_cmd_delcmd], ["@program", $help_cmd_program]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax ", <$format, ["tt", [], ["@del-m?ethod|@delm?ethod|@dm <objref>.<method>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command will remove an unwanted <method> from the <objref>. Once the <method> has been removed, you can't get it back, so be sure you want the method removed, or that you have a backup of it. Also, if a command references this method, be sure that you remove the command with ", <$format, ["link", [["node", "$help_cmd_delcmd"]], ["@del-command"], 'do_link]>, ".", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_program"]], ["@program"], 'do_link]>], #[['links, #[["@del-command", "$help_cmd_delcmd"], ["@program", "$help_cmd_program"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_delmethod];


new object $help_cmd_eval: $help_cmds;

var $root manager = $help_cmd_eval;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870647020;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@eval", "@eval"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@eval [<code>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command is a powerful tool given to programmers. Its primary function is to allow programmers to execute ColdC code without actually programming it as a method. Anything specified in <code> is compiled and executed immediately. Furthermore, it also provides profiling and debugging tools, and an alternate feature that will show the interpreter opcodes it becomes, rather than executing it. ", <$format, ["np", [], [], 'do_np]>, "The shortcut ", <$format, ["tt", [], [";"], 'do_tt]>, " can also be used in place of ", <$format, ["tt", [], ["@eval"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Example:"], 'do_b]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">; .location().announce(\"Testing.\")\nTesting.\n=> $courtyard (the Courtyard)\n[ seconds: 1.1022141; operations: 1506 (1506 ticks per second) ]\n"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In this example, the .location() gives us the object name of where we currently are ($courtyard). The .announce() says that this location should announce to all the players in this location our message (\"Testing.\"). If the code executes correctly, our message is displayed to everybody, and the @eval command returns the result of the expression, as well as the amount of time, operations, and ticks per second it took to perform the execution. Note: when measuring performance, the actual time it takes to execute is more important than the number of operations (because this is an interpreted language, different operations can be faster than the others, so the actual count is not a true representation of performance). ", <$format, ["subj", [["level", "2"]], ["Execution Environment"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "By default, @eval will assume the code you are specifying is an expression, and will prefix it with '", <$format, ["tt", [], ["return"], 'do_tt]>, "', so the value of the expression is returned. This is a problem if your code is a statement, instead of an expression (such as a looping statement). To avoid this you can define variables, or include 'return' in your code where it should be--and @eval will not prefix it. ", <$format, ["np", [], [], 'do_np]>, "Furthermore, @eval defines a set of variables which can be used by the ColdC code. These are: ", <$format, ["tt", [], ["me"], 'do_tt]>, " and ", <$format, ["tt", [], ["here"], 'do_tt]>, ", representing your own object and your current location, respectively. ", <$format, ["subj", [["level", "2"]], ["Environment Substitution"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Anywhere within the ColdC code (other than inside strings) you can use the carat character (", <$format, ["tt", [], ["^"], 'do_tt]>, ") followed by a string token of alphanumeric characters. If @eval finds this, it will try to match the token as a name against objects in your environment. If a match is found it will replace that token with the dbref for that object. ", <$format, ["subj", [["level", "2"]], ["Execution Flags"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "One of the following flags can be defined before the ColdC code (seperated with a semi-colon), which will change the execution behaviour: ", <$format, ["tt", [], ["trace"], 'do_tt]>, ", ", <$format, ["tt", [], ["debug"], 'do_tt]>, ", ", <$format, ["tt", [], ["profile"], 'do_tt]>, " or ", <$format, ["tt", [], ["opcodes"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "If ", <$format, ["tt", [], ["trace"], 'do_tt]>, " is defined, a trace of all method calls made during the execution will be printed after execution is complete--along with the tick number they were made at. If ", <$format, ["tt", [], ["debug"], 'do_tt]>, " is defined, the output is similar to ", <$format, ["tt", [], ["trace"], 'do_tt]>, " but the tick number of the return statement is also included. If ", <$format, ["tt", [], ["profile"], 'do_tt]>, " is defined, a breakdown of all method calls is provided, along with the number of ticks consumed by the method--sorted by the largest first. If ", <$format, ["tt", [], ["opcodes"], 'do_tt]>, " is defined, the code will not actually execute, but instead will return the interpreter's opcodes for the method."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_eval];


new object $help_cmd_grep: $help_cmds;

var $root manager = $help_cmd_grep;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870647047;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@grep", "@grep"];
var $help_node links = #[["regexp", $help_coldc_regexp]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@grep [options] <regexp> <object> <object>..."], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command allows you to search through the database for items matching the ", <$format, ["link", [["node", "$help_coldc_regexp"]], ["regexp"], 'do_link]>, ". Depending on the options selected, <object> may be either the root object to start searching from, or one (or more) of the indivdual objects to search. ", <$format, ["np", [], [], 'do_np]>, " Options can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "30%,70%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+d?escend"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Start searching from the following <object> and work down it's descendants list."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+f?ull"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Lists the method <regexp> was found in, as well as the line that contains the <regexp>."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+l?ist"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Lists the methods the <regexp> was found in."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+r?eplace-with=<text>"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Text to replace item matched by <regexp> with."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The following example will search through the database, starting with the $root object, and progress down it's descendants list searching for .tell. The numbers following the method names, are the line numbers within those methods that contain the <regexp>: ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@grep +d .tell $root\nSearching for \".tell\"...\n$root.uninit_root(): 25\n$root.initialize(): 16, 22 and 23\n$root.uninitialize(): 16, 17, 18, 27, 28, 30, 31, 32, 45, 46, 47, 55, 56, 57, 58 and 59\n$root.add_method(): 15\n$root.debug(): 12\n..\n"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Caution: It is advised that you don't descend from $root very often, as this tends to lag the server."], #[['links, #[["regexp", "$help_coldc_regexp"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_grep];


new object $help_cmd_id: $help_cmds;

var $root manager = $help_cmd_id;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870647065;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@id", "@id"];
var $help_node links = #[["@display", $help_cmd_display]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax ", <$format, ["tt", [], ["@id <objref>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The @id command provides summary information similar to the provided by ", <$format, ["link", [["node", "$help_cmd_display"]], ["@display"], 'do_link]>, ". However, there are no options to list variables, or methods. @id provides the following information as a one line summary: ", <$format, ["np", [], [], 'do_np]>, "$objref (objref name) [permissions] [parents] size ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@id $vampire\n$vampire (Vampire) [-----] [$admin, $antisocial] 5924 bytes\n"], 'do_quote]>], 'do_dfn]>], #[['links, #[["@display", "$help_cmd_display"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_id];


new object $help_cmd_join: $help_cmds;

var $root manager = $help_cmd_join;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870647079;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@join", "@join"];
var $help_node links = #[["teleports", $help_cmd_teleport]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax ", <$format, ["tt", [], ["@join <user>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command ", <$format, ["link", [["node", "$help_cmd_teleport"]], ["teleports"], 'do_link]>, " you to the same location that <user> is located."], #[['links, #[["teleports", "$help_cmd_teleport"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_join];


new object $help_cmd_trace: $help_cmds;

var $root manager = $help_cmd_trace;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870647128;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@trace-method|@trace", "@trace-method|@trace"];
var $help_node links = #[["pass()", $help_func_pass]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@trace-method|@trace <method>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command allows a programmer to find out where a method ", <$format, ["link", [["node", "$help_func_pass"]], ["pass()"], 'do_link]>, "'s to. ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Example:"], 'do_b]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@trace .name\nMethod trace of $vampire.name():\n ----    6 $root.name([args])\n ----   55 $has_name.name([args])\n"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The first method listed is the top level method to which @trace was able to go back too. Following it, is each method farther away, until it can find no other matches."], #[['links, #[["pass()", "$help_func_pass"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_trace];


new object $help_cmd_undefsetting: $help_cmds;

var $root manager = $help_cmd_undefsetting;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870647179;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@undef-setting|@undefine-setting", "@undef-setting|@undefine-setting"];
var $help_node links = #[["@define-setting", $help_cmd_defsetting]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@undef-setting|@undefine-setting <definer>:<setting>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Removes the <setting> from the object represented by <definer>. ", <$format, ["np", [], [], 'do_np]>, "See also: ", <$format, ["link", [["node", "$help_cmd_defsetting"]], ["@define-setting"], 'do_link]>], #[['links, #[["@define-setting", "$help_cmd_defsetting"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_undefsetting];


new object $help_cmd_defsetting: $help_cmds;

var $root manager = $help_cmd_defsetting;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870647223;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@def-setting|@define-setting", "@def-setting|@define-setting"];
var $help_node links = #[["@set", $help_cmd_set], ["@config-setting", $help_cmd_configsetting]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@def-set?ting|@define-set?ting <definer>:<setting>[=default] [options]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command creates, and sets up new settings that can be modified with ", <$format, ["link", [["node", "$help_cmd_set"]], ["@set"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, " Options can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "30%,70%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+get"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Sets the method that is called when you try to get the contents of the setting."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+get-a?rgs"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Data to return when the setting is gotten. If this option is empty, when the setting is gotten it returns the contents of the setting."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+set"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Sets the method that is called in order to set this setting."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+set-a?rgs"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Additional data used by the method in +set option."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+parse"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Sets the method that is called when you @set the setting, this method then parses it before saving it to the setting."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+parse-a?rgs"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Additional data used by the method in +parse option."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+c?lear"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Sets the method for clearing the setting."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+f?ormat"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Sets the method that is called when other methods want the setting formatted for display."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+a?ccess"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Sets that determines who or what has access to this setting."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+t?ype"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Types can be any ColdC type, 'boolean, or 'item-list."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, " ", <$format, ["np", [], [], 'do_np]>, "See also: ", <$format, ["link", [["node", "$help_cmd_configsetting"]], ["@config-setting"], 'do_link]>], #[['links, #[["@set", "$help_cmd_set"], ["@config-setting", "$help_cmd_configsetting"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_defsetting];


new object $help_cmd_configsetting: $help_cmds;

var $root manager = $help_cmd_configsetting;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870647269;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@config-setting|@configure-setting", "@config-setting|@configure-setting"];
var $help_node links = #[["@def-setting", $help_cmd_defsetting]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@config-set?ting|@configure-set?ting <definer>:<setting>[=default] [options]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command displays how settings are currently setup, and can modify the options that were set when the setting was created with ", <$format, ["link", [["node", "$help_cmd_defsetting"]], ["@def-setting"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Example:"], 'do_b]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@config-set me:rl-email\nReconfigured setting $user_info:rl-email as:\n    +get=get_user_info\n    +set=set_user_info\n    +clear=clear_user_info\n    +format=format_user_info\n    +access=public_user_info\n"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The complete list of options and their definitions can be found by looking at the ", <$format, ["link", [["node", "$help_cmd_defsetting"]], ["@def-setting"], 'do_link]>, " help page."], #[['links, #[["@def-setting", "$help_cmd_defsetting"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_configsetting];


new object $help_cmd_teleport: $help_cmds;

var $root manager = $help_cmd_teleport;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870650078;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@teleport|@go", "@teleport|@go"];
var $help_node links = #[["@join", $help_cmd_join]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["BUILDER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@teleport|@go <location>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command transports your user character to <location>, if it can pass through any locks and permission checks that are in place on the <location>.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_join"]], ["@join"], 'do_link]>], #[['links, #[["@join", "$help_cmd_join"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_teleport];


new object $help_cmd_attach: $help_cmds;

var $root manager = $help_cmd_attach;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870659823;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@attach", "@attach"];
var $help_node links = #[["@build", $help_cmd_build], ["Exits and Entrances", $help_places_paths]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["BUILDER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@attach <place1> to <place2>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command attaches an exit from <place1> to <place2>. It will prompt for the name of the exit, and a description for the exit.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_build"]], ["@build"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_places_paths"]], ["Exits and Entrances"], 'do_link]>], #[['links, #[["@build", "$help_cmd_build"], ["Exits and Entrances", "$help_places_paths"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_attach];


new object $help_cmd_bugs: $help_cmds;

var $root manager = $help_cmd_bugs;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870659838;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@bugs|@pr|@problems", "@bugs|@pr|@problems"];
var $help_node links = #[["@report", $help_cmd_report]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["BUILDER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@bug?s"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This is a meta command which places you in a menu-based bug management system. From within this system you have the option to scan unclaimed open bugs reports, scan bugs you are currently working on, scan all open bug reports, review all repaired bugs, all non-archived/non-dismissed and report a new bug. ", <$format, ["np", [], [], 'do_np]>, "Bugs that enter this system usually enter in one of two ways, from the @bugs report new bug option, and from ", <$format, ["link", [["node", "$help_cmd_report"]], ["@report"], 'do_link]>, "."], #[['links, #[["@report", "$help_cmd_report"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_bugs];


new object $help_cmd_children: $help_cmds;

var $root manager = $help_cmd_children;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870660012;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@children|@kids", "@children|@kids"];
var $help_node links = #[["@parents", $help_cmd_parents]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["BUILDER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@child?ren|@kids <objref>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Displays the name, flags, size, and manager of <objref>'s children.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_parents"]], ["@parents"], 'do_link]>, " ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@children $admin\nChildren of $admin (Generic Admin):\n#  Name                         Flags   Size   Manager\n2  $brian (Brian)               --m-c   3749   $brian (Brian)\n3  $user_ken (Ken)              -----   2671   $user_ken (Ken)\n2  $miro (Miro)                 -----   7799   $miro (Miro)\n3  $user_bruce (Bruce)          -----   4346   $user_bruce (Bruce)\n2  $vampire (Vampire)           -----   6581   $vampire (Vampire)\n1  $brandon (Brandon)           --m--   5550   $brandon (Brandon)\n"], 'do_quote]>], 'do_dfn]>], #[['links, #[["@parents", "$help_cmd_parents"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_children];


new object $help_cmd_destroy: $help_cmds;

var $root manager = $help_cmd_destroy;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870660035;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@destroy", "@destroy"];
var $help_node links = #[["Frobs", $help_coldc_types_frobs], ["discard", $help_cmd_discard], ["@new", $help_cmd_new]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["BUILDER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@destroy <object>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Destroys an <object> and removes it from the system. This command will not destroy ", <$format, ["link", [["node", "$help_coldc_types_frobs"]], ["Frobs"], 'do_link]>, ", use ", <$format, ["link", [["node", "$help_cmd_discard"]], ["discard"], 'do_link]>, " instead.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_new"]], ["@new"], 'do_link]>], #[['links, #[["Frobs", "$help_coldc_types_frobs"], ["discard", "$help_cmd_discard"], ["@new", "$help_cmd_new"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_destroy];


new object $help_cmd_parents: $help_cmds;

var $root manager = $help_cmd_parents;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870660071;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@parents", "@parents"];
var $help_node links = #[["@children", $help_cmd_children]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["BUILDER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@par?ents <objref>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Displays the name, flags, size, and manager of <objref>'s parents.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_children"]], ["@children"], 'do_link]>, " ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@parents $vampire\nParents of Vampire ($vampire):\n#  Name                         Flags   Size   Manager\n12 $admin (Generic Admin)       *-mvcC  40389  $admin (Generic Admin)\n16 $antisocial                  *fmvcC  9756   $antisocial\n"], 'do_quote]>], 'do_dfn]>], #[['links, #[["@children", "$help_cmd_children"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_parents];


new object $help_cmd_realms: $help_cmds;

var $root manager = $help_cmd_realms;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870660092;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@realms", "@realms"];
var $help_node links = #[["Realms", $help_places_realms]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["BUILDER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@realm?s"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command displays all the names of the known realms on the server.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_places_realms"]], ["Realms"], 'do_link]>], #[['links, #[["Realms", "$help_places_realms"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_realms];


new object $help_cmd_report: $help_cmds;

var $root manager = $help_cmd_report;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870663118;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@report", "@report"];
var $help_node links = #[["@bug", $help_cmd_bugs]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@report"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command is used to report bugs within the system, @report will prompt the user for a description of the bug found.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_bugs"]], ["@bug"], 'do_link]>], #[['links, #[["@bug", "$help_cmd_bugs"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_report];


new object $help_cmd_build: $help_cmds;

var $root manager = $help_cmd_build;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870664087;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@build", "@build"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["BUILDER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@build"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This is the interactive build command, which takes you step by step through the process of extending your VR surroundings. From creating a path to/from the new place, creating the place itself, setting the place's realm, and setting all of the descriptions for the place, and the ways to and from it. ", <$format, ["np", [], [], 'do_np]>, "To use this command simply go to the place you wish to extend, and type ", <$format, ["tt", [], ["@build"], 'do_tt]>, ". It will prompt you for all of the information to build another place connected to your current location."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_build];


new object $help_cmd_dig: $help_cmds;

var $root manager = $help_cmd_dig;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870664099;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@dig", "@dig"];
var $help_node links = #[["@attach", $help_cmd_attach], ["@build", $help_cmd_build]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["BUILDER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@dig <place>"], 'do_tt]>, <$format, ["br", [], [], 'do_br]>, "Syntax: ", <$format, ["tt", [], ["@dig <leaving way>[|<arriving way>] to <place>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The first form of this command creates a new place, with the name being whatever you specify for <place>. The object name for the new place will be displayed, for easy reference later. ", <$format, ["np", [], [], 'do_np]>, "The second form of the command works the same as the first, but also allows you to define a path and attach leaving and arriving ways for the path, at the same time the place is created. This path will be linked from your current location to the new place. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@dig north|south to Hallway"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This will create a new place named ", <$format, ["tt", [], ["\"Hallway\""], 'do_tt]>, " and will build a path with ", <$format, ["tt", [], ["\"north\""], 'do_tt]>, " going from the current location to the Hallway (e.g. leaving), and ", <$format, ["tt", [], ["\"south\""], 'do_tt]>, " going from the Hallway to the current location (e.g. arriving). ", <$format, ["np", [], [], 'do_np]>, "See also: ", <$format, ["link", [["node", "$help_cmd_attach"]], ["@attach"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_build"]], ["@build"], 'do_link]>], #[['links, #[["@attach", "$help_cmd_attach"], ["@build", "$help_cmd_build"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_dig];


new object $help_cmd_discard: $help_cmds;

var $root manager = $help_cmd_discard;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870757106;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "discard", "discard"];
var $help_node links = #[["@destroy", $help_cmd_destroy], ["Frobs", $help_coldc_types_frobs], ["@new", $help_cmd_new]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["discard <frob>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Destroys a <frob> and removes it from the system. This command will not destroy normal objects, use ", <$format, ["link", [["node", "$help_cmd_destroy"]], ["@destroy"], 'do_link]>, " instead.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_coldc_types_frobs"]], ["Frobs"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_new"]], ["@new"], 'do_link]>], #[['links, #[["@destroy", "$help_cmd_destroy"], ["Frobs", "$help_coldc_types_frobs"], ["@new", "$help_cmd_new"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_discard];


new object $help_cmd_age: $help_cmds;

var $root manager = $help_cmd_age;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870925660;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@age", "@age"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@age <objref>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Displays the date <objref> was created, and how long ago that was from the current time. When getting the @age of players, it will additionally display how much time that player has been connected to the server. ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@age Vampire\nVampire was created on Monday January 13 1997\nHe is 6 months, 19 days, 2 hours and 47 minutes old.\nHe has logged 4 months, 17 days, 22 hours, 7 minutes and 33 seconds online.\n"], 'do_quote]>], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_age];


new object $help_cmd_audit: $help_cmds;

var $root manager = $help_cmd_audit;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870925742;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@audit", "@audit"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@audit <object> +m?anages"], 'do_tt]>, <$format, ["br", [], [], 'do_br]>, "Syntax: ", <$format, ["tt", [], ["@audit <object> +w?rites"], 'do_tt]>, <$format, ["br", [], [], 'do_br]>, "Syntax: ", <$format, ["tt", [], ["@audit <object> +trusted-by"], 'do_tt]>, <$format, ["br", [], [], 'do_br]>, "Syntax: ", <$format, ["tt", [], ["@audit <object> +q?uota [+s?ummary]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Display a list of objects managed, writable or trusted by the given <object>. In the case of the +quota option, list a total byte usage for the <object>. If +summary is also specified, only a summary of the total used and allocated for <object> is displayed. ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@audit Vampire +quota\nObjects managed by Vampire ($vampire):      bytes Location\n  $vampire (Vampire)                        6,701 [The Pit]\n  $note_79 (UI_stuff)                         492 [Vampire]\n  $thing_265 (parser)                         406 [Vampire]\n  $help_cmd_addshortcut (@add-s?hortcut       414\nTotal usage: 27,885 bytes\nTotal quota: 75,000 bytes\nRemaining:   47,115 bytes"], 'do_quote]>], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_audit];


new object $help_cmd_commands: $help_cmds;

var $root manager = $help_cmd_commands;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870925794;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@commands", "@commands"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@com?mands <objref> [options]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Displays all the commands that <objref> has on it either directly, or from it's parents. ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@commands Squeak +f\nRemote commands on Squeak the lemming:\n  \"step on <this>\"                                    .step_cmd()\n  \"beat the <this>\"                                   .beat_cmd()\n  \"beat <this>\"                                       .beat_cmd()\n  \"beat up the <this>\"                                .beat_cmd()\n  \"beat up <this>\"                                    .beat_cmd()\n  \"jump on the <this>\"                                .step_cmd()\n  \"jump on <this>\"                                    .step_cmd()\n  \"pet <this>\"                                        .pet_cmd()\n"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["np", [], [], 'do_np]>, " Options can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "30%,70%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+f?ull"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Shows command followed by it's method."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+a?ll"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Shows all of <objref>'s commands, including those inherited from parents."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+l?ocal"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Shows any local commands that are defined on the object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+r?emote"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Shows any remote commands that are defined on the object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+s?hortcuts"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Shows any shortcuts that are defined on the object."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_commands];


new object $help_cmd_context: $help_cmds;

var $root manager = $help_cmd_context;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870925820;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@context", "@context"];
var $help_node links = #[["Environment", $help_environment]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@context"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Displays your environmental contexts. The server records the last object you named, as well as all of the last objects you named (with a gender).", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_environment"]], ["Environment"], 'do_link]>, " ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@context\nLast thing: Generic User Object\nLast it:    Generic User Object\nLast her:   Squeak the lemming\nLast him:   Brad\n"], 'do_quote]>], 'do_dfn]>], #[['links, #[["Environment", "$help_environment"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_context];


new object $help_cmd_date: $help_cmds;

var $root manager = $help_cmd_date;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870925836;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@date|@time", "@date|@time"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@date|@time"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Displays the server's local date and time. ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@date\n10:52 PM Wednesday, August 06 1997 MDT\n"], 'do_quote]>], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_date];


new object $help_cmd_examine: $help_cmds;

var $root manager = $help_cmd_examine;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926002;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@examine", "@examine"];
var $help_node links = #[["setting", $help_settings]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@ex?amine [+c?hop]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Displays an overview of information about the object, such as the name, manager, parents, location, and description. ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@examine Vampire\nObject (@rename):    Vampire ($vampire)\nTemplates (@ant):    none\nCreated:             Mon Jan 13 18:19:17 1997\nQuota:               75,000 bytes\nSize:                6,710 bytes (on disk)\nPerms (@chmod):\nManager (@chmanage): Vampire ($vampire)\nWriters (@aw/@dw):   (none)\nTrusted (@at/@dt):   (none)\nParents (@ap/@dp):   $admin and $antisocial\nLocation (@move):    $the_pit (The Pit)\nDescription (@describe):\nAn insane, poorly spelling creature.\n"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+c?hop"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Chops lines longer than the players cols ", <$format, ["link", [["node", "$help_interface_settings"]], ["setting"], 'do_link]>, "."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["setting", "$help_interface_settings"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_examine];


new object $help_cmd_finger: $help_cmds;

var $root manager = $help_cmd_finger;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926022;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@finger|@ustat", "@finger|@ustat"];
var $help_node links = #[["age", $help_cmd_age], ["quota", $help_cmd_audit]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@finger|@ustat <objref>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Provides general information about the <objref> such as name, ", <$format, ["link", [["node", "$help_cmd_age"]], ["age"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_audit"]], ["quota"], 'do_link]>, ", and for users, it additionally lists general user information, and information about any connections it is currently using. ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@finger Vampire\nInformation on Vampire (use @set to change):\n  Vampire was created on Monday January 13 1997\n  He is 6 months, 19 days, 18 hours, 40 minutes and 4 seconds old.\n  He has logged 4 months, 17 days, 22 hours, 7 minutes and 33 seconds online.\n  Quota:\n    Total:     75,000\n    Used:      28,983\n    Remaining: 46,017\n"], 'do_quote]>], 'do_dfn]>], #[['links, #[["age", "$help_cmd_age"], ["quota", "$help_cmd_audit"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_finger];


new object $help_cmd_map: $help_cmds;

var $root manager = $help_cmd_map;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926082;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@map", "@map"];
var $help_node links = #[["Generic Map", $help_obj_generic_map]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@map"], 'do_tt]>, " ", <$format, ["np", [], [], 'do_np]>, "@map shows you your surroundings, if the current room or realm recognize them. See ", <$format, ["link", [["node", "$help_obj_generic_map"]], ["Generic Map"], 'do_link]>, " for more information."], #[['links, #[["Generic Map", "$help_obj_generic_map"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_map];


new object $help_cmd_monitor: $help_cmds;

var $root manager = $help_cmd_monitor;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926114;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@monitor", "@monitor"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@monitor [on | off]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command turns on and off monitoring of actions, and spoofs. If you have monitoring turned on, you can see what, if anything has been spoofed, by simply doing @monitor without any arguments. ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["ind", "3"]], [<$format, ["quote", [], [">@monitor\n$user_bruce (Bruce)  $courtyard.announce() line 9   Bruce says, \"it does...\n$vampire (Vampire)   $courtyard.announce() line 9   Vampire says, \"bah\"\n$vampire (Vampire)   $courtyard.announce() line 9   Vampire doesn't like...\n0                    $courtyard.announce() line 9   <$message_frob, #[[\"gene...\n"], 'do_quote]>], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_monitor];


new object $help_cmd_news: $help_cmds;

var $root manager = $help_cmd_news;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926179;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@news", "@news"];
var $help_node links = #[["@read", $help_mail_read]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@news"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command lists recent postings to the *news mail list. ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@news\nthe Cold Dark news:\n\n        23) oif\n        24) RC5 Challenge and the Cold Project Team\n        25) @help $help_node\n        26) Building the Castle\n\n"], 'do_quote]>], 'do_dfn]>, "Use ", <$format, ["link", [["node", "$help_mail_read"]], ["@read"], 'do_link]>, " #, where # is the news item number, such as \"@read 1\". All news items can be found on mail list *news."], #[['links, #[["@read", "$help_mail_read"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_news];


new object $help_cmd_password: $help_cmds;

var $root manager = $help_cmd_password;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926204;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@password|@passwd", "@password|@passwd"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [["nobound", 1]], ["Syntax: ", <$format, ["tt", [], ["@password|@passwd"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@password|@passwd <old password> <new password>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command allows a user to change it's password. In the first form, it will prompt you for your current password, and then you will be asked to enter your new password. In the second form, you can enter both your <old password> and <new password>, as a one line command. ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@password foobar barfoo\n"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@password\nCurrent Password (@abort to abort):\n   <non-echoed current password>\nNew Password (@abort to abort):\n   <non-echoed new password>\nRetype New Password (@abort to abort):\n   <non-echoed new password>\n"], 'do_quote]>], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_password];


new object $help_cmd_quit: $help_cmds;

var $root manager = $help_cmd_quit;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926235;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@quit", "@quit"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@quit"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command logs your current connection off the server. Any other connections you have to the server remain unaffected."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_quit];


new object $help_cmd_status: $help_cmds;

var $root manager = $help_cmd_status;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926275;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@status", "@status"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@status [+cache]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Displays technical information about the driver and core. The available driver information may vary, depending upon what the operating system provides. ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@status\n--- the Cold Dark status report ---\nSystem is:        clean, will skip backup.\nSystem lag:       0.0\nNext dbref:       #47968\nDriver:           Cold Genesis 1.1p0-STABLE\nCore:             ColdCore 3.0a9.02\nStarted:          2 days, 4 hours, 49 minutes and 3 seconds ago\nBackup:     last: 20 minutes ago\n            next: 40 minutes from now\n        interval: 1 hour\nCPU time used:    user: 3 minutes, 52 seconds and 399 milliseconds\n                  system: 49 seconds and 478 milliseconds\nPage:             57742 reclaims 807 faults\nContext switches: 114616 voluntary 8071 involuntary\nSignals:          53\n---"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In addition, administrators may specify the option ", <$format, ["tt", [], ["+cache"], 'do_tt]>, " to receive a visual map of the object cache in memory. An example of what it may look like is: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\nCache Size: 61x10\nCache Map (Horizontal):\n +--------------------------- WIDTH ---------------------------\nD|A.A.....I...........aa...................a.....A.......I.....\nE|......................I...................................II.\nP|..................I...........................I..............\nT|......I.........I.............................I..............\nH|...........I....II..............I.....I......................\n |.............I....I..........................................\n |................... ............. ..........  ......... .....\n |.... ....I... .....  ...........  ..........  ......... .....\n |...   ....... .....      ... ...  I.........   .......   ....\n |.      ...  . ..  .           .   ..            .. .     ....\n +-------------------------------------------------------------"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If the width of the cache is too wide to fit the screen, it will be displayed vertically instead of horizontally. In the map the character '", <$format, ["tt", [], ["a"], 'do_tt]>, "' represents an active object. If it is capitalized it represents an active dirty object. If it is a capital '", <$format, ["tt", [], ["I"], 'do_tt]>, "' it represents an inactive dirty object. Periods represent inactive clean objects which will not have to be written to disk. Keep in mind that an active object is only in reference to those used in the current task--that being the task which is displaying the cache map."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_status];


new object $help_cmd_exits: $help_cmds;

var $root manager = $help_cmd_exits;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926312;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@ways|@exits", "@ways|@exits"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: '", <$format, ["tt", [], ["@ways"], 'do_tt]>, "' ", <$format, ["np", [], [], 'do_np]>, "@ways command prints the exits from the current room. Its exact formatting depends on the ", <$format, ["tt", [], ["exit-style"], 'do_tt]>, " setting on the player (can be one of none, brief, template?s, long or verbose)."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_exits];


new object $help_cmd_whereis: $help_cmds;

var $root manager = $help_cmd_whereis;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926362;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@whereis|@where-is", "@whereis|@where-is"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: `", <$format, ["tt", [], ["@where-is <user>[,<user>...]"], 'do_tt]>, " ", <$format, ["np", [], [], 'do_np]>, "The command prints out the location of each user in the list. It only prints the realm, not the exact room."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_whereis];


new object $help_cmd_who: $help_cmds;

var $root manager = $help_cmd_who;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926371;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@who", "@who"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@who [<options>] [<users>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command in it's default form lists all users currently connected to the system. The @who listing can be used to show information about various groups of users depending on what usernames and options are given.", <$format, ["p", [], [], 'do_p]>, "Users should be specified separated by commas (optionally, with \"and\" before the last one, as in english). ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@who\n--- Connected Users (1) ---\nName      On for  Location\n----      ------  --------\nVampire   2 days  Solar System (NASA, Space Wing)\n"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@who vampire, scott, and brad\n--- Users (3) ---\nName     On for   Idle    Location\n----     ------   ----    --------\nVampire  10 days          Nowhere (<Creation>)\nBrad     3 days   22 hrs  the Courtyard (Caislea'n, Taobh Thiar)\nScott    5 hrs    2 hrs   the Courtyard (Caislea'n, Taobh Thiar)\n---\n"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["np", [], [], 'do_np]>, " Options can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "30%,70%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+admin"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["List all connected admins."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+prog"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["List all connected programmers."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+all"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["List all users in the specified group (admins or programmers), connected or not."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+short"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Display @who listing in short form."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+sort=<type>"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Sort the users listed according to <type>:", <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["tt", [], ["idle"], 'do_tt]>], 'do_dt]>, <$format, ["dd", [], ["How long they've been idle"], 'do_dd]>, <$format, ["dt", [], [<$format, ["tt", [], ["connected"], 'do_tt]>], 'do_dt]>, <$format, ["dd", [], ["How long they've been connected"], 'do_dd]>, <$format, ["dt", [], [<$format, ["tt", [], ["name"], 'do_tt]>], 'do_dt]>, <$format, ["dd", [], ["Alphabetically by name"], 'do_dd]>, <$format, ["dt", [], [<$format, ["tt", [], ["location"], 'do_tt]>], 'do_dt]>, <$format, ["dd", [], ["Grouped by location"], 'do_dd]>, <$format, ["dt", [], [<$format, ["tt", [], ["place"], 'do_tt]>], 'do_dt]>, <$format, ["dd", [], ["(same as ", <$format, ["tt", [], ["location"], 'do_tt]>, ")"], 'do_dd]>], 'do_dl]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["-sort=<type>"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Same as ", <$format, ["tt", [], ["+sort"], 'do_tt]>, ", but sort in descending order."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_who];


new object $help_cmd_drop: $help_cmds;

var $root manager = $help_cmd_drop;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926490;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "drop", "drop"];
var $help_node links = #[["inventory", $help_cmd_inventory], ["get", $help_cmd_get]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["drop <object>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command allows you to move objects in your ", <$format, ["link", [["node", "$help_cmd_inventory"]], ["inventory"], 'do_link]>, " to your current location.", <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_get"]], ["get"], 'do_link]>], #[['links, #[["inventory", "$help_cmd_inventory"], ["get", "$help_cmd_get"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_drop];


new object $help_cmd_get: $help_cmds;

var $root manager = $help_cmd_get;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926521;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "get|take", "get|take"];
var $help_node links = #[["inventory", $help_cmd_inventory], ["drop", $help_cmd_drop]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [["nobound", 1]], ["Syntax: ", <$format, ["tt", [], ["get|take <object>"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["get|take <object> from <location>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command allows you to move objects from your current location to your ", <$format, ["link", [["node", "$help_cmd_inventory"]], ["inventory"], 'do_link]>, ".", <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "The second form allows you to move objects from an alternate location to your inventory.", <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_drop"]], ["drop"], 'do_link]>], #[['links, #[["inventory", "$help_cmd_inventory"], ["drop", "$help_cmd_drop"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_get];


new object $help_cmd_inventory: $help_cmds;

var $root manager = $help_cmd_inventory;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926540;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "inventory", "inventory"];
var $help_node links = #[["description", $help_cmd_describe]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["i?nventory"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Displays your name, your ", <$format, ["link", [["node", "$help_cmd_describe"]], ["description"], 'do_link]>, ", your state, and the contents of what your user is carrying. ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">inventory\nVampire\nAn insane, poorly spelling creature.\nHe is wearing Cloak.\nHe is awake.\nHe is holding:\n        UI_stuff\n        parser\n        big birthday cake\n        list_of_places\nVampire's eyes do not glow from mojo.\n"], 'do_quote]>], 'do_dfn]>], #[['links, #[["description", "$help_cmd_describe"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_inventory];


new object $help_cmd_look: $help_cmds;

var $root manager = $help_cmd_look;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870926567;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "look|examine", "look|examine"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["look|examine <location | object>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command displays your current surroundings including the description and contents of the location; or the description and contents of the object you are looking at."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_look];


new object $help_cmd_quote: $help_cmds;

var $root manager = $help_cmd_quote;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874182075;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "quote", "quote"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "This interaction command allows you to quote (without any substition by the system) a line of text. It can also be used via the '|' shortcut. ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Examples:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">quote Brandon giggles like a little schoolgirl.\nVampire | Brandon giggles like a little schoolgirl.\n\n>|Brandon beats Vampire with a wet noddle.\nVampire | Brandon beats Vampire with a wet noddle.\n"], 'do_quote]>], 'do_dfn]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_quote];


new object $help_cmd_remembered: $help_cmds;

var $root manager = $help_cmd_remembered;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874198526;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@remembered", "@remembered"];
var $help_node links = #[["@remember", $help_cmd_remember]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@remembered"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Displays the objects you ", <$format, ["link", [["node", "$help_cmd_remember"]], ["@remember"], 'do_link]>, " and the names that you have given them. ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@remembered\nRemembered Items:\n  goofy is $user_gorren (Gorren)\n"], 'do_quote]>], 'do_dfn]>], #[['links, #[["@remember", "$help_cmd_remember"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_remembered];


new object $help_cmd_forget: $help_cmds;

var $root manager = $help_cmd_forget;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874199317;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@forget", "@forget"];
var $help_node links = #[["@remember", $help_cmd_remember], ["@remembered", $help_cmd_remembered]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@forget <object>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This is the opposite of the ", <$format, ["link", [["node", "$help_cmd_remember"]], ["@remember"], 'do_link]>, " command. This allows you to selectively forget things that you have aliased to easier to remember names.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_remembered"]], ["@remembered"], 'do_link]>], #[['links, #[["@remember", "$help_cmd_remember"], ["@remembered", "$help_cmd_remembered"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_forget];


new object $help_cmd_aca: $help_cmds;

var $root manager = $help_cmd_aca;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874972060;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@add-command-a?lias|@aca?lias", "@add-command-a?lias|@aca?lias"];
var $help_node links = #[["@del-command-alias", $help_cmd_dca], ["@command-aliases", $help_cmd_ca]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@add-command-a?lias|@aca?lias \"<alias>\" [to] \"<command>\""], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "@aca allows you to alias one command to another name, for yourself (to do this globally see ", <$format, ["link", [["node", "$help_cmd_dca"]], ["@del-command-alias"], 'do_link]>, " ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@aca \"poof %1\" to \"pub %1\"\nNew command alias \"poof %1\" => \"pub %1\" added."], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The new alias 'poof %1' will now allow you to talk on the public channel (to which 'pub %1' points to) as such:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">poof hello all!\n<Public> Vampire: hello all!\n"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_dca"]], ["@del-command-alias"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_ca"]], ["@command-aliases"], 'do_link]>], #[['links, #[["@del-command-alias", "$help_cmd_dca"], ["@command-aliases", "$help_cmd_ca"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_aca];


new object $help_cmd_dca: $help_cmds;

var $root manager = $help_cmd_dca;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874972098;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@del-command-a?lias|@dca?lias", "@del-command-a?lias|@dca?lias"];
var $help_node links = #[["@add-command-alias", $help_cmd_aca], ["@command-aliases", $help_cmd_ca]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@del-command-a?lias|@dca?lias <alias>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command deletes an alias previously created with ", <$format, ["link", [["node", "$help_cmd_aca"]], ["@add-command-alias"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@del-command-alias \"poof %1\"\nDeleted command alias \"poof %1\"."], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_aca"]], ["@add-command-alias"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_ca"]], ["@command-aliases"], 'do_link]>], #[['links, #[["@add-command-alias", "$help_cmd_aca"], ["@command-aliases", "$help_cmd_ca"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_dca];


new object $help_cmd_ca: $help_cmds;

var $root manager = $help_cmd_ca;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874973168;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@command-a?liases|@ca?liases", "@command-a?liases|@ca?liases"];
var $help_node links = #[["@del-command-alias", $help_cmd_dca], ["@add-command-alias", $help_cmd_aca]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@command-a?liases|@ca?liases"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "@command-aliases lists any and all commands that you have aliased to another command.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_dca"]], ["@del-command-alias"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_aca"]], ["@add-command-alias"], 'do_link]>], #[['links, #[["@del-command-alias", "$help_cmd_dca"], ["@add-command-alias", "$help_cmd_aca"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_ca];


new object $help_cmd_edit: $help_cmds;

var $root manager = $help_cmd_edit;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 877034883;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@edit", "@edit"];
var $help_node links = #[["@cleanup-sessions", $help_cmd_cs], ["@msg", $help_cmd_msg], ["Editor subsystem", $help_sys_editor]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [["nobound", 1]], ["Syntax: ", <$format, ["tt", [], ["@edit"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["dfn", [["nobound", 1]], ["Syntax: ", <$format, ["tt", [], ["@edit <prose> [+t?ype]"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@edit <method> [+t?ype]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In the first case @edit will report if you have any editor sessions running in the background. To end these editor sessions, you can either resume them and exit properly from them, or you can kill them with ", <$format, ["link", [["node", "$help_cmd_cs"]], ["@cleanup-sessions"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "In the second case, users can use @edit to change descriptions (prose) of things. Such as in the example below. ", <$format, ["np", [], [], 'do_np]>, "As a programmer, additional functionality is provided, that allows you to edit methods with this command. ", <$format, ["np", [], [], 'do_np]>, "Without [+t?ype], a reasonable default is chosen. The [+t?ype] option takes the following possible inputs: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["help"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Edits the help text on an object (such as a help node)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["messages"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Edits the messages on the object. See also: ", <$format, ["link", [["node", "$help_cmd_msg"]], ["@msg"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["prose"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Edits the objects description."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["text"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Edits the text the object contains (such as in a $note)."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, " ", <$format, ["np", [], [], 'do_np]>, " ", <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@edit me\nEditor invoked with Vampire/prose.\nType 'help' to list available commands.\n>list\n  =>1: Some silly description\n    2: An insane, poorly spelling\n    3: creature.\n  [END]\n>done\n"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_sys_editor"]], ["Editor subsystem"], 'do_link]>], #[['links, #[["@cleanup-sessions", "$help_cmd_cs"], ["@msg", "$help_cmd_msg"], ["Editor subsystem", "$help_sys_editor"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_edit];


new object $help_cmd_cs: $help_cmds;

var $root manager = $help_cmd_cs;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 877035960;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@cleanup-sessions|@c-s", "@cleanup-sessions|@c-s"];
var $help_node links = #[["@edit", $help_cmd_edit]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@cleanup-sessions|@c-s <editor session number>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command destroys old editor sessions which are running in the background, any changes which have been made to these edit sessions will not be saved. To find out which (if any) sessions you have running, use the ", <$format, ["link", [["node", "$help_cmd_edit"]], ["@edit"], 'do_link]>, " command."], #[['links, #[["@edit", "$help_cmd_edit"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_cs];


new object $help_cmd_mcp_upload: $help_cmds;

var $root manager = $help_cmd_mcp_upload;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 877037992;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@mcp-upload-session", "@mcp-upload-session"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This command is used in conjunction with the MCP editor, and should not normally be called by a user."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_mcp_upload];


new object $help_cmd_give: $help_cmds;

var $root manager = $help_cmd_give;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 877822514;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "give|put", "give|put"];
var $help_node links = #[["inventory", $help_cmd_inventory], ["get", $help_cmd_get], ["drop", $help_cmd_drop]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["give|put <thing> to|in <thing>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command allows you to transfer an object between your ", <$format, ["link", [["node", "$help_cmd_inventory"]], ["inventory"], 'do_link]>, " and another object, or between one object and another. In the case of users, you can not transfer one user to another, only objects can be transfered into a user.", <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_get"]], ["get"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_drop"]], ["drop"], 'do_link]>], #[['links, #[["inventory", "$help_cmd_inventory"], ["get", "$help_cmd_get"], ["drop", "$help_cmd_drop"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_give];


new object $help_cmd_walk: $help_cmds;

var $root manager = $help_cmd_walk;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 877822538;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "walk|go", "walk|go"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["walk|go <direction>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This is a basic movement command which is rarely used due to exits having builtin shortcuts which effectively call this command when you enter the exit's name."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_walk];


new object $help_cmd_name_templates: $help_cmds;

var $root manager = $help_cmd_name_templates;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 878186751;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@name-templates|@templates", "@name-templates|@templates"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_name_templates];


new object $help_cmd_registered: $help_cmds;

var $root manager = $help_cmd_registered;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 878186815;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@registered", "@registered"];
var $help_node links = #[["@register|@unregister", $help_cmd_register_name]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@registered"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Shows all names currently registered by your character. ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@registered\nRegistered names: Vamp and Vampire.\n"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_register_name"]], ["@register|@unregister"], 'do_link]>, "."], #[['links, #[["@register|@unregister", "$help_cmd_register_name"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_registered];


new object $help_cmd_register_name: $help_cmds;

var $root manager = $help_cmd_register_name;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 878186871;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@register|@unregister|@register-name|@unregister-name", "@register|@unregister|@register-name|@unregister-name"];
var $help_node links = #[["@registered", $help_cmd_registered]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [["nobound", 1]], ["Syntax: ", <$format, ["tt", [], ["@register <name>"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@unregister <name>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "@register adds a name to the registation database that can optioally identify your character. @unregister removes a name from the database. ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@register HelpGod\nRegistered alternate name \"HelpGod\".\nRegistered names: Vamp and Vampire, HelpGod.\n"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Example:"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], [">@unregister HelpGod\nUnregistered alternate name \"HelpGod\".\nRegistered names: Vamp and Vampire.\n"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_registered"]], ["@registered"], 'do_link]>, "."], #[['links, #[["@registered", "$help_cmd_registered"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_register_name];


new object $help_cmd_channel_acm: $help_cmds;

var $root manager = $help_cmd_channel_acm;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 878187174;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@add-channel-manager|@acm", "@add-channel-manager|@acm"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_channel_acm];


new object $help_cmd_channel_dcm: $help_cmds;

var $root manager = $help_cmd_channel_dcm;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 878187203;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@del-channel-manager|@dcm", "@del-channel-manager|@dcm"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_channel_dcm];


new object $help_cmd_channel_desc: $help_cmds;

var $root manager = $help_cmd_channel_desc;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 878187228;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@desc-channel", "@desc-channel"];
var $help_node links = #[["@channel", $help_cmd_channels]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@desc-c?hannel <channel> as <description>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command sets a <channel>'s title that can be seen with ", <$format, ["link", [["node", "$help_cmd_channels"]], ["@channel"], 'do_link]>, ". The channels description should be something informative, so that users will know what it is for, such as the principle topic of the channel."], #[['links, #[["@channel", "$help_cmd_channels"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_channel_desc];


new object $help_cmd_channel_join_lock: $help_cmds;

var $root manager = $help_cmd_channel_join_lock;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 878187263;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@join-lock-channel|@jlc", "@join-lock-channel|@jlc"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_channel_join_lock];


new object $help_cmd_channel_leave_lock: $help_cmds;

var $root manager = $help_cmd_channel_leave_lock;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 878187289;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@leave-lock-channel|@llc", "@leave-lock-channel|@llc"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_channel_leave_lock];


new object $help_cmd_channel_use_lock: $help_cmds;

var $root manager = $help_cmd_channel_use_lock;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 878187316;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@use-lock-channel|@ulc", "@use-lock-channel|@ulc"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_channel_use_lock];


new object $help_cmd_channel_purge: $help_cmds;

var $root manager = $help_cmd_channel_purge;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 878187342;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@purge-channel", "@purge-channel"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@purge-channel <channel>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Removes a channel from the world, but only if you are the channel manager.", <$format, ["p", [], [], 'do_p]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_channel_purge];


new object $help_cmd_channel_add: $help_cmds;

var $root manager = $help_cmd_channel_add;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 878187456;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@add-channel|@addcom", "@add-channel|@addcom"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_channel_add];


new object $help_cmd_channels: $help_cmds;

var $root manager = $help_cmd_channels;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 878187484;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@channels", "@channels"];
var $help_node links = #[["title", $help_cmd_channel_desc], ["channel manager", $help_cmd_channel_acm]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@channel?s [+f?ull +d?etailed]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Without either of the two options, this command displays the channels that you are currently listening too. The +full option displays all the channels available; the +detailed option displays information regarding each of the channels, such as the ", <$format, ["link", [["node", "$help_cmd_channel_desc"]], ["title"], 'do_link]>, ", number of current listeners, the channel owner, and the ", <$format, ["link", [["node", "$help_cmd_channel_acm"]], ["channel manager"], 'do_link]>, "."], #[['links, #[["title", "$help_cmd_channel_desc"], ["channel manager", "$help_cmd_channel_acm"]]]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_channels];


new object $help_cmd_kick: $help_cmds;

var $root manager = $help_cmd_kick;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 878512086;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@kick", "@kick"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@kick <user>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This command destroys all of a user's current login connections, effectively disconnecting them from the server."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_kick];


new object $help_cmd_quota: $help_cmds;

var $root manager = $help_cmd_quota;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 887772510;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "@quota", "@quota"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@quota <object> to <any:+e?xempt>"], 'do_tt]>, <$format, ["p", [], [], 'do_p]>, "This command sets an objects quota to either a numeric amount or exempt or non-exempt."], #[]]>;
var $root inited = 1;
var $root managed = [$help_cmd_quota];


new object $help_obj: $help_core;

var $root manager = $help_obj;
var $root flags = ['variables, 'methods, 'code, 'fertile, 'core];
var $root created_on = 864416191;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Objects", "Objects"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[]]>;
var $root inited = 1;
var $help_node group = 1;
var $help_node holder = 1;
var $help_node nolist = 0;
var $root managed = [$help_obj];


new object $help_cml_colors: $help_obj;

var $root manager = $help_cml_colors;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 864416453;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Colors", "Colors"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "CML Color provides services to enable color on user clients supporting HTML or ANSI.", <$format, ["p", [], [], 'do_p]>, <$format, ["subj", [["level", "2"]], [<$format, ["font", [["color", "cyan"]], ["Usage"], 'do_font]>], 'do_subj]>, " ", <$format, ["font", [["color", "green"]], [<$format, ["dfn", [], ["{font color=<color> bcolor=<color>:Text to display in color.}"], 'do_dfn]>], 'do_font]>, <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["font", [["color", "blue"]], [<$format, ["quote", [], ["color:"], 'do_quote]>], 'do_font]>], 'do_dt]>, <$format, ["dd", [], [<$format, ["font", [["color", "yellow"]], ["Defines the forground color of the text. It must be of a valid type listed in $cml_color,colors."], 'do_font]>], 'do_dd]>, <$format, ["dt", [], [<$format, ["font", [["color", "blue"]], [<$format, ["quote", [], ["bcolor:"], 'do_quote]>], 'do_font]>], 'do_dt]>, <$format, ["dd", [], [<$format, ["font", [["color", "yellow"]], ["Defines the background color, and is not supported in html."], 'do_font]>], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, <$format, ["font", [["color", "green"]], ["color and bcolor are optional, though using neither will have no affect on your text. The following examples are all valid."], 'do_font]>, " ", <$format, ["subj", [["level", "3"]], [<$format, ["font", [["color", "cyan"]], ["Examples:"], 'do_font]>], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], ["{font color=red bcolor=blue:Hello world!}"], 'do_dt]>, <$format, ["dd", [], [<$format, ["font", [["color", "red"], ["bcolor", "blue"]], ["Hello world!"], 'do_font]>], 'do_dd]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dt", [], ["{font color=red:Hello world!}"], 'do_dt]>, <$format, ["dd", [], [<$format, ["font", [["color", "red"]], ["Hello world!"], 'do_font]>], 'do_dd]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dt", [], ["{font bcolor=blue:Hello world!}"], 'do_dt]>, <$format, ["dd", [], [<$format, ["font", [["bcolor", "blue"]], ["Hello world!"], 'do_font]>], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $help_node group = 1;
var $root managed = [$help_cml_colors];


new object $help_obj_trie: $help_obj;

var $root manager = $help_obj_trie;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 838774726;
var $has_name name = ['prop, "Trie", "Trie"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Trie is a datastructure that behaves like dictionary with string keys, except that it allows fast match_begin with all the keys. Also, key may be associated with a value list instead of a single value. Its memory overhead is about twice that of a dictionary, and all the operations are slower, except match_begin (which, unlike the dictionary's, does not have to loop through all the keys). Empty trie is represented as ", <$format, ["tt", [], ["<$trie,[0,\"\"]>"], 'do_tt]>, ".", <$format, ["p", [], [], 'do_p]>, <$format, ["subj", [["level", "3"]], ["Methods"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["trie.add", 1]], ["add"], 'do_method]>, "(", <$format, ["var", [], ["key"], 'do_var]>, ", ", <$format, ["var", [], ["value"], 'do_var]>, "[,", <$format, ["var", [], ["value"], 'do_var]>, "...])"], 'do_dt]>, <$format, ["dd", [], ["Associate a list of values with a key."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["trie.del", 1]], ["del"], 'do_method]>, "(", <$format, ["var", [], ["key"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Remove the key from trie."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["trie.match_exact", 1]], ["match_exact"], 'do_method]>, "(", <$format, ["var", [], ["key"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Find an exact match to the key."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["trie.match_begin", 1]], ["match_begin"], 'do_method]>, "(", <$format, ["var", [], ["key"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Find an approximate match."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["trie.keys", 1]], ["keys"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Get a list of the keys. This is very slow operation."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["trie.to_dict", 1]], ["to_dict"], 'do_method]>, "(), $dictionary.", <$format, ["method", [["dictionary.to_trie", 1]], ["to_trie"], 'do_method]>, "(", <$format, ["var", [], ["dict"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Conversions. The first one converts a trie with a single-element values into dictionary, reverse converts a dictionary with string keys to trie."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_obj_trie];
var $help_node index = $help_index_objects;
var $help_node nolist = 0;
var $help_node group = 1;


new object $help_obj_list: $help_obj;

var $root manager = $help_obj_list;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837714742;
var $has_name name = ['prop, "List Library", "List Library"];
var $help_node links = #[["Elements", $help_list_element], ["Formatting", $help_list_formatting], ["Maps", $help_list_maps], ["Sets", $help_list_sets], ["Others", $help_list_other]];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["link", [["node", "$help_list_element"]], ["Elements"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Element operations"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_list_formatting"]], ["Formatting"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["List formatting"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_list_maps"]], ["Maps"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Mapping and filtering"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_list_sets"]], ["Sets"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Set operations"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_list_other"]], ["Others"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Others"], 'do_dd]>], 'do_dl]>], #[['this, $help_obj_list]]]>;
var $root inited = 1;
var $root managed = [$help_obj_list];
var $help_node index = $help_index_objects;
var $help_node nolist = 0;
var $help_node group = 1;


new object $help_list_element: $help_obj_list;

var $root manager = $help_list_element;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850833025;
var $has_name name = ['prop, "Element", "Element"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["list.length", 1]], ["length"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Length of the ", <$format, ["var", [], ["list"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.replace", 1]], ["replace"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["n"], 'do_var]>, ", ", <$format, ["var", [], ["elt"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Replaces ", <$format, ["var", [], ["n"], 'do_var]>, "th element with ", <$format, ["var", [], ["elt"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.delete", 1]], ["delete"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["n"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Deletes ", <$format, ["var", [], ["n"], 'do_var]>, "th element from the list."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.insert", 1]], ["insert"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["n"], 'do_var]>, ", ", <$format, ["var", [], ["elt"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Inserts ", <$format, ["var", [], ["elt"], 'do_var]>, " at the ", <$format, ["var", [], ["n"], 'do_var]>, "th place of the list."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.subrange", 1]], ["subrange"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["n"], 'do_var]>, ", ", <$format, ["var", [], ["len"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Returns sublist starting at ", <$format, ["var", [], ["l"], 'do_var]>, ", with ", <$format, ["var", [], ["len"], 'do_var]>, " elements."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.last", 1]], ["last"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Returns last element of the list."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.sort", 1]], ["sort"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, "[, ", <$format, ["var", [], ["keys"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Sorts the list by the keys list. Keys default to the list itself."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.chop", 1]], ["chop"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, "[, ", <$format, ["var", [], ["count"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Removes count elements from the tail of the list. Default is 1 element."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.swap", 1]], ["swap"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["index1"], 'do_var]>, ", ", <$format, ["var", [], ["index2"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Swaps the two elements of the list."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $help_node nolist = 0;
var $root managed = [$help_list_element];


new object $help_list_formatting: $help_obj_list;

var $root manager = $help_list_formatting;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850833050;
var $has_name name = ['prop, "Formatting", "Formatting"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["list.join", 1]], ["join"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, "[, ", <$format, ["var", [], ["separator"], 'do_var]>, "]) ", <$format, ["var", [], ["native"], 'do_var]>], 'do_dt]>, <$format, ["dd", [], ["Format the ", <$format, ["var", [], ["list"], 'do_var]>, " by converting its elements to strings, and putting ", <$format, ["var", [], ["separator"], 'do_var]>, " between them."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.to_english", 1]], ["to_english"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, "[, ", <$format, ["var", [], ["empty"], 'do_var]>, "[, ", <$format, ["var", [], ["and"], 'do_var]>, "[, ", <$format, ["var", [], ["sep"], 'do_var]>, "]]])"], 'do_dt]>, <$format, ["dd", [], ["Convert the elements of the ", <$format, ["var", [], ["list"], 'do_var]>, " to strings, put ", <$format, ["var", [], ["separator"], 'do_var]>, " between them, except the last two elements, that will be separated with ", <$format, ["var", [], ["and"], 'do_var]>, ". Defaults for the arguments are: ", <$format, ["var", [], ["empty"], 'do_var]>, " = 'nothing', ", <$format, ["var", [], ["and"], 'do_var]>, " = ' and ', ", <$format, ["var", [], ["sep"], 'do_var]>, " = ', '."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.columnize", 1]], ["columnize"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["cols"], 'do_var]>, "[, ", <$format, ["var", [], ["separator"], 'do_var]>, "[, ", <$format, ["var", [], ["linelength"], 'do_var]>, "]])"], 'do_dt]>, <$format, ["dd", [], ["Format the line in ", <$format, ["var", [], ["cols"], 'do_var]>, " columns, adding the ", <$format, ["var", [], ["separators"], 'do_var]>, ". ", <$format, ["var", [], ["Linelength"], 'do_var]>, " defaults to 78."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.lcolumnize", 1]], ["lcolumnize"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, "[, ", <$format, ["var", [], ["len"], 'do_var]>, "[, ", <$format, ["var", [], ["sep"], 'do_var]>, "]])"], 'do_dt]>, <$format, ["dd", [], ["Columnizes by detecting the maximal length of the list elements."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.vcolumnize", 1]], ["vcolumnize"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["cols"], 'do_var]>, "[, ", <$format, ["var", [], ["linelen"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Columnizes in the stanard manner (consecutive elements are aligned vertically)."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.center_lines", 1]], ["center_lines"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["width"], 'do_var]>, "[, ", <$format, ["var", [], ["args"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Calls ", <$format, ["method", [["string.center", 1]], ["$string.center"], 'do_method]>, " on each line in the ", <$format, ["var", [], ["list"], 'do_var]>, ", with extra ", <$format, ["var", [], ["args"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.prefix", 1]], ["prefix"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["prefix"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Prepends a ", <$format, ["var", [], ["prefix"], 'do_var]>, " to each element of the ", <$format, ["var", [], ["list"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.affix", 1]], ["affix"], 'do_method]>, "(", <$format, ["var", [], ["l1"], 'do_var]>, ", ", <$format, ["var", [], ["l2"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Appends ", <$format, ["var", [], ["l2"], 'do_var]>, " to ", <$format, ["var", [], ["l1"], 'do_var]>, ", with adding the first element of ", <$format, ["var", [], ["l2"], 'do_var]>, " to the last element of ", <$format, ["var", [], ["l1"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.tabulate", 1]], ["tabulate"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["headers"], 'do_var]>, "[, ", <$format, ["var", [], ["colsizes"], 'do_var]>, ", ", <$format, ["var", [], ["trim_cols"], 'do_var]>, ", ", <$format, ["var", [], ["header_sep"], 'do_var]>, ", ", <$format, ["var", [], ["len"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Output the ", <$format, ["var", [], ["list"], 'do_var]>, " as a table, with given ", <$format, ["var", [], ["headers"], 'do_var]>, ". ", <$format, ["var", [], ["Colsizes"], 'do_var]>, ", if 0, are automatically calculated."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $help_node nolist = 0;
var $root managed = [$help_list_formatting];


new object $help_list_maps: $help_obj_list;

var $root manager = $help_list_maps;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850833055;
var $has_name name = ['prop, "Maps", "Maps"];
var $help_node links = #[["sender", $help_func_sender]];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["list.make", 1]], ["make"], 'do_method]>, "(", <$format, ["var", [], ["n"], 'do_var]>, "[,", <$format, ["var", [], ["elt"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Makes a list of ", <$format, ["var", [], ["n"], 'do_var]>, " copies of ", <$format, ["var", [], ["elt"], 'do_var]>, ". ", <$format, ["var", [], ["Elt"], 'do_var]>, " defaults to 0."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.mmap", 1]], ["mmap"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["method"], 'do_var]>, ", ", <$format, ["var", [], ["args"], 'do_var]>, "...)"], 'do_dt]>, <$format, ["dd", [], ["Calls ", <$format, ["var", [], ["method"], 'do_var]>, " on each element (with additional arguments, if specified), returns the results."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.mfilter", 1]], ["mfilter"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["method"], 'do_var]>, ", ", <$format, ["var", [], ["args"], 'do_var]>, "...)"], 'do_dt]>, <$format, ["dd", [], ["Similar to .", <$format, ["method", [["list.mmap", 1]], ["mmap"], 'do_method]>, "(), but returns the list of objects for which ", <$format, ["var", [], ["method"], 'do_var]>, " returned a true value."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.lmap", 1]], ["lmap"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["method"], 'do_var]>, ", ", <$format, ["var", [], ["args"], 'do_var]>, "...)"], 'do_dt]>, <$format, ["dd", [], ["Calls ", <$format, ["link", [["node", "$help_func_sender"]], ["sender"], 'do_link]>, "().", <$format, ["var", [], ["method"], 'do_var]>, " on each element of the list, returns the results."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.omap", 1]], ["omap"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["object"], 'do_var]>, ", ", <$format, ["var", [], ["method"], 'do_var]>, ", ", <$format, ["var", [], ["args"], 'do_var]>, "...)"], 'do_dt]>, <$format, ["dd", [], ["Calls ", <$format, ["var", [], ["object"], 'do_var]>, ".", <$format, ["var", [], ["method"], 'do_var]>, " on each element."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.map_to_english", 1]], ["map_to_english"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["method"], 'do_var]>, ", ", <$format, ["var", [], ["args"], 'do_var]>, "...)"], 'do_dt]>, <$format, ["dt", [], [".", <$format, ["method", [["list.map_to_string", 1]], ["map_to_string"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["method"], 'do_var]>, ", ", <$format, ["var", [], ["args"], 'do_var]>, "...)"], 'do_dt]>, <$format, ["dd", [], ["Shorthand for .", <$format, ["method", [["list.mmap", 1]], ["mmap"], 'do_method]>, "() followed with .", <$format, ["method", [["list.to_english", 1]], ["to_english"], 'do_method]>, "()/.", <$format, ["method", [["list.to_string", 1]], ["to_string"], 'do_method]>, "()."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.element_maxlength", 1]], ["element_maxlength"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Finds the longest element (measuring by string representation)."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.nth_element_maxlength", 1]], ["nth_element_maxlength"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["n"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Same as list.", <$format, ["method", [["list.slice", 1]], ["slice"], 'do_method]>, "(", <$format, ["var", [], ["n"], 'do_var]>, ").", <$format, ["method", [["list.element_maxlength", 1]], ["element_maxlength"], 'do_method]>, "()."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.reverse", 1]], ["reverse"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Reverse the order of the elements of the ", <$format, ["var", [], ["list"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.compress", 1]], ["compress"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Removes the repeated elements."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.slice", 1]], ["slice"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["n"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Returns the list of ", <$format, ["var", [], ["n"], 'do_var]>, "th elements from a list of lists. If ", <$format, ["var", [], ["n"], 'do_var]>, " is a list, it will return a list of lists."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.numbered_text", 1]], ["numbered_text"], 'do_method]>, "(", <$format, ["var", [], ["text"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Returns the ", <$format, ["var", [], ["text"], 'do_var]>, " with line numbers prepended."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.max", 1]], ["max"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dt", [], [".", <$format, ["method", [["list.min", 1]], ["min"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Returns minimal/maximal element of the ", <$format, ["var", [], ["list"], 'do_var]>, " (0 if empty)."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.fold", 1]], ["fold"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["object"], 'do_var]>, ", ", <$format, ["var", [], ["method"], 'do_var]>, ", ", <$format, ["var", [], ["args"], 'do_var]>, "...)"], 'do_dt]>, <$format, ["dd", [], ["Fold operation from functional programming. For an empty list, it returns 0, for a 1 element list, it returns the first element. Otherwise, it calls the ", <$format, ["var", [], ["method"], 'do_var]>, " for the first two elements, then calls it with the result and the third element, etc. It returns the last result."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.valid_objects", 1]], ["valid_objects"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Removes invalid objects from the ", <$format, ["var", [], ["list"], 'do_var]>], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.grep", 1]], ["grep"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ",", <$format, ["var", [], ["regexp"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["For each line that matches ", <$format, ["var", [], ["regexp"], 'do_var]>, ", returns [linenumber, regexp match regions, the line text]."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.count", 1]], ["count"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["elem"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Counts the number of occurences of element in the list."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.locate", 1]], ["locate"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["value"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Returns the list of indices into the list where the value of the element is equivalent to the value of ", <$format, ["var", [], ["value"], 'do_var]>, ". ", <$format, ["blockquote", [], ["[4, 2, 3, 4].locate(4) -> [1, 4]"], 'do_blockquote]>, " "], 'do_dd]>], 'do_dl]>], #[['links, #[["sender", "$help_func_sender"]]]]]>;
var $root inited = 1;
var $help_node nolist = 0;
var $root managed = [$help_list_maps];


new object $help_list_sets: $help_obj_list;

var $root manager = $help_list_sets;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850833059;
var $has_name name = ['prop, "Sets", "Sets"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [["ind", "8"]], [<$format, ["dt", [], [".", <$format, ["method", [["list.setadd", 1]], ["setadd"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["elt"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Adds an element to the list unless it's already contained in the list."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.setremove", 1]], ["setremove"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["elt"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Removes the first occurence of the element from the list."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.union", 1]], ["union"], 'do_method]>, "(", <$format, ["var", [], ["list1"], 'do_var]>, ",", <$format, ["var", [], ["list2"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Union of the two lists. Use ", <$format, ["method", [["list.fold", 1]], ["big_list.fold"], 'do_method]>, "($list,'union) to get a union of the family of lists."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.set_difference", 1]], ["set_difference"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ", ", <$format, ["var", [], ["l1"], 'do_var]>, ", ...)"], 'do_dt]>, <$format, ["dd", [], ["Removes the elements from ", <$format, ["var", [], ["l1"], 'do_var]>, ", ", <$format, ["var", [], ["l2"], 'do_var]>, " etc from the list."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.intersection", 1]], ["intersection"], 'do_method]>, "(", <$format, ["var", [], ["l1"], 'do_var]>, ", ", <$format, ["var", [], ["l2"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Returns the elements that occur on both lists. Use ", <$format, ["method", [["list.fold", 1]], ["$list.fold()"], 'do_method]>, " for more lists."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.set_contains", 1]], ["set_contains"], 'do_method]>, "(", <$format, ["var", [], ["l1"], 'do_var]>, ", ", <$format, ["var", [], ["l2"], 'do_var]>, ", ...)"], 'do_dt]>, <$format, ["dd", [], ["Returns 1 if the first argument contains all the others."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.set_equal", 1]], ["set_equal"], 'do_method]>, "(", <$format, ["var", [], ["l1"], 'do_var]>, ", ", <$format, ["var", [], ["l2"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Returns 1 if the lists are equal as sets (that is, if ", <$format, ["var", [], ["l1"], 'do_var]>, " is contained in ", <$format, ["var", [], ["l2"], 'do_var]>, " and if ", <$format, ["var", [], ["l2"], 'do_var]>, " is contained in l1)."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $help_node nolist = 0;
var $root managed = [$help_list_sets];


new object $help_list_other: $help_obj_list;

var $root manager = $help_list_other;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850833064;
var $has_name name = ['prop, "Other", "Other"];
var $help_node links = #[["buffer", $help_coldc_types_buffers], ["dictionaries", $help_coldc_types_dicts]];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["list.flatten", 1]], ["flatten"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Raise all the sublists to the toplevel."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.sum", 1]], ["sum"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Returns the sum of the elements of the list."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.non_alphanumeric", 1]], ["non_alphanumeric"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dt", [], [".", <$format, ["method", [["list.numbers", 1]], ["numbers"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dt", [], [".", <$format, ["method", [["list.alphabet", 1]], ["alphabet"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns the lists of characters in each class."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.to_buffer", 1]], ["to_buffer"], 'do_method]>, "([", <$format, ["var", [], ["args"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Turns a list of strings into ", <$format, ["link", [["node", "$help_coldc_types_buffers"]], ["buffer"], 'do_link]>, ", inserting a newlist (by default) as a separator."], 'do_dd]>], 'do_dl]>, <$format, ["subj", [["level", "3"]], ["Associative lists"], 'do_subj]>, "Associative lists are lists of key/value pairs. Use them only when dealing with very few elements (fewer than 5, for instance). For larger databases, memory advantage of the associative lists ceases to matter, and they are much slower than ", <$format, ["link", [["node", "$help_coldc_types_dicts"]], ["dictionaries"], 'do_link]>, ".", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["list.addkey", 1]], ["addkey"], 'do_method]>, "(", <$format, ["var", [], ["l"], 'do_var]>, ", ", <$format, ["var", [], ["key"], 'do_var]>, ", ", <$format, ["var", [], ["val"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Adds a key/value pair to the list, or modifies the value associated with existing key."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.delkey", 1]], ["delkey"], 'do_method]>, "(", <$format, ["var", [], ["l"], 'do_var]>, ", ", <$format, ["var", [], ["key"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Removes the key/value pair if exists."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.getkey", 1]], ["getkey"], 'do_method]>, "(", <$format, ["var", [], ["l"], 'do_var]>, ", ", <$format, ["var", [], ["key"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Returns the value associated with the key, or throws ~keynf."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["list.getkey_index", 1]], ["getkey_index"], 'do_method]>, "(", <$format, ["var", [], ["l"], 'do_var]>, ", ", <$format, ["var", [], ["key"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Returns the index if the key, or throws."], 'do_dd]>], 'do_dl]>], #[['links, #[["buffer", "$help_coldc_types_buffers"], ["dictionaries", "$help_coldc_types_dicts"]]]]]>;
var $root inited = 1;
var $help_node nolist = 0;
var $root managed = [$help_list_other];


new object $help_obj_has_text: $help_obj;

var $root manager = $help_obj_has_text;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 864411446;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "has_text", "has_text"];
var $help_node links = #[["Methods", $help_obj_has_text_methods]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "$has_text provides general services for handling text and is largely used in $note and $mail_message.", <$format, ["p", [], [], 'do_p]>, <$format, ["subj", [["level", "3"]], ["Settings"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["quote", [], ["plaintext"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Is either yes or no. Yes indicates that the text is plaintext and no processing need be done. No indicates that the text is CML and needs to be handled as such."], 'do_dd]>], 'do_dl]>, <$format, ["subj", [["level", "3"]], [<$format, ["link", [["node", "$help_obj_has_text_methods"]], ["Methods"], 'do_link]>], 'do_subj]>, " ", <$format, ["subj", [["level", "3"]], ["Variables"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["quote", [], ["text"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Stores the text in either plaintext or the internal representation of CML depending on the setting \"plaintext\"."], 'do_dd]>], 'do_dl]>], #[['links, #[["Methods", "$help_obj_has_text_methods"]]]]]>;
var $root inited = 1;
var $help_node group = 1;
var $root managed = [$help_obj_has_text];


new object $help_obj_has_text_methods: $help_obj_has_text;

var $root manager = $help_obj_has_text_methods;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 864416982;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Methods", "Methods"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["subj", [["level", "3"]], ["Methods"], 'do_subj]>, " ", <$format, ["subj", [["level", "4"]], ["Accessors"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["has_text.text", 1]], ["text"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns the text in the format it is stored in, either plaintext or the frob representation of CML."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["has_text.get_raw_text", 1]], ["get_raw_text"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns the raw text to be edited. For plaintext, this is the text, while for CML, this will be the decompiled CML in it's raw form."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["has_text.lines", 1]], ["lines"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns a number identifying how many lines of text there are. Note that with CML, this is not accurate for the formatted output but rather for the uncompiled CML text."], 'do_dd]>], 'do_dl]>, <$format, ["subj", [["level", "4"]], ["Mutators"], 'do_subj]>, " ", <$format, ["dt", [], [".", <$format, ["method", [["has_text.set_text", 1]], ["set_text"], 'do_method]>, "(", <$format, ["var", [], ["txt"], 'do_var]>, ")"], 'do_dt]>, " ", <$format, ["dd", [], ["Accepts either a single line of text or a list of lines as input. If the text is set to not be plaintext, it will compile the text with the CML compiler."], 'do_dd]>, " ", <$format, ["dt", [], [".", <$format, ["method", [["has_text.ins_line", 1]], ["ins_line"], 'do_method]>, "(", <$format, ["var", [], ["txt"], 'do_var]>, ", [", <$format, ["var", [], ["loc"], 'do_var]>, "])"], 'do_dt]>, " ", <$format, ["dd", [], ["Accepts a line of text and an optional location (given by line number) for where to put it. If the location is not specified, it defaults to adding the line of text at the end."], 'do_dd]>, " ", <$format, ["dt", [], [".", <$format, ["method", [["has_text.del_text", 1]], ["del_text"], 'do_method]>, "()"], 'do_dt]>, " ", <$format, ["dd", [], ["Clears the text."], 'do_dd]>, " ", <$format, ["dt", [], [".", <$format, ["method", [["has_text.del_line", 1]], ["del_line"], 'do_method]>, "(", <$format, ["var", [], ["linestr"], 'do_var]>, ")"], 'do_dt]>, " ", <$format, ["dd", [], ["Removes the first instance of the string (must be a complete line) given as the argument from the text."], 'do_dd]>, " ", <$format, ["dt", [], [".", <$format, ["method", [["has_text.del_nline", 1]], ["del_nline"], 'do_method]>, "(", <$format, ["var", [], ["nline"], 'do_var]>, ")"], 'do_dt]>, " ", <$format, ["dd", [], ["Removes the line specified by the line number given as the argument from the text."], 'do_dd]>, " ", <$format, ["dt", [], [".", <$format, ["method", [["has_text.ins_lines", 1]], ["ins_lines"], 'do_method]>, "(", <$format, ["var", [], ["lines"], 'do_var]>, ", ", <$format, ["var", [], ["loc"], 'do_var]>, ")"], 'do_dt]>, " ", <$format, ["dd", [], ["Inserts the list of strings at the specified location."], 'do_dd]>, "}"], #[]]>;
var $root inited = 1;
var $root managed = [$help_obj_has_text_methods];


new object $help_mutex: $help_obj;

var $root manager = $help_mutex;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858089990;
var $root managed = [$help_mutex];
var $has_name name = ['prop, "Mutex", "Mutex"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Mutex is 'Mutual Exclusion'. Its purpose is preventing concurrent tasks from interfering with each other. A task grabbing mutex lock will suspend until all other tasks release the incompatible locks. Each lock has class and list of values. Two locks are ", <$format, ["i", [], ["incompatible"], 'do_i]>, " if:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], ["Their class have common descendant (classes themselves are considered descendants for the purpose of this definition)"], 'do_li]>, <$format, ["li", [], ["Their values have common elements."], 'do_li]>], 'do_ul]>, <$format, ["np", [], [], 'do_np]>, "Primary mutex class is $mutex (note that grabbing $mutex will cause all attempts to grab locks with similar values to suspend). Its descendants allow programmer to set up finer locks, which allow multiple tasks to deal with nondisjoint value lists concurrently. ", <$format, ["np", [], [], 'do_np]>, "$mutex has the following functions:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], [".grab(@values)"], 'do_dt]>, <$format, ["dd", [], ["Grab the list of values on the called class."], 'do_dd]>, <$format, ["dt", [], [".release(@values)"], 'do_dt]>, <$format, ["dd", [], ["Release the list from the class."], 'do_dd]>, <$format, ["dt", [], [".release_all()"], 'do_dt]>, <$format, ["dd", [], ["Release all the locks held by the current class. Use this call from connection objects and such."], 'do_dd]>, <$format, ["dt", [], [".cleanup_dead_tasks()"], 'do_dt]>, <$format, ["dd", [], ["Remove the dead tasks from this class."], 'do_dd]>], 'do_dl]>], #[['this, $help_mutex]]]>;
var $root inited = 1;
var $help_node nolist = 0;
var $help_node group = 1;


new object $help_heap: $help_obj;

var $root manager = $help_heap;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858400875;
var $has_name name = ['prop, "Heap", "Heap"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The heap is an efficient implementation of the priority queue. It is currently used by $scheduler and $graph. When you use it only in assignment calls (", <$format, ["tt", [], ["list = $heap.method(args)"], 'do_tt]>, ", in other words), it will operate in the logarithmic time (very fast).", <$format, ["p", [], [], 'do_p]>, "Heap is a list with the property that ", <$format, ["i", [], ["i"], 'do_i]>, "-th element of the list has lower priority than either ", <$format, ["i", [], ["2*i"], 'do_i]>, "-th and ", <$format, ["i", [], ["2*i+1"], 'do_i]>, "-st element of the list. Obviously, the first element of the list will have the lowest priority.", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["tt", [], ["$heap.push(heap, element, priority_index)"], 'do_tt]>], 'do_dt]>, <$format, ["dd", [], ["Add a new element to the heap. In this implementation, heap is assumed to be list of lists, with priority_index determining the priority field of each element."], 'do_dd]>, <$format, ["dt", [], [<$format, ["tt", [], ["$heap.del(heap, index, priority_index)"], 'do_tt]>], 'do_dt]>, <$format, ["dd", [], ["Delete an element at index ", <$format, ["i", [], ["i"], 'do_i]>, " of the heap. if index is greater than length of the heap, the method will throw."], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "Both methods assume that their first argument already is a heap."], #[]]>;
var $root inited = 1;
var $root managed = [$help_heap];
var $help_node group = 1;


new object $help_weather_system: $help_obj;

var $root manager = $help_weather_system;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856455167;
var $root managed = [$help_weather_system];
var $has_name name = ['prop, "Weather System", "Weather System"];
var $help_node links = #[["$realm", $help_places_realms], ["$climate", $help_sys_climate], ["$weather", $help_sys_weather], ["$weather_attributes", $help_sys_weather_attributes]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdCore uses elaborate weather system, allowing the administrators to set realistic weathers and climates. The system is based on several objects, each keeping track of a facet of the weather: ", <$format, ["dfn", [["ind", "4"], ["nobound", 1]], [<$format, ["table", [["cols", "30%,70%"]], [<$format, ["tr", [], [<$format, ["td", [], ["$world"], 'do_td]>, <$format, ["td", [], ["$world keeps the weather cycle, and calls the updates on realms."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_places_realms"]], ["$realm"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Children of $realm keep track of the current weather and season, as well as of VR timezones."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_sys_climate"]], ["$climate"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["$climate keeps the season names for each part of the year, and lists of weathers that may occur in that climate."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_sys_weather"]], ["$weather"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Weather objects contain weather descriptions, messages and attributes. Attributes are the most important, since they can be used to fork room descriptions to reflect conditions in the weather."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_sys_weather_attributes"]], ["$weather_attributes"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["This object is a database of all the available weather attributes."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When changing the weather, the system will pay attention to differences between weather attributes (so it'll be unlikely that a storm will start a moment after the sun shining), seasonal ratings, and inter-realm dependancies."], #[['links, #[["$realm", "$help_places_realms"], ["$climate", "$help_sys_climate"], ["$weather", "$help_sys_weather"], ["$weather_attributes", "$help_sys_weather_attributes"]]]]]>;
var $root trusted = [$help_node];
var $root inited = 1;
var $help_node nolist = 0;
var $help_node group = 1;


new object $help_sys_climate: $help_weather_system;

var $root manager = $help_sys_climate;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856455152;
var $root managed = [$help_sys_climate];
var $has_name name = ['prop, "Climate", "Climate"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["Instances of the climate object are used to define general weather patterns for an area. The following information is stored on each climate object:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], ["A list of season names."], 'do_li]>, <$format, ["li", [], ["A list of daylengths assigned to each season. Daylength is given as an offset, meaning that with +2, you have an early sunrise and late sunset. This number is interpreted by $world_time."], 'do_li]>, <$format, ["li", [], ["A list of weathers, each with probabilities for every season. Probabilities are not percentages, instead, only their ratios really matter."], 'do_li]>], 'do_ul]>, <$format, ["subj", [["level", "3"]], ["Climate commands"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], ["@setup <this> seasons <any> daylengths <any>"], 'do_dt]>, <$format, ["dd", [], ["Erases all the data on a climate object, sets a new season list and daylength lists. Both arguments are list of items separated by space; they must be of the same length."], 'do_dd]>, <$format, ["dt", [], ["@list-climate <this>"], 'do_dt]>, <$format, ["dd", [], ["Shows the information on climate."], 'do_dd]>, <$format, ["dt", [], ["@add-weather <this> type <descendant of $weather> prob?abilities <any>"], 'do_dt]>, <$format, ["dd", [], ["Adds a weather object to $climate; the object must be already built. Probabilities is a ' '-separated list of integers, one element for each season."], 'do_dd]>, <$format, ["dt", [], ["@del-weather <this> type <descendant of $weather>"], 'do_dt]>, <$format, ["dd", [], ["Removes weather from the climate."], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "No climate patterns should ever be defined on the base $climate object."], #[]]>;
var $root trusted = [$help_node];
var $root inited = 1;
var $help_node nolist = 0;


new object $help_sys_weather: $help_weather_system;

var $root manager = $help_sys_weather;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856455112;
var $root managed = [$help_sys_weather];
var $has_name name = ['prop, "Weather", "Weather"];
var $help_node links = #[["weather attributes", $help_sys_weather_attributes]];
var $help_node body = <$ctext_frob, [["Weather is a container for ", <$format, ["link", [["node", "$help_sys_weather_attributes"]], ["weather attributes"], 'do_link]>, ", description and invocation message. Make sure to follow these conventions when creating a weather object:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], ["name must be an adjective (example: nice, sunny, stormy)"], 'do_li]>, <$format, ["li", [], ["invoke message is printed each time $weather sets this weather to be current in a realm"], 'do_li]>, <$format, ["li", [], ["attributes *must* be set"], 'do_li]>], 'do_ul]>], #[['this, $help_sys_weather]]]>;
var $has_name templates = ["Generic Weather"];
var $root trusted = [$help_node];
var $root inited = 1;
var $help_node nolist = 0;


new object $help_sys_weather_attributes: $help_weather_system;

var $root manager = $help_sys_weather_attributes;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856455137;
var $root managed = [$help_sys_weather_attributes];
var $has_name name = ['prop, "Attributes", "Attributes"];
var $help_node links = #[["Generic Weather", $help_sys_weather]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Weather attributes are general characteristics a weather might have, such as humidity, precipitation, and so on. They can be used as generators in room descriptions, allowing builders to refer to 'rivulets of rain sliding down the ravine' only if it really is raining, or to say that 'it's terribly hot' only if it really is hot. ", <$format, ["np", [], [], 'do_np]>, "In addition, one can add more complex 'extra' attributes. These are not set on the weather, but are calculated from the existing attributes; for example, you can use them as cases in a switch for 'is it a hot, humid night?'. Note: you should not fiddle with this object too much after its attributes are set, because you will also need to reset each weather object. ", <$format, ["subj", [["level", "3"]], ["Weather attribute commands"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], ["@add-weather-attribute|awa <any> values <any> to <this>"], 'do_dt]>, <$format, ["dd", [], ["Adds a new weather attribute. Values is a list of descripting values separated by ';'. For example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@awa precipitation values none;rain;heavy rain;snow to $weather_attributes"], 'do_dfn]>], 'do_dd]>, <$format, ["dt", [], ["@add-extra-attribute|@aea <any> values <any> to <this>"], 'do_dt]>, <$format, ["dd", [], ["Adds extra attribute. Unlike normal attribs, these don't need to be set on the weather objects."], 'do_dd]>, <$format, ["dt", [], ["@del-weather-attribute|dwa <any> from <this>"], 'do_dt]>, <$format, ["dd", [], ["Removes a weather attribute."], 'do_dd]>, <$format, ["dt", [], ["@list-weather-attributes|lwa <this>"], 'do_dt]>, <$format, ["dd", [], ["Lists the current setup."], 'do_dd]>], 'do_dl]>, <$format, ["subj", [["level", "3"]], ["Default attributes"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "These attributes are set in the coldcore as-is. Modify them only if you are prepared to use @set weather:attributes on all descendants of ", <$format, ["link", [["node", "$help_sys_weather"]], ["Generic Weather"], 'do_link]>, ". ", <$format, ["dfn", [["nobound", 1]], [<$format, ["table", [["cols", "30%,70%"]], [<$format, ["tr", [], [<$format, ["td", [], ["precipitation"], 'do_td]>, <$format, ["td", [], ["fine;drizzle;rain;shower;snow"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["humidity"], 'do_td]>, <$format, ["td", [], ["dry;fine;humid"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["temperature"], 'do_td]>, <$format, ["td", [], ["hot;warm;cold;freezing"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["visibility"], 'do_td]>, <$format, ["td", [], ["clear;hazy;murky"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["wind"], 'do_td]>, <$format, ["td", [], ["serene;windy;stormy"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["clouds"], 'do_td]>, <$format, ["td", [], ["clear;cloudy;overcast"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["Generic Weather", "$help_sys_weather"]]]]]>;
var $has_name templates = ["Weather Attributes"];
var $root trusted = [$help_node];
var $root inited = 1;
var $help_node nolist = 0;


new object $help_obj_math: $help_obj;

var $root manager = $help_obj_math;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 869046674;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Math Library", "Math Library"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["subj", [["level", "3"]], ["Vector operations"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["math.add", 1]], ["add"], 'do_method]>, "(", <$format, ["var", [], ["v1"], 'do_var]>, ",", <$format, ["var", [], ["v2"], 'do_var]>, ") native"], 'do_dt]>, <$format, ["dd", [], ["Vector addition. It adds two floating-point lists, element-by-element."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.sub", 1]], ["sub"], 'do_method]>, "(", <$format, ["var", [], ["v1"], 'do_var]>, ",", <$format, ["var", [], ["v2"], 'do_var]>, ") native"], 'do_dt]>, <$format, ["dd", [], ["Vector substraction."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.dot", 1]], ["dot"], 'do_method]>, "(", <$format, ["var", [], ["v1"], 'do_var]>, ",", <$format, ["var", [], ["v2"], 'do_var]>, ") native"], 'do_dt]>, <$format, ["dd", [], ["Dot product of two vectors."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.cross", 1]], ["cross"], 'do_method]>, "(", <$format, ["var", [], ["v1"], 'do_var]>, ",", <$format, ["var", [], ["v2"], 'do_var]>, ") native"], 'do_dt]>, <$format, ["dd", [], ["Cross product of 3-dimensional vectors."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.distance", 1]], ["distance"], 'do_method]>, "(", <$format, ["var", [], ["v1"], 'do_var]>, ",", <$format, ["var", [], ["v2"], 'do_var]>, ") native"], 'do_dt]>, <$format, ["dd", [], ["Euclidean distance between the two vectors."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.scale", 1]], ["scale"], 'do_method]>, "(", <$format, ["var", [], ["x"], 'do_var]>, ",", <$format, ["var", [], ["v"], 'do_var]>, ") native"], 'do_dt]>, <$format, ["dd", [], ["Scales the vector ", <$format, ["var", [], ["v"], 'do_var]>, " by scalar ", <$format, ["var", [], ["x"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.minor", 1]], ["minor"], 'do_method]>, "(", <$format, ["var", [], ["v1"], 'do_var]>, ",", <$format, ["var", [], ["v2"], 'do_var]>, ") native"], 'do_dt]>, <$format, ["dd", [], ["Calculates element-by-element minimum of the two lists. Used for boxes."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.major", 1]], ["major"], 'do_method]>, "(", <$format, ["var", [], ["v1"], 'do_var]>, ",", <$format, ["var", [], ["v2"], 'do_var]>, ") native"], 'do_dt]>, <$format, ["dd", [], ["Calculates element-by-element maximum."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.is_lower", 1]], ["is_lower"], 'do_method]>, "(", <$format, ["var", [], ["v1"], 'do_var]>, ",", <$format, ["var", [], ["v2"], 'do_var]>, ") native"], 'do_dt]>, <$format, ["dd", [], ["Returns true if every element of ", <$format, ["var", [], ["v1"], 'do_var]>, " is lesser or equal than corresponding element of ", <$format, ["var", [], ["v2"], 'do_var]>, "."], 'do_dd]>], 'do_dl]>, <$format, ["subj", [["level", "3"]], ["Coordinate operations"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["math.pi", 1]], ["pi"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns pi."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.pi2", 1]], ["pi2"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns 2*pi."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.deg_rad", 1]], ["deg_rad"], 'do_method]>, "(", <$format, ["var", [], ["angle"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Converts the ", <$format, ["var", [], ["angle"], 'do_var]>, " from degrees to radians."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.rad_deg", 1]], ["rad_deg"], 'do_method]>, "(", <$format, ["var", [], ["angle"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Converts the ", <$format, ["var", [], ["angle"], 'do_var]>, " from radians to degrees."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.polar_rectangular", 1]], ["polar_rectangular"], 'do_method]>, "(", <$format, ["var", [], ["coords"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Transforms pair [distance, angle] into [x,y]."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.rectangular_polar", 1]], ["rectangular_polar"], 'do_method]>, "(", <$format, ["var", [], ["coords"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Inverse of the above."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.cylindrical_rectangular", 1]], ["cylindrical_rectangular"], 'do_method]>, "(", <$format, ["var", [], ["coords"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Transforms [r, angle, z] into [x,y,z]."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.rectangular_cylindrical", 1]], ["rectangular_cylindrical"], 'do_method]>, "(", <$format, ["var", [], ["coords"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Inverse of the above."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.spherical_rectangular", 1]], ["spherical_rectangular"], 'do_method]>, "(", <$format, ["var", [], ["coords"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Transform [r, phi, theta] into [x,y,z]."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.rectangular_spherical", 1]], ["rectangular_spherical"], 'do_method]>, "(", <$format, ["var", [], ["coords"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Inverse of the above."], 'do_dd]>], 'do_dl]>, <$format, ["subj", [["level", "3"]], ["Matrix operations"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["math.matrix_add", 1]], ["matrix_add"], 'do_method]>, "(", <$format, ["var", [], ["m1"], 'do_var]>, ",", <$format, ["var", [], ["m2"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Add two matrices."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.matrix_sub", 1]], ["matrix_sub"], 'do_method]>, "(", <$format, ["var", [], ["m1"], 'do_var]>, ",", <$format, ["var", [], ["m2"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Substract ", <$format, ["var", [], ["m2"], 'do_var]>, " from ", <$format, ["var", [], ["m1"], 'do_var]>], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.matrix_mul", 1]], ["matrix_mul"], 'do_method]>, "(", <$format, ["var", [], ["m1"], 'do_var]>, ",", <$format, ["var", [], ["m2"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Multiply the two matrices (their dimensions must be compatible for multiplication, of course)"], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.matrix_scale", 1]], ["matrix_scale"], 'do_method]>, "(", <$format, ["var", [], ["s"], 'do_var]>, ",", <$format, ["var", [], ["m"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Scale the matrix ", <$format, ["var", [], ["m"], 'do_var]>, " by scalar ", <$format, ["var", [], ["s"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.transpose", 1]], ["transpose"], 'do_method]>, "(", <$format, ["var", [], ["m"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Transpose the matrix. This will actually work regardless of the element type, so the operation is useful on lists, as well."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.ident_mat", 1]], ["ident_mat"], 'do_method]>, "(", <$format, ["var", [], ["n"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Returns ", <$format, ["var", [], ["n"], 'do_var]>, "-dimensional identity matrix."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.translation_mat", 1]], ["translation_mat"], 'do_method]>, "(", <$format, ["var", [], ["v"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Constructs the matrix for translation by vector ", <$format, ["var", [], ["v"], 'do_var]>, ". It works for 2d or 3d case."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.tensor", 1]], ["tensor"], 'do_method]>, "(", <$format, ["var", [], ["m1"], 'do_var]>, ",", <$format, ["var", [], ["m2"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Tensor product of the two vectors. This is the matrix ", <$format, ["var", [], ["A"], 'do_var]>, " with the property that Ax=<x,v1>v2."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.skew", 1]], ["skew"], 'do_method]>, "(", <$format, ["var", [], ["v"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Construct a skew operator for the vector ", <$format, ["var", [], ["v"], 'do_var]>, ". That's matrix ", <$format, ["var", [], ["A"], 'do_var]>, " that turns any vector into its cross product with ", <$format, ["var", [], ["v"], 'do_var]>, ". This is used by rotation_mat_3d."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.rotation_mat_2d", 1]], ["rotation_mat_2d"], 'do_method]>, "(", <$format, ["var", [], ["angle"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Construct 2d rotation matrix for the given ", <$format, ["var", [], ["angle"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.rotation_mat_3d", 1]], ["rotation_mat_3d"], 'do_method]>, "(", <$format, ["var", [], ["axis"], 'do_var]>, ",", <$format, ["var", [], ["angle"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This is 3d rotation. Valid values for ", <$format, ["var", [], ["axis"], 'do_var]>, " are 'x, 'y, 'z, or a 3d vector. The result is a homogenous matrix."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.scale_mat", 1]], ["scale_mat"], 'do_method]>, "(", <$format, ["var", [], ["scale"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Returns a scaling matrix (nonuniform). Scale is assumed to be 2d or 3d vector."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["math.transform_vect", 1]], ["transform_vect"], 'do_method]>, "(", <$format, ["var", [], ["m"], 'do_var]>, ",", <$format, ["var", [], ["v"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Transform the vector by matrix. This will work for both normal and homogenous matrices (determined by comparing the dimensions of the matrix and vector)."], 'do_dd]>], 'do_dl]>, <$format, ["subj", [["level", "3"]], ["Miscellanous"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["math.runge", 1]], ["runge"], 'do_method]>, "(", <$format, ["var", [], ["x"], 'do_var]>, ",", <$format, ["var", [], ["y"], 'do_var]>, ",", <$format, ["var", [], ["h"], 'do_var]>, ",", <$format, ["var", [], ["f"], 'do_var]>, ",", <$format, ["var", [], ["data"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This is one step in Runge-Kutta method for ordinary differential equations. Scalar ", <$format, ["var", [], ["x"], 'do_var]>, " and vector ", <$format, ["var", [], ["y"], 'do_var]>, " are the current values of independant and dependant variables, ", <$format, ["var", [], ["h"], 'do_var]>, " is the timestep, ", <$format, ["var", [], ["f"], 'do_var]>, " is the method on the sender that accepts ", <$format, ["var", [], ["x"], 'do_var]>, ", ", <$format, ["var", [], ["y"], 'do_var]>, ", and ", <$format, ["var", [], ["data"], 'do_var]>, ", and returns the right-hand-side of the equation."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $help_node group = 1;
var $root managed = [$help_obj_math];


new object $help_obj_integer: $help_obj;

var $root manager = $help_obj_integer;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870205331;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Integer", "Integer"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [["ind", "8"]], [<$format, ["dt", [], [".", <$format, ["method", [["integer.n_to_nth", 1]], ["n_to_nth"], 'do_method]>, "(", <$format, ["var", [], ["number"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given an integer, returns the numerical ordinal form. For example, given the integer '1', the method would return the string \"1st\"."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer.parse_range", 1]], ["parse_range"], 'do_method]>, "(", <$format, ["var", [], ["range"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given a string representing a range, returns a list of two elements representing the range in a parsed form."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer.to_english", 1]], ["to_english"], 'do_method]>, "(", <$format, ["var", [], ["number"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given a number, returns a string representation of that number that has had commas inserted according to the US standard."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer.parse_range", 1]], ["parse_range"], 'do_method]>, "(", <$format, ["var", [], ["x"], 'do_var]>, ", ", <$format, ["var", [], ["y"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given a lower and upper bound, returns a list of all numbers between them, including the bounds."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer.to_string", 1]], ["to_string"], 'do_method]>, "(", <$format, ["var", [], ["number"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given an integer, converts it to a string with no transformations performed upon it."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer._range_type", 1]], ["_range_type"], 'do_method]>, "(", <$format, ["var", [], ["type"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Helper method for .", <$format, ["method", [["integer.range", 1]], ["range"], 'do_method]>, "()."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer.and", 1]], ["and"], 'do_method]>, "(", <$format, ["var", [], ["x"], 'do_var]>, ", ", <$format, ["var", [], ["y"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Performs a bitwise ", <$format, ["i", [], ["and"], 'do_i]>, " operation upon ", <$format, ["i", [], ["x"], 'do_i]>, " and ", <$format, ["i", [], ["y"], 'do_i]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer.or", 1]], ["or"], 'do_method]>, "(", <$format, ["var", [], ["x"], 'do_var]>, ", ", <$format, ["var", [], ["y"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Performs a bitwise ", <$format, ["i", [], ["or"], 'do_i]>, " operation upon ", <$format, ["i", [], ["x"], 'do_i]>, " and ", <$format, ["i", [], ["y"], 'do_i]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer.xor", 1]], ["xor"], 'do_method]>, "(", <$format, ["var", [], ["x"], 'do_var]>, ", ", <$format, ["var", [], ["y"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Performs a bitwise ", <$format, ["i", [], ["xor"], 'do_i]>, " operation upon ", <$format, ["i", [], ["x"], 'do_i]>, " and ", <$format, ["i", [], ["y"], 'do_i]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer.shleft", 1]], ["shleft"], 'do_method]>, "(", <$format, ["var", [], ["x"], 'do_var]>, ", ", <$format, ["var", [], ["y"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Performs a ", <$format, ["i", [], ["left shift"], 'do_i]>, " operation upon ", <$format, ["i", [], ["x"], 'do_i]>, " and ", <$format, ["i", [], ["y"], 'do_i]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer.shright", 1]], ["shright"], 'do_method]>, "(", <$format, ["var", [], ["x"], 'do_var]>, ", ", <$format, ["var", [], ["y"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Performs a ", <$format, ["i", [], ["right shift"], 'do_i]>, " operation upon ", <$format, ["i", [], ["x"], 'do_i]>, " and ", <$format, ["i", [], ["y"], 'do_i]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer.not", 1]], ["not"], 'do_method]>, "(", <$format, ["var", [], ["number"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Performs a bitwise ", <$format, ["i", [], ["not"], 'do_i]>, " operation upon ", <$format, ["i", [], ["number"], 'do_i]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer.to_english_text", 1]], ["to_english_text"], 'do_method]>, "(", <$format, ["var", [], ["number"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given an integer, converts it to englist text form, spelling out all numbers."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer.to_bytes", 1]], ["to_bytes"], 'do_method]>, "(", <$format, ["var", [], ["number"], 'do_var]>, "[, ", <$format, ["var", [], ["long"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Given an integer, converts it to the number of bytes. If the optional argument ", <$format, ["i", [], ["long"], 'do_i]>, " is given, then the long form of the unit name (kilobyte vs. kb) will be used."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer.to_roman_numeral", 1]], ["to_roman_numeral"], 'do_method]>, "(", <$format, ["var", [], ["number"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given an integer, converts it to the roman numeral representation."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["integer.roman_numeral_scheme", 1]], ["roman_numeral_scheme"], 'do_method]>, "(", <$format, ["var", [], ["val"], 'do_var]>, ", ", <$format, ["var", [], ["x"], 'do_var]>, ", ", <$format, ["var", [], ["y"], 'do_var]>, ", ", <$format, ["var", [], ["z"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Helper method for .", <$format, ["method", [["integer.to_roman_numeral", 1]], ["to_roman_numeral"], 'do_method]>, "()."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_obj_integer];


new object $help_obj_data_lib: $help_obj;

var $root manager = $help_obj_data_lib;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870208061;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Data Lib", "Data Lib"];
var $help_node links = #[["valid ColdC data", $help_coldc_types], ["toliteral", $help_func_toliteral], ["symbol", $help_coldc_types_symbols], ["valid ColdC type", $help_coldc_types]];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["data_lib.unparse_indent", 1]], ["unparse_indent"], 'do_method]>, "(", <$format, ["var", [], ["value"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Accepts a ", <$format, ["link", [["node", "$help_coldc_types"]], ["valid ColdC data"], 'do_link]>, " item as an argument, and returns a textual representation similar to the result of a ", <$format, ["link", [["node", "$help_func_toliteral"]], ["toliteral"], 'do_link]>, "() call, except in a more driver-friendly manner."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["data_lib.unparse_indent_html", 1]], ["unparse_indent_html"], 'do_method]>, "(", <$format, ["var", [], ["value"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Accepts a ", <$format, ["link", [["node", "$help_coldc_types"]], ["valid ColdC data"], 'do_link]>, " item as an argument and calls .", <$format, ["method", [["data_lib.unparse_indent", 1]], ["unparse_indent"], 'do_method]>, "() with it. It then post-processes the data converting it to HTML. Conversions performed are converting various characters to the valid HTML entity and linking objects the web view of them via /bin/display."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["data_lib.data_map", 1]], ["data_map"], 'do_method]>, "(", <$format, ["var", [], ["val"], 'do_var]>, ", ", <$format, ["var", [], ["method"], 'do_var]>, ", ", <$format, ["var", [], ["options"], 'do_var]>, "[, ", <$format, ["var", [], ["@args"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Maps a method over elements of any data structure. You can use it to map a function inside a list on a frob, for instance. Options decide which data types and frob classes will be affected and which will be left alone. Options is a dict of [key, value] pairs."], 'do_dd]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], ["['object, something]"], 'do_dt]>, <$format, ["dd", [], ["If its an object, it calls the method from that object, otherwise it calls it from data value."], 'do_dd]>, <$format, ["dt", [], ["['list,1]"], 'do_dt]>, <$format, ["dd", [], ["Map into lists."], 'do_dd]>, <$format, ["dt", [], ["['dictionary,1]"], 'do_dt]>, <$format, ["dd", [], ["Map into dicts."], 'do_dd]>, <$format, ["dt", [], ["['frob,1]"], 'do_dt]>, <$format, ["dd", [], ["Map into frobs. You must use the option 'class to specify the class to affect."], 'do_dd]>, <$format, ["dt", [], ["['all,1]"], 'do_dt]>, <$format, ["dd", [], ["Affect all types."], 'do_dd]>, <$format, ["dt", [], ["[type, 1]"], 'do_dt]>, <$format, ["dd", [], ["Affect the types not mentioned above."], 'do_dd]>], 'do_dl]>, <$format, ["dt", [], [".", <$format, ["method", [["data_lib.is_valid_type", 1]], ["is_valid_type"], 'do_method]>, "(", <$format, ["var", [], ["type"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given a ", <$format, ["link", [["node", "$help_coldc_types_symbols"]], ["symbol"], 'do_link]>, ", returns true if it is a ", <$format, ["link", [["node", "$help_coldc_types"]], ["valid ColdC type"], 'do_link]>, ", false if not."], 'do_dd]>], 'do_dl]>], #[['links, #[["valid ColdC data", "$help_coldc_types"], ["toliteral", "$help_func_toliteral"], ["symbol", "$help_coldc_types_symbols"], ["valid ColdC type", "$help_coldc_types"]]]]]>;
var $root inited = 1;
var $root managed = [$help_obj_data_lib];


new object $help_obj_object_lib: $help_obj;

var $root manager = $help_obj_object_lib;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870210595;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Object Lib", "Object Lib"];
var $help_node links = #[["@display", $help_cmd_display]];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [["ind", "8"]], [<$format, ["dt", [], [".", <$format, ["method", [["object_lib.to_dbref", 1]], ["to_dbref"], 'do_method]>, "(", <$format, ["var", [], ["obj"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Accepts strings or objnums and returns a valid objnum. Can throw ~namenf, ~objnf, or ~invdbref."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["object_lib.get_name", 1]], ["get_name"], 'do_method]>, "(", <$format, ["var", [], ["obj"], 'do_var]>, "[, ", <$format, ["var", [], ["@args"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Returns the name of the object. Accepts two optional args. The first is the name of the method to call on the object to return the name. This defaults to 'name. The second argument must be a list, and should contain the list of arguments with which to call the method returning the name of the object."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["object_lib.see_perms", 1]], ["see_perms"], 'do_method]>, "(", <$format, ["var", [], ["obj"], 'do_var]>, "[, ", <$format, ["var", [], ["@args"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Accepts an object as the first argument and displays it's flags in a succint manner. The optional args should be two in number, both of them strings. These are used as the first and last character of the string returned and default to '[' and ']'."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["object_lib.str_to_objlist", 1]], ["str_to_objlist"], 'do_method]>, "(", <$format, ["var", [], ["args"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Accepts a list in string form that is either in english form or delimited by spaces. It then explodes the list into a string and calls .", <$format, ["method", [["object_lib.list_to_objlist", 1]], ["list_to_objlist"], 'do_method]>, "() and returns the result. See the help on .", <$format, ["method", [["object_lib.list_to_objlist", 1]], ["list_to_objlist"], 'do_method]>, "() for further details."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["object_lib.list_to_objlist", 1]], ["list_to_objlist"], 'do_method]>, "(", <$format, ["var", [], ["args"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Accepts a list and attempts to convert each element to a dbref. It returns a dictionary with two keys. 'valid contains a list of the valid dbrefs. 'invalid contains a list of the invalid elements of the list passed in as the argument."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["object_lib.parse_method_flags", 1]], ["parse_method_flags"], 'do_method]>, "(", <$format, ["var", [], ["flags"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Accepts a list of method flags and returns a short string summarizing them. This method is used by ", <$format, ["link", [["node", "$help_cmd_display"]], ["@display"], 'do_link]>, " and other commands."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["object_lib.format_object", 1]], ["format_object"], 'do_method]>, "(", <$format, ["var", [], ["obj"], 'do_var]>, ", ", <$format, ["var", [], ["chop"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Accepts an object and a boolean flag ", <$format, ["var", [], ["chop"], 'do_var]>, ". Formats some general information about the object. Used by ", <$format, ["link", [["node", "$help_cmd_display"]], ["@display"], 'do_link]>, " mainly."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["object_lib.format_method_header", 1]], ["format_method_header"], 'do_method]>, "(", <$format, ["var", [], ["obj"], 'do_var]>, ", ", <$format, ["var", [], ["method"], 'do_var]>, ", ", <$format, ["var", [], ["opt"], 'do_var]>, ", ", <$format, ["var", [], ["flags"], 'do_var]>, ", ", <$format, ["var", [], ["access"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Accepts an object, method name, string, method flags and method access and returns a method header in '@program' format."], 'do_dd]>], 'do_dl]>], #[['links, #[["@display", "$help_cmd_display"]]]]]>;
var $root inited = 1;
var $root managed = [$help_obj_object_lib];


new object $help_obj_help_node: $help_obj;

var $root manager = $help_obj_help_node;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870559421;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Help Node", "Help Node"];
var $help_node links = #[["Commands", $help_node_commands], ["Names", $help_node_names], ["Setting", $help_node_settings], ["Creation", $help_node_creation], ["Formatting", $help_node_formatting]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "These pages explain how to create a help system (or just a single help node), and the conventions and standards that should be followed.", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["link", [["node", "$help_node_commands"]], ["Commands"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Commands to use in manipulating help nodes"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_node_names"]], ["Names"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Information about naming help nodes"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_node_settings"]], ["Setting"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Information about help node settings"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_node_creation"]], ["Creation"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Conventions used in creating a help node"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_node_formatting"]], ["Formatting"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Common Help Node formatting Conventions"], 'do_dd]>], 'do_dl]>], #[['links, #[["Commands", "$help_node_commands"], ["Names", "$help_node_names"], ["Setting", "$help_node_settings"], ["Creation", "$help_node_creation"], ["Formatting", "$help_node_formatting"]]]]]>;
var $root inited = 1;
var $root managed = [$help_obj_help_node];
var $help_node group = 1;


new object $help_node_names: $help_obj_help_node;

var $root manager = $help_node_names;
var $root managed = [$help_node_names];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870559844;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Names", "Names"];
var $help_node links = #[["name templates", $help_app_names]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Help nodes do not use ", <$format, ["link", [["node", "$help_app_names"]], ["name templates"], 'do_link]>, ", due to indexing and referencing concerns. Instead to have a help node be indexed with more than one name, include all the names in the node name, seperating them with a pipe character ('", <$format, ["tt", [], ["|"], 'do_tt]>, "'), such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["\"@help-list|@hlist|@hl\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When this is done, each part will be indexed seperately, and only the first name in the group will be displayed on the Help Node Page."], #[['links, #[["name templates", "$help_app_names"]]]]]>;
var $root inited = 1;


new object $help_node_settings: $help_obj_help_node;

var $root manager = $help_node_settings;
var $root managed = [$help_node_settings];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870559923;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Settings", "Settings"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Settings on a help node:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["group = yes", <$format, ["br", [], [], 'do_br]>, "holder = no", <$format, ["br", [], [], 'do_br]>, "index =", <$format, ["br", [], [], 'do_br]>, "nolist = yes"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The group setting is used to control if a node lists the group (i.e. its siblings) at the bottom of the page. If group is enabled, they will be listed. Otherwise, they will not be listed. Note: If the help node is a child of ", <$format, ["tt", [], ["$help_obj"], 'do_tt]>, ", ", <$format, ["tt", [], ["$help_sys"], 'do_tt]>, ", ", <$format, ["tt", [], ["$help_cmds"], 'do_tt]>, " or a similar 'place-holder' object, its group should be set to no. ", <$format, ["np", [], [], 'do_np]>, "The holder setting is enabled when a help node exists purely for heirarchial reasons. This changes how the object is listed when a title is generated with all heirarchial information. If holder is enabled, no links will be made to the object. ", <$format, ["np", [], [], 'do_np]>, "The index setting is used to set the help index (children of $help_index). Only specify an index for a help node when the help node is a unique concept (specifically in the name). For instance, the node 'Events' exists, and has several children nodes including the node 'Registering'. In this situation 'Events' is indexed but 'Registering' is not. ", <$format, ["np", [], [], 'do_np]>, "The nolist setting is used to make an object 'invisible', so that it does not showup in groups or heirarchial information."], #[]]>;
var $root inited = 1;


new object $help_node_creation: $help_obj_help_node;

var $root manager = $help_node_creation;
var $root managed = [$help_node_creation];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870560232;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Creation", "Creation"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "When creating a help node, be sure to keep the following conventions in mind: ", <$format, ["np", [], [], 'do_np]>, "Command nodes always descend from ", <$format, ["tt", [], ["$help_cmds"], 'do_tt]>, ", but have the prefix 'help_cmd_' (non-plural). Command nodes always go in the Command help index (", <$format, ["tt", [], ["$help_index_cmds"], 'do_tt]>, "). ", <$format, ["np", [], [], 'do_np]>, "ColdCore help descends from ", <$format, ["tt", [], ["$help_coldcore"], 'do_tt]>, " ", <$format, ["np", [], [], 'do_np]>, "Subsystems descend from ", <$format, ["tt", [], ["$help_sys"], 'do_tt]>, " ", <$format, ["np", [], [], 'do_np]>, "Object help descends from ", <$format, ["tt", [], ["$help_obj"], 'do_tt]>, " (generally libraries) ", <$format, ["np", [], [], 'do_np]>, "When naming an object, include its parentage where appropriate. However, dont include all levels of descending in the name. Use what is necessary to make it unique without being overbearing. For instance, ", <$format, ["tt", [], ["$help_coldc_func"], 'do_tt]>, " is perfectly fine, where ", <$format, ["tt", [], ["$help_coldcore_prog_coldc_func"], 'do_tt]>, " would be the ''full'' name (use the former, not the latter). All help nodes should begin with the 'help_' prefix, but not 'help_node_'. ", <$format, ["np", [], [], 'do_np]>, "only specify an index for a help node, when the help node is a unique concept (specifically in the name). For instance, the node 'Events' exists, and has several children nodes including the node 'Registering'. In this situation 'Events' is indexed but 'Registering' is not. ", <$format, ["np", [], [], 'do_np]>, "make sure the node settings are correct. These can be confusing, so try to navigate the tree from various directions and make sure everything is functioning and displaying properly. (see Help Node Settings for more information)}"], #[]]>;
var $root inited = 1;


new object $help_node_formatting: $help_obj_help_node;

var $root manager = $help_node_formatting;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870560380;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Format Conventions", "Format Conventions"];
var $help_node links = #[["General", $help_formatting_general], ["Commands", $help_formatting_commands], ["Objects", $help_formatting_objects]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Close attention should be given to how a help node is formatted, so that it looks the same as other help nodes. Everything from spacing to which tags to use in which situation should be the same from help node to help node of similar type (such as commands). ", <$format, ["np", [], [], 'do_np]>, "Formatting Conventions:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_formatting_general"]], ["General"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_formatting_commands"]], ["Commands"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_formatting_objects"]], ["Objects"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['links, #[["General", "$help_formatting_general"], ["Commands", "$help_formatting_commands"], ["Objects", "$help_formatting_objects"]]]]]>;
var $root inited = 1;
var $root managed = [$help_node_formatting];


new object $help_formatting_general: $help_node_formatting;

var $root manager = $help_formatting_general;
var $root managed = [$help_formatting_general];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870560749;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "General", "General"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["np", [], [], 'do_np]>, "Some general formatting conventions: ", <$format, ["subj", [["level", "2"]], ["White Space"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "White Space in CML is generally managed ok. However, in some cases it is not--when formatting plaintext. This is due primarily to the problems which arise with multiple output formats. Therefore, you should pay close attention when writing help information that your Whitespace formatting is correct. Are your paragraphs spaced with one blank line them? Do your paragraphs begin at the start of the line, or is there a space first? ", <$format, ["subj", [["level", "2"]], ["Action Examples"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "When giving an example of an action the user may take, always format it as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["{dfn:example}"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In the case of one or more lines, use {br}, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["{dfn:example line 1{br}example line 2}"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When showing an action and result, use '=>' to represent the result. Do not prefix the action with a prompt, unless it is a command."], #[]]>;
var $root inited = 1;


new object $help_formatting_commands: $help_node_formatting;

var $root manager = $help_formatting_commands;
var $root managed = [$help_formatting_commands];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870561246;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Commands", "Commands"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Each command node has the following general look:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["nobound", 1]], [<$format, ["quote", [], ["TYPE COMMAND\n\n    Syntax: cmd args\n\nExplanation\n\nExamples"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["subj", [["level", "2"]], ["Command Type"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "TYPE is one of: ADMIN, PROGRAMMER, BUILDER, or the appropriate name for the object the command is defined on. In the case of $user no command is type is defined. ", <$format, ["tt", [], ["$player"], 'do_tt]>, " and similar objects may (in the future) also define their own type. Feature objects will as well (although they will list as SOCIAL FEATURE COMMAND for the $social feature). ", <$format, ["np", [], [], 'do_np]>, "Type has a CML format of:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["nobound", 1]], ["{p}{b:ADMIN COMMAND}"], 'do_dfn]>, " ", <$format, ["subj", [["level", "2"]], ["Command Syntax"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Syntax is a standard command syntax definition, using <token> to represent an argument, brackets to enclose optional arguments, and an elipse to represent any number of arguments beyond that point. ", <$format, ["np", [], [], 'do_np]>, "Command syntax has a CML format of:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["nobound", 1]], ["{dfn:Syntax: {tt:@cmd \[-option\] <arg> \[<arg2> ...\]}}"], 'do_dfn]>, " ", <$format, ["subj", [["level", "2"]], ["Explanation"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "The explanation is one or more paragraphs explaning the command. Always correctly use {p} vs {np} to guarantee one blank line between paragraphs. ", <$format, ["subj", [["level", "2"]], ["Examples"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Examples should use the general example format. Make sure to correctly use {p} or {np} as appropriate in order to guarantee one blank line between the example and any paragraphs."], #[]]>;
var $root inited = 1;


new object $help_formatting_objects: $help_node_formatting;

var $root manager = $help_formatting_objects;
var $root managed = [$help_formatting_objects];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870561303;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Objects", "Objects"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The format used in an object node will depend upon the complexity and type of object. Look at other existing object nodes for general formatting not outlined below. Don't forget to set the objects's help-node setting, ala:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["nobound", 1]], ["@set obj:help-node=$help_obj_foof"], 'do_dfn]>, " ", <$format, ["subj", [["level", "2"]], ["Method Listings"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "When listing methods, always use a definition list (dl) with an indent of eight characters (ind=8). Specify the method reference in the definition title ({dt}), using the {method} tag. Use {var} around any arguments. The method explanation goes in the definition description ({dd}). Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["nobound", 1]], [<$format, ["quote", [], ["{dl ind=8:\n  {dt: .{method list.length:length}({var:list})}           \n  {dd: Length of the {var:list}.}   \n  ...}"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["subj", [["level", "2"]], ["Method Groups"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "If possible, group methods by behaviour or subsystem, to reduce the overall method list size."], #[]]>;
var $root inited = 1;


new object $help_node_commands: $help_obj_help_node;

var $root manager = $help_node_commands;
var $root managed = [$help_node_commands];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870636767;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Commands", "Commands"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[]]>;
var $root inited = 1;


new object $help_obj_code_lib: $help_obj;

var $root manager = $help_obj_code_lib;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870639275;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Code Lib", "Code Lib"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["code_lib.quotes", 1]], ["quotes"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns as the entire 'library' of quotes."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib.add_random_quote", 1]], ["add_random_quote"], 'do_method]>, "(", <$format, ["var", [], ["quote"], 'do_var]>, "[, ", <$format, ["var", [], ["from"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Accepts a ", <$format, ["var", [], ["quote"], 'do_var]>, " and an optional attribution ", <$format, ["var", [], ["from"], 'do_var]>, " and adds it to the library of quotes."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib.random_quote", 1]], ["random_quote"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns as a list of strings, a randomly selected quote."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib.generate_listing", 1]], ["generate_listing"], 'do_method]>, "(", <$format, ["var", [], ["who"], 'do_var]>, "[, ", <$format, ["var", [], ["args"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Helper method for the @who commands for gathering the information for the table."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib.parse_name", 1]], ["parse_name"], 'do_method]>, "(", <$format, ["var", [], ["name"], 'do_var]>, "[, ", <$format, ["var", [], ["def"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib.random_word", 1]], ["random_word"], 'do_method]>, "([", <$format, ["var", [], ["args"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Creates a random word. It can accept up to 3 args. First is the minimum length of the generated word, which defaults to 3 characters. Second is the maximum length of the generated word, defaulting to 10 characters. The third and final optional argument is a dictionary which can be used to specify additional consonants, vowels, and rare letters."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib.random_password", 1]], ["random_password"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Creates a random word suitable for use as a password."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib.punctuation_type", 1]], ["punctuation_type"], 'do_method]>, "(", <$format, ["var", [], ["str"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given a string, ", <$format, ["var", [], ["str"], 'do_var]>, ", determines a verb to use when 'saying' that string based on the punctuation at the end of the string."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib.verify_code", 1]], ["verify_code"], 'do_method]>, "(", <$format, ["var", [], ["code"], 'do_var]>, ", ", <$format, ["var", [], ["method"], 'do_var]>, ", ", <$format, ["var", [], ["warn"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Checks over code, looking for particular common errors."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib.generate_object_listing", 1]], ["generate_object_listing"], 'do_method]>, "(", <$format, ["var", [], ["objs"], 'do_var]>, ", ", <$format, ["var", [], ["multi"], 'do_var]>, "[, ", <$format, ["var", [], ["args"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib.point_to_line", 1]], ["point_to_line"], 'do_method]>, "(", <$format, ["var", [], ["err"], 'do_var]>, ", ", <$format, ["var", [], ["left"], 'do_var]>, ", ", <$format, ["var", [], ["right"], 'do_var]>, ", ", <$format, ["var", [], ["lineno"], 'do_var]>, ", ", <$format, ["var", [], ["line"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib._debug_listing", 1]], ["_debug_listing"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib.generate_debug_listing", 1]], ["generate_debug_listing"], 'do_method]>, "(", <$format, ["var", [], ["info"], 'do_var]>, ", ", <$format, ["var", [], ["mode"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib._trace_listing", 1]], ["_trace_listing"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib._trace_profile", 1]], ["_trace_profile"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib._profile_listing", 1]], ["_profile_listing"], 'do_method]>, "(", <$format, ["var", [], ["list"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib._show_ref", 1]], ["_show_ref"], 'do_method]>, "(", <$format, ["var", [], ["i"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib.valid_message_id", 1]], ["valid_message_id"], 'do_method]>, "(", <$format, ["var", [], ["str"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Verifies whether or not the given string, ", <$format, ["var", [], ["str"], 'do_var]>, ", is a valid id for a message."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib.valid_setting_id", 1]], ["valid_setting_id"], 'do_method]>, "(", <$format, ["var", [], ["str"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Verifies whether or not the given string, ", <$format, ["var", [], ["str"], 'do_var]>, ", is a valid id for a setting."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib.code_to_html", 1]], ["code_to_html"], 'do_method]>, "(", <$format, ["var", [], ["code"], 'do_var]>, "[, ", <$format, ["var", [], ["object"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Converts a code listing to HTML."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["code_lib._do_method_href", 1]], ["_do_method_href"], 'do_method]>, "(", <$format, ["var", [], ["method"], 'do_var]>, "[, ", <$format, ["var", [], ["object"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Helper method for .", <$format, ["method", [["code_lib.code_to_html", 1]], ["code_to_html"], 'do_method]>, "() for generating the HTML."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_obj_code_lib];


new object $help_obj_generic_map: $help_obj;

var $root manager = $help_obj_generic_map;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 874066987;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Generic Map", "Generic Map"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Generic map is a simple note that contains a map of the room and its surroundings. While it can be described, it's not strictly necessary, you only need to edit the note's text for the desired effect. The map may be both wider and taller than the screen; in that case, only a part of the map will be displayed. The window to be displayed is configurable. ", <$format, ["subj", [["level", "3"]], ["Tracking the location"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "You can embed pairs of numbers (example: ", <$format, ["tt", [], ["'00'"], 'do_tt]>, ") within the map. All such pairs will be replaced with spaces once the map is printed to the player, except the one that corresponds to the current location. To display that, set map-position on the current room. The map position specifies the window (the upper left corner of the part of the map you want to display), tag (the room tag that will be shown) and the generic map object that is used with the current room. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> @set here:map-position=window 0, 0 tag 04 on $map_of_taobh_thiar"], 'do_dfn]>, " This sets the map of the current room to the $map_of_taobh_thiar; its tag to 04. Window (0,0) makes @map display the entire map. Finally, the portion of the $map_of_taobh_thiar for this room looks like:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["\n                        \                   |     /     \ \n   Steam Tunnel 03    Steam Tunnel 04 Steam Tunnel 07   |\n                          \            /                |\n\n"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "@map in the Steam Tunnel will replace 04 with **, 03 and 07 will vanish from the map."], #[]]>;
var $root inited = 1;
var $help_node group = 1;
var $root managed = [$help_obj_generic_map];


new object $help_obj_world_time: $help_obj;

var $root manager = $help_obj_world_time;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 887957184;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "World Time", "World Time"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "$world_time contains methods relating to time-handling on a world wide basis. Parts of it need upgrading for a more complex world, like ", <$format, ["method", [["world_time.current_season", 1]], ["current_season"], 'do_method]>, " to handle having a north and south hemisphere with opposite seasons.", <$format, ["p", [], [], 'do_p]>, <$format, ["subj", [["level", "3"]], ["Methods"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["world_time.from_english", 1]], ["from_english"], 'do_method]>, "(", <$format, ["var", [], ["string"], 'do_var]>, ", [", <$format, ["var", [], ["units"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Given an english description of a length of time as a ", <$format, ["var", [], ["string"], 'do_var]>, ", it returns the number of seconds that time represents."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["world_time.local_time", 1]], ["local_time"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns the number of 'world seconds' since the world-time started."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["world_time.daytime", 1]], ["daytime"], 'do_method]>, "(", <$format, ["var", [], ["zone"], 'do_var]>, ", ", <$format, ["var", [], ["dayscale"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Returns a list of three elements. First is the number of hours into the day. Second is a symbol for the part of day it is, 'night, 'predawn, 'dawn, etc. Third is either 'day or 'night depending on the time of day."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["world_time.current_season", 1]], ["current_season"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns a string for the current season."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["world_time.from_unit_list", 1]], ["from_unit_list"], 'do_method]>, "(", <$format, ["var", [], ["time"], 'do_var]>, ", ", <$format, ["var", [], ["ulist"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given a number of seconds, ", <$format, ["var", [], ["time"], 'do_var]>, ", and a list of indexes into the time_units, ", <$format, ["var", [], ["ulist"], 'do_var]>, ", return an english string representing the time."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["world_time.parse_unit", 1]], ["parse_unit"], 'do_method]>, "(", <$format, ["var", [], ["unit"], 'do_var]>, ", [", <$format, ["var", [], ["units"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Returns the entry in time_units for the unit given by ", <$format, ["var", [], ["unit"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["world_time.time_units", 1]], ["time_units"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns the current units of time being used."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_obj_world_time];


new object $help_obj_time: $help_obj;

var $root manager = $help_obj_time;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 887988392;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Time", "Time"];
var $help_node links = #[["$world_time", $help_obj_world_time]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "$time is a general utility object for handling time values that don't deal specifically with the game's time system. Those issues are covered by ", <$format, ["link", [["node", "$help_obj_world_time"]], ["$world_time"], 'do_link]>, ".", <$format, ["p", [], [], 'do_p]>, <$format, ["subj", [["level", "3"]], ["Methods"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["time.format", 1]], ["format"], 'do_method]>, "(", <$format, ["var", [], ["format"], 'do_var]>, ", ", <$format, ["var", [], ["time"], 'do_var]>, ") ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Given a format string, ", <$format, ["var", [], ["format"], 'do_var]>, " and a time in seconds, ", <$format, ["var", [], ["time"], 'do_var]>, ", returns the formatted time string. For now, revert to a man page for strftime for help on the format string."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["time.elapsed", 1]], ["elapsed"], 'do_method]>, "(", <$format, ["var", [], ["time"], 'do_var]>, ", [", <$format, ["var", [], ["flag"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Given a time ", <$format, ["var", [], ["time"], 'do_var]>, ", it returns the time between now and then. ", <$format, ["var", [], ["flag"], 'do_var]>, " controls how it is formatted. 'long will return it in the manner of .", <$format, ["method", [["time.to_english", 1]], ["to_english"], 'do_method]>, "(), while the default value, 'stopwatch, will return it as HH:MM:SS"], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["time.dhms", 1]], ["dhms"], 'do_method]>, "(", <$format, ["var", [], ["secs"], 'do_var]>, ", [", <$format, ["var", [], ["long"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Given a time, ", <$format, ["var", [], ["time"], 'do_var]>, ", it returns the number of days OR hours OR minutes OR seconds, which ever unit fits roughly. If the flag ", <$format, ["var", [], ["long"], 'do_var]>, " is true, it uses the full name of the unit of time."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["time.from_english", 1]], ["from_english"], 'do_method]>, "(", <$format, ["var", [], ["string"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Returns the number of seconds represented by the english description of time in the argument ", <$format, ["var", [], ["string"], 'do_var]>, ". This just defers to $world_time.", <$format, ["method", [["world_time.from_english", 1]], ["from_english"], 'do_method]>, "()."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["time.to_english", 1]], ["to_english"], 'do_method]>, "(", <$format, ["var", [], ["time"], 'do_var]>, ", [", <$format, ["var", [], ["reftime"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Given a number of seconds, ", <$format, ["var", [], ["time"], 'do_var]>, ", and an optional reference time, ", <$format, ["var", [], ["reftime"], 'do_var]>, ", which defaults to the current time, will return a string representing the time in English. This method attempts to take the varying number of days in a month and also leap years into account. NOTE: The results of this method when fed into .", <$format, ["method", [["time.from_english", 1]], ["from_english"], 'do_method]>, "(), will NOT return the original integer due to the lack of compensation for the things this method accounts for: the leap years, number of days in a month, etc."], 'do_dd]>], 'do_dl]>], #[['links, #[["$world_time", "$help_obj_world_time"]]]]]>;
var $root inited = 1;
var $root managed = [$help_obj_time];


new object $help_obj_robot: $help_obj;

var $root manager = $help_obj_robot;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 888050848;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Robot|@reactions|@activate-reaction|@deactivate-reaction|@add-reaction", "Robot|@reactions|@activate-reaction|@deactivate-reaction|@add-reaction"];
var $help_node links = #[["Methods", $help_obj_robot_methods]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "$robot is an object for generic puppet type things. It can have reactions defined on it to respond to events in it's environment.", <$format, ["p", [], [], 'do_p]>, <$format, ["subj", [["level", "3"]], ["Commands"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], ["@reactions <this>"], 'do_dt]>, <$format, ["dd", [], ["Lists information about the reactions defined on ", <$format, ["var", [], ["this"], 'do_var]>, ". An asterisk in the left margin means that the reaction is activated. The numbers given here may be used by @activate-reaction and @deactivate-reaction."], 'do_dd]>, <$format, ["dt", [], ["@activate-r?eaction|@ar <number> on <this>"], 'do_dt]>, <$format, ["dd", [], ["Activates the reaction ", <$format, ["var", [], ["number"], 'do_var]>, " on the robot ", <$format, ["var", [], ["this"], 'do_var]>, ". The number may be found by looking at @reactions ", <$format, ["var", [], ["this"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], ["@deactivate-r?eaction|@dr <number> on <this>"], 'do_dt]>, <$format, ["dd", [], ["Deactivates the reaction ", <$format, ["var", [], ["number"], 'do_var]>, " on the robot ", <$format, ["var", [], ["this"], 'do_var]>, ". The number may be found by looking at @reactions ", <$format, ["var", [], ["this"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], ["@add-r?eaction <any> to <any> on <this>"], 'do_dt]>, <$format, ["dd", [], ["Add a reaction with ", <$format, ["var", [], ["template"], 'do_var]>, " to ", <$format, ["var", [], ["hook"], 'do_var]>, " on ", <$format, ["var", [], ["this"], 'do_var]>, ". Options follow the template and are as follows: ", <$format, ["tt", [], ["+m?ethod"], 'do_tt]>, " Match the template with ", <$format, ["var", [], ["method"], 'do_var]>, ". Accepted values are regexp, pattern, and template. The default is regexp. ", <$format, ["tt", [], ["+t?ype"], 'do_tt]>, " Type of event to which to react. Valid values are tell to react to anything sent to .tell(), notell to react to everything not sent to .tell(), any to react to anything (inefficient and not recommended), or any social event (currently whisper, tosay, and remote). The default is tosay. ", <$format, ["tt", [], ["+c?hance"], 'do_tt]>, " Percent chance that the reaction will be triggered. ", <$format, ["tt", [], ["+ti?mes"], 'do_tt]>, " Number of times a reaction can be triggered before being deactivated. ", <$format, ["tt", [], ["+a?rgs"], 'do_tt]>, " Arguments to give to ", <$format, ["var", [], ["hook"], 'do_var]>, " after the match string, the output of the match method, and the sender. ", <$format, ["tt", [], ["+min"], 'do_tt]>, " Minimum delay before triggering reaction (default: 0). ", <$format, ["tt", [], ["+max"], 'do_tt]>, " Maximum delay before triggering reaction (default: same as min). If you wish to match any event of a given type, leave the template blank. If you give options, just don't specify a template at all. Otherwise, use \"\"."], 'do_dd]>, <$format, ["dt", [], ["@del-r?eaction <number> from|on <this>"], 'do_dt]>, <$format, ["dd", [], ["Delete reaction ", <$format, ["var", [], ["number"], 'do_var]>, " from robot ", <$format, ["var", [], ["this"], 'do_var]>, ", deactivating and unhooking if necessary."], 'do_dd]>], 'do_dl]>, <$format, ["subj", [["level", "3"]], [<$format, ["link", [["node", "$help_obj_robot_methods"]], ["Methods"], 'do_link]>], 'do_subj]>, " ", <$format, ["subj", [["level", "3"]], ["How do I use it?"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["Define the method to carry out the work of the response if needed. There are pre-defined utilty methods to help avoid this."], 'do_li]>, <$format, ["li", [], ["Call @add-reaction and define your reaction."], 'do_li]>, <$format, ["li", [], ["Call @activate-reaction to activate your new reaction."], 'do_li]>, <$format, ["li", [], ["Experiment and have fun."], 'do_li]>], 'do_ol]>, <$format, ["p", [], [], 'do_p]>], #[['links, #[["Methods", "$help_obj_robot_methods"]]]]]>;
var $root inited = 1;
var $root managed = [$help_obj_robot];


new object $help_obj_robot_methods: $help_obj_robot;

var $root manager = $help_obj_robot_methods;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 888050905;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Robot Methods", "Robot Methods"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Public Methods:", <$format, ["br", [], [], 'do_br]>, <$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["robot.parse_line", 1]], ["parse_line"], 'do_method]>, "(", <$format, ["var", [], ["line"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Accepts a line of text and treats it as if it had been typed by a user."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.tell", 1]], ["tell"], 'do_method]>, "(what, [", <$format, ["var", [], ["who"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Standard 'tell method for receiving input."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.event_notify", 1]], ["event_notify"], 'do_method]>, "(", <$format, ["var", [], ["event"], 'do_var]>, ", ", <$format, ["var", [], ["origin"], 'do_var]>, ", [", <$format, ["var", [], ["args"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.startup", 1]], ["startup"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.active", 1]], ["active"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns a dictionary of the active reactions."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.activate_reaction", 1]], ["activate_reaction"], 'do_method]>, "(", <$format, ["var", [], ["id"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given an ", <$format, ["var", [], ["id"], 'do_var]>, ", activates that reaction."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.tell_traceback", 1]], ["tell_traceback"], 'do_method]>, "([", <$format, ["var", [], ["args"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.add_reaction", 1]], ["add_reaction"], 'do_method]>, "([", <$format, ["var", [], ["args"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.del_reaction", 1]], ["del_reaction"], 'do_method]>, "(", <$format, ["var", [], ["id"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.reactions", 1]], ["reactions"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns a dictionary of all defined reactions."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.match_type", 1]], ["match_type"], 'do_method]>, "(", <$format, ["var", [], ["type"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.reactions_cmd", 1]], ["reactions_cmd"], 'do_method]>, "(", <$format, ["var", [], ["cmdstr"], 'do_var]>, ", ", <$format, ["var", [], ["cmd"], 'do_var]>, ", ", <$format, ["var", [], ["this"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Command for listing information about the reactions on the robot."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.update_reaction", 1]], ["update_reaction"], 'do_method]>, "(", <$format, ["var", [], ["id"], 'do_var]>, ", ", <$format, ["var", [], ["part"], 'do_var]>, ", ", <$format, ["var", [], ["value"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.deactivate_reaction", 1]], ["deactivate_reaction"], 'do_method]>, "(", <$format, ["var", [], ["id"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given an ", <$format, ["var", [], ["id"], 'do_var]>, ", deactivates that reaction."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.connected", 1]], ["connected"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["If the robot is active, returns true, otherwise false."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.connected_time", 1]], ["connected_time"], 'do_method]>, "([", <$format, ["var", [], ["args"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.idle_time", 1]], ["idle_time"], 'do_method]>, "([", <$format, ["var", [], ["args"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.activate_reaction_cmd", 1]], ["activate_reaction_cmd"], 'do_method]>, "(", <$format, ["var", [], ["cmdstr"], 'do_var]>, ", ", <$format, ["var", [], ["cmd"], 'do_var]>, ", ", <$format, ["var", [], ["int"], 'do_var]>, ", ", <$format, ["var", [], ["prep"], 'do_var]>, ", ", <$format, ["var", [], ["this"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Command for activating a reaction on the robot."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.deactivate_reaction_cmd", 1]], ["deactivate_reaction_cmd"], 'do_method]>, "(", <$format, ["var", [], ["cmdstr"], 'do_var]>, ", ", <$format, ["var", [], ["cmd"], 'do_var]>, ", ", <$format, ["var", [], ["int"], 'do_var]>, ", ", <$format, ["var", [], ["prep"], 'do_var]>, ", ", <$format, ["var", [], ["this"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Command for deactivating a reaction on the robot."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.add_reaction_cmd", 1]], ["add_reaction_cmd"], 'do_method]>, "(", <$format, ["var", [], ["cmdstr"], 'do_var]>, ", ", <$format, ["var", [], ["cmd"], 'do_var]>, ", ", <$format, ["var", [], ["str"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Command for adding a new reaction to the robot."], 'do_dd]>], 'do_dl]>, "Protected Methods:", <$format, ["br", [], [], 'do_br]>, <$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["robot.react_command", 1]], ["react_command:react_command"], 'do_method]>, "(", <$format, ["var", [], ["str"], 'do_var]>, ", ", <$format, ["var", [], ["match"], 'do_var]>, ", ", <$format, ["var", [], ["sender"], 'do_var]>, ", ", <$format, ["var", [], ["cmd"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.react_subcmd", 1]], ["react_subcmd"], 'do_method]>, "(", <$format, ["var", [], ["str"], 'do_var]>, ", ", <$format, ["var", [], ["match"], 'do_var]>, ", ", <$format, ["var", [], ["sender"], 'do_var]>, ", ", <$format, ["var", [], ["cmd"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.check_reactions", 1]], ["check_reactions"], 'do_method]>, "(", <$format, ["var", [], ["type"], 'do_var]>, ", ", <$format, ["var", [], ["str"], 'do_var]>, ", ", <$format, ["var", [], ["sender"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.update_active", 1]], ["update_active"], 'do_method]>, "(", <$format, ["var", [], ["key"], 'do_var]>, ", ", <$format, ["var", [], ["id"], 'do_var]>, ", ", <$format, ["var", [], ["value"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.remove_active", 1]], ["remove_active"], 'do_method]>, "(", <$format, ["var", [], ["key"], 'do_var]>, ", ", <$format, ["var", [], ["id"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.do_reaction", 1]], ["do_reaction"], 'do_method]>, "(", <$format, ["var", [], ["str"], 'do_var]>, ", ", <$format, ["var", [], ["match"], 'do_var]>, ", ", <$format, ["var", [], ["id"], 'do_var]>, ", ", <$format, ["var", [], ["sender"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], [], 'do_dd]>], 'do_dl]>, "Private Methods:", <$format, ["br", [], [], 'do_br]>, <$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["robot.check_reaction_args", 1]], ["check_reaction_args"], 'do_method]>, "(", <$format, ["var", [], ["method"], 'do_var]>, ", ", <$format, ["var", [], ["template"], 'do_var]>, ", ", <$format, ["var", [], ["type"], 'do_var]>, ", ", <$format, ["var", [], ["chance"], 'do_var]>, ", ", <$format, ["var", [], ["times"], 'do_var]>, ", ", <$format, ["var", [], ["hook"], 'do_var]>, ", ", <$format, ["var", [], ["min"], 'do_var]>, ", ", <$format, ["var", [], ["max"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Type checking method."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.check_reaction_hook", 1]], ["check_reaction_hook"], 'do_method]>, "(", <$format, ["var", [], ["hook"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Type checking method."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.check_reaction_hook_method", 1]], ["check_reaction_hook_method"], 'do_method]>, "(", <$format, ["var", [], ["method"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Type checking method."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.check_reaction_hook_args", 1]], ["check_reaction_hook_args"], 'do_method]>, "(", <$format, ["var", [], ["args"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Type checking method."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.check_reaction_min", 1]], ["check_reaction_min"], 'do_method]>, "(", <$format, ["var", [], ["min"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Type checking method."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.check_reaction_max", 1]], ["check_reaction_max"], 'do_method]>, "(", <$format, ["var", [], ["max"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Type checking method."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.check_reaction_matchwith", 1]], ["check_reaction_matchwith"], 'do_method]>, "(", <$format, ["var", [], ["method"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Type checking method."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.check_reaction_template", 1]], ["check_reaction_template"], 'do_method]>, "(", <$format, ["var", [], ["template"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Type checking method."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.check_reaction_type", 1]], ["check_reaction_type"], 'do_method]>, "(", <$format, ["var", [], ["type"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Type checking method."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.check_reaction_chance", 1]], ["check_reaction_chance"], 'do_method]>, "(", <$format, ["var", [], ["chance"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Type checking method."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["robot.check_reaction_times", 1]], ["check_reaction_times"], 'do_method]>, "(", <$format, ["var", [], ["times"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Type checking method."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_obj_robot_methods];


new object $help_obj_motd: $help_obj;

var $root manager = $help_obj_motd;
var $root managed = [$help_obj_motd];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 906679568;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "motd", "motd"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "$motd is an object which controls the display which users receive upon connecting, as well as the web page which the HTTP server returns. This object allows administrators to easily change and customize this information. This can be done via the following settings:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], ["$motd:login-sequence:"], 'do_dt]>, <$format, ["dd", [], ["Sets the sequence of items to be displayed on the login screen"], 'do_dd]>, <$format, ["dt", [], ["$motd:server-name:"], 'do_dt]>, <$format, ["dd", [], ["Sets the default server name for MOTD displays"], 'do_dd]>, <$format, ["dt", [], ["$motd:server-title:"], 'do_dt]>, <$format, ["dd", [], ["Sets the default server title for MOTD displays"], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "$motd:login-sequence is a list of items which can be passed to $motd.build() to construct the login display. The list of valid arguments are as follows:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], ["'admins:"], 'do_dt]>, <$format, ["dd", [], ["Displays a list of administrators"], 'do_dd]>, <$format, ["dt", [], ["'connected:"], 'do_dt]>, <$format, ["dd", [], ["Displays the number of currently connected users"], 'do_dd]>, <$format, ["dt", [], ["'core_version:"], 'do_dt]>, <$format, ["dd", [], ["Displays the current core version"], 'do_dd]>, <$format, ["dt", [], ["'default:"], 'do_dt]>, <$format, ["dd", [], ["Constructs a default login display"], 'do_dd]>, <$format, ["dt", [], ["'driver_version:"], 'do_dt]>, <$format, ["dd", [], ["Displays the version of the driver currently in use"], 'do_dd]>, <$format, ["dt", [], ["'help:"], 'do_dt]>, <$format, ["dd", [], ["Displays a help message"], 'do_dd]>, <$format, ["dt", [], ["'long:"], 'do_dt]>, <$format, ["dd", [], ["Displays the server's title, then its name"], 'do_dd]>, <$format, ["dt", [], ["'name:"], 'do_dt]>, <$format, ["dd", [], ["Displays the server name"], 'do_dd]>, <$format, ["dt", [], ["'notes:"], 'do_dt]>, <$format, ["dd", [], ["Displays the contents of the notes variable on $motd"], 'do_dd]>, <$format, ["dt", [], ["'short:"], 'do_dt]>, <$format, ["dd", [], ["Displays only the server's title"], 'do_dd]>, <$format, ["dt", [], ["'title:"], 'do_dt]>, <$format, ["dd", [], ["Displays the server title"], 'do_dd]>, <$format, ["dt", [], ["'quote:"], 'do_dt]>, <$format, ["dd", [], ["Displays a random quote"], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $help_node index = $help_index_objects;


new object $help_obj_mail_list: $help_obj;

var $root manager = $help_obj_mail_list;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 909406280;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Mail List", "Mail List"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The Mail List is a generic recipient for mail. To create a mailing list simply spawn a new object from $mail_list, and name it as appropriate for your list. You can configure the following settings on a mailing list: mail-notify, mail-senders, mail-readers and inet-list. The first three settings can be set as logically true or false (i.e. anybody, everybody, nobody, etc), or they can be set to the token \"writers\", or they can be a list of objects. If they are the token \"writers\" it includes whoever is included as a writer. If it is a list of objects, only those objects are included. ", <$format, ["subj", [["level", "2"]], ["mail-notify"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "A list of people who will receive notification, if false or true no notification is made to anybody. ", <$format, ["subj", [["level", "2"]], ["mail-senders"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Who can send to the list, or if true anybody can send to the list. ", <$format, ["subj", [["level", "2"]], ["mail-readers"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Who who can read the list. If true anybody can read the list. ", <$format, ["subj", [["level", "2"]], ["inet-list"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Can be set to an email address. If so, it will treat this Mail List as an Internet Mailing List. This behaviour is special in that it will forward to the specified email address if mail is received from within the Virtual Environment--but if mail is received from the SMTP gateway it will be stored on the list as normal.", <$format, ["p", [], [], 'do_p]>, "To setup an internet list in this way, simply set this setting to be the internet list address, and also subscribe the SMTP name for the ColdCore list (list-<name>@domain) to the internet list. For this to work as an internet list hook, you must also setup SMTP forwarding from your operating system, or bind the SMTP port directly to port 25. More information on this can be found at: ", <$format, ["web", [["src", "http://www.cold.org/sitenames.html"]], ["Sitenames"], 'do_web]>, ".", <$format, ["p", [], [], 'do_p]>, "This setting can only be set by administrators, look for a mail-forward setting in the future, which will have configurable access restrictions."], #[]]>;
var $root inited = 1;
var $root managed = [$help_obj_mail_list];


new object $help_obj_float: $help_obj;

var $root manager = $help_obj_float;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 910069163;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Float", "Float"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [["ind", "8"]], [<$format, ["dt", [], [".", <$format, ["method", [["float.ceiling", 1]], ["ceiling"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method calculates the ceiling of the floating point value. The ceiling is the next largest integer, so the ceiling of 5.4 is 6.0."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.floor", 1]], ["floor"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method calculates the floor of the floating point value ", <$format, ["var", [], ["float"], 'do_var]>, ". The floor is the next smallest integer, so the floor of 5.4 is 5.0."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.round", 1]], ["round"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method returns the rounded off value of ", <$format, ["var", [], ["float"], 'do_var]>, " to the nearest integral value."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.round_to", 1]], ["round_to"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ", ", <$format, ["var", [], ["places"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method rounds the value ", <$format, ["var", [], ["float"], 'do_var]>, " off to the given number of places as specified by the argument ", <$format, ["var", [], ["places"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.fractional_part", 1]], ["fractional_part"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method returns the fractional part of a floating point value. The result for 1.234 would be 0.234. The value will always be positive."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.to_integer", 1]], ["to_integer"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method returns the integral value of a floating point number."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.log", 1]], ["log"], 'do_method]>, "(", <$format, ["var", [], ["base"], 'do_var]>, ", ", <$format, ["var", [], ["value"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given a base, ", <$format, ["var", [], ["base"], 'do_var]>, ", and a value, ", <$format, ["var", [], ["value"], 'do_var]>, ", this method returns the log of the value in the given base."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_obj_float];


new object $help_sys: $help_core;

var $root manager = $help_sys;
var $help_node nolist = 1;
var $root flags = ['variables, 'methods, 'code, 'core, 'fertile];
var $root created_on = 870556878;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Subsystems", "Subsystems"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[]]>;
var $root inited = 1;
var $help_node group = 1;
var $root managed = [$help_sys];


new object $help_sys_events: $help_sys;

var $root manager = $help_sys_events;
var $help_node index = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850790348;
var $has_name name = ['prop, "Events", "Events"];
var $help_node links = #[["Registering", $help_sys_event_register], ["Hooking", $help_sys_event_hook], ["Sending", $help_sys_event_send], ["Receiving", $help_sys_event_recv]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The Event System allows objects to be notified of changes in their environment. They do this by selectively hooking into known events, such as movement and social interaction events. When the event occurs all objects which have hooked into it will be notified. ", <$format, ["np", [], [], 'do_np]>, "The Event System is actually several subsystems all handled through the same parent object--this will often cause confusion. In general, the only subsystem most people will be interested with is the Registering ability of hooks. However, all of the subsystems are: Registering, Hooking, Sending/Receiving. ", <$format, ["np", [], [], 'do_np]>, "The Registering subsystem allows an object to register an event hook along with when it should be turned on/off and when it should be updated (such as when the object is moved). The Hooking subsystem deals with whether the object receives an event or not (the object must be hooked into an event to receive it). The Sending/Receiving subsystem deals with the initial and final stages of sending and receiving events. In general, a programmer is only interested in the Registering and Sending/Receiving subsystems (as Hooking is handled automatically once an event is Registered). ", <$format, ["np", [], [], 'do_np]>, "See Also:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_sys_event_register"]], ["Registering"], 'do_link]>, " Events"], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_sys_event_hook"]], ["Hooking"], 'do_link]>, " Events"], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_sys_event_send"]], ["Sending"], 'do_link]>, " Events"], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_sys_event_recv"]], ["Receiving"], 'do_link]>, " Events"], 'do_li]>], 'do_ul]>], #[['links, #[["Registering", "$help_sys_event_register"], ["Hooking", "$help_sys_event_hook"], ["Sending", "$help_sys_event_send"], ["Receiving", "$help_sys_event_recv"]]]]]>;
var $root inited = 1;
var $help_node group = 1;
var $root managed = [$help_sys_events];
var $help_node nolist = 0;


new object $help_sys_event_register: $help_sys_events;

var $root manager = $help_sys_event_register;
var $root managed = [$help_sys_event_register];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 864944385;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Registering", "Registering"];
var $help_node links = #[["Sending Events", $help_sys_event_send]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The Registering subsystem allows an object to register an event hook along with when it should be turned on/off and when it should be updated (such as when the object is moved). Events are registered with the Event to Hook, when to Hook it and where to Hook it at (relay). ", <$format, ["np", [], [], 'do_np]>, "The event to hook can be any symbol that represents an event. An event type is created by simply sending it, so there is no registration or initialization involved in creating a new event (see ", <$format, ["link", [["node", "$help_sys_event_send"]], ["Sending Events"], 'do_link]>, " for more information) ", <$format, ["np", [], [], 'do_np]>, "When to hook the event can currently be either at startup, or when the object is moved. The symbols ", <$format, ["tt", [], ["'startup"], 'do_tt]>, " or ", <$format, ["tt", [], ["'move"], 'do_tt]>, " are sent to specify this. ", <$format, ["np", [], [], 'do_np]>, "The relay for the event, or where you hook into it at (see ", <$format, ["link", [["node", "$help_sys_event_send"]], ["Sending Events"], 'do_link]>, " for more information on event relay's) must be one of: ", <$format, ["tt", [], ["'location"], 'do_tt]>, ", ", <$format, ["tt", [], ["'this"], 'do_tt]>, " or an object which is a descendant of ", <$format, ["tt", [], ["$event_handler"], 'do_tt]>, ". If ", <$format, ["tt", [], ["'location"], 'do_tt]>, " is set as the source, the object's current location is used for the event relay. If ", <$format, ["tt", [], ["'this"], 'do_tt]>, " is used as the source, the object itself is used for the relay. ", <$format, ["np", [], [], 'do_np]>, "The methods used for Registering are:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["event_handler.register_event", 1]], ["register_event"], 'do_method]>, "(", <$format, ["i", [], ["event"], 'do_i]>, ", ", <$format, ["i", [], ["when"], 'do_i]>, ", ", <$format, ["i", [], ["relay"], 'do_i]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Used to register an event hook. You should only need to call this method once in the life of an object, unless it is unregistered later."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["event_handler.deregister_event", 1]], ["deregister_event"], 'do_method]>, "(", <$format, ["i", [], ["event"], 'do_i]>, ", ", <$format, ["i", [], ["when"], 'do_i]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Used to de-register an event hook."], 'do_dd]>], 'do_dl]>], #[['links, #[["Sending Events", "$help_sys_event_send"]]]]]>;
var $root inited = 1;


new object $help_sys_event_hook: $help_sys_events;

var $root manager = $help_sys_event_hook;
var $root managed = [$help_sys_event_hook];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 864944385;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Hooks", "Hooks"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[]]>;
var $root inited = 1;


new object $help_sys_event_send: $help_sys_events;

var $root manager = $help_sys_event_send;
var $root managed = [$help_sys_event_send];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 864944385;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Sending", "Sending"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Sending events is quite simple, from a programming point of view. There is no registration or initialization involved in creating an event--they exist as they are sent. ", <$format, ["np", [], [], 'do_np]>, "The method used to Send an Event is:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], ["relay.", <$format, ["method", [["event_handler.send_event", 1]], ["send_event"], 'do_method]>, "(", <$format, ["i", [], ["event"], 'do_i]>, ", ", <$format, ["i", [], ["@args"], 'do_i]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Used to send an event. The object ", <$format, ["tt", [], ["relay"], 'do_tt]>, " is the broadcaster of the event (usually the current object's location). Any arguments beyond the event name are sent to the receiving event handler."], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "An example sending the event ", <$format, ["tt", [], ["'combat"], 'do_tt]>, " to the current object's location:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [".location().send_event('combat, target_obj, with_weapon)"], 'do_dfn]>], #[]]>;
var $root inited = 1;


new object $help_sys_event_recv: $help_sys_events;

var $root manager = $help_sys_event_recv;
var $root managed = [$help_sys_event_recv];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 864944385;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Receiving", "Receiving"];
var $help_node links = #[["Sending Events", $help_sys_event_send]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Events are received through the following method:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], [".event_notify(event, obj, @args)"], 'do_dt]>, <$format, ["dd", [], ["Receive an event caused by 'obj'."], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "The ", <$format, ["tt", [], ["event"], 'do_tt]>, " argument is the name of the event. The ", <$format, ["tt", [], ["obj"], 'do_tt]>, " argument is the object which caused the event, any subsequent arguments are those sent to ", <$format, ["tt", [], [".send_event()"], 'do_tt]>, ", which is explained in the section ", <$format, ["link", [["node", "help_sys_event_send"]], ["Sending Events"], 'do_link]>, "."], #[['links, #[["Sending Events", "help_sys_event_send"]]]]]>;
var $root inited = 1;


new object $help_sys_editor: $help_sys;

var $root manager = $help_sys_editor;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 840585945;
var $has_name name = ['prop, "Editor", "Editor"];
var $help_node links = #[["Invoking", $help_node_editor_invoking], ["Commands", $help_node_editor_commands], ["Programming", $help_node_editor_programming]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ColdCore Editor is an integrated system, giving the ability to to edit methods or other data through a builtin line editor or by using your own local editor through MCP. Local editing is controlled through the local-editor setting (it can be set to either ", <$format, ["tt", [], ["none"], 'do_tt]>, " or ", <$format, ["tt", [], ["mcp"], 'do_tt]>, ", such as: ", <$format, ["tt", [], ["@set local-editor=mcp"], 'do_tt]>, "). Each user may have multiple editor sessions. Any coldcore system can create editor session for a user.", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["link", [["node", "$help_node_editor_invoking"]], ["Invoking"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Comamnds used to invoke the editor"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_node_editor_commands"]], ["Commands"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Editor commands"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_node_editor_programming"]], ["Programming"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Editor: The Programmer's view"], 'do_dd]>], 'do_dl]>], #[['this, $help_sys_editor]]]>;
var $root inited = 1;
var $root managed = [$help_sys_editor];
var $help_node index = $help_index_subsystem;
var $help_node nolist = 0;
var $help_node group = 1;


new object $help_node_editor_invoking: $help_sys_editor;

var $root manager = $help_node_editor_invoking;
var $root managed = [$help_node_editor_invoking];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 840586820;
var $has_name name = ['prop, "Invoking", "Invoking"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["@edit"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["List all editor sessions."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["@edit %<x>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Resume background session, where <x> is the session to resume (as listed in the session list)"], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["@edit object.method"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Create a new session with the specified method."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["@edit object [+t?ype=method]"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Edit data on the object. Type specifies what data (typical values: prose, text, messages or help). Without +t, a reasonable default is chosen."], 'do_dd]>], 'do_dl]>], #[['this, $help_node_editor_invoking]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_node_editor_commands: $help_sys_editor;

var $root manager = $help_node_editor_commands;
var $root managed = [$help_node_editor_commands];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 840586826;
var $has_name name = ['prop, "Commands", "Commands"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["a?fter [<text>] OR _<text>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Add <text> after current line. You may also use an underscore (_) as a shortcut character. If text does not exist you will be prompted for the input."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["ap?pend <text> OR ,<text>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Add <text> after current line. You may also use a comma (,) as a shortcut character."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["copy [<range>] [to] <line>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Copy <range> of text or current line to <line>."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["d?elete [<range>]"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Delete <range> or current line."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["done|quit"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Close editor without saving changes."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["fill <range> <line width>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Fill <range> of lines to fit within <line width> appropriately (either by expanding or joining)."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["help [<command>]"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Basic editor help."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["i?nsert [<text>] OR '<text>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Add <text> before current line. You may also use a single-quote (') as a shortcut character. If text does not exist you will be prompted for the input."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["list [<range>] [-n?umbers]"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["List <range> or all of edit buffer. The option -n?umbers may be used to not specify line numbers."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["line <line>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Change the current line to <line>. You can also use a period (.) as a shortcut character."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["move [<range>] [to] <line>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Move <range> or current line to <line>."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["save|comp?ile [as] [<ref>]"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Save document, if arguments are given will save alternate copy."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["s?ub|sed <old> <new> [<range>] [<options>]"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Search for <old> and replace it with <new> in <range> (defaulting to the current line). The character following the command is used as a seperator (a space in the example). This allows for the sed-like syntax: s/old/new/. The command 'sed' will use strsed() with regular expressions, the command 'sub' or 's' will use strsub() with literal matching. Options are any one of:", <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "g Globally match and replace (do it multiple times)", <$format, ["p", [], [], 'do_p]>, "s Single match and replace (do it only on the first occurance)", <$format, ["p", [], [], 'do_p]>, "c Case matters when matching.", <$format, ["p", [], [], 'do_p]>, "i Case doesn't matter when matching.", <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "Option defaults for sed are: si", <$format, ["p", [], [], 'do_p]>, "Option defaults for sub are: gi"], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["send|mail <mail-recipient>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Used to send current contents of editor to a mail recipient."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["store"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Store editor--do not save changes. Editor can be resumed with @edit %0."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $help_node nolist = 0;

public method .generate_body() {
    var helps, h, cmds, c, out, syn;
    
    (sender() == $editor_parser) || (> .perms(sender()) <);
    helps = $editor_parser.command_help();
    cmds = $editor_parser.commands();
    out = "{dl:";
    for c in ((cmds.keys()).sort()) {
        refresh();
        h = helps[cmds[c]];
        syn = strsed(h[1], "Syntax: *", "");
        if ((h[2]) == "")
            h = sublist(h, 3).join("{p}");
        else
            h = sublist(h, 2).join("{p}");
        syn = strsub(syn, "[", "\[");
        syn = strsub(syn, "]", "\]");
        out += ((("{dt:{subj level=3:{tt:" + syn) + "}}}{dd:") + h) + "}";
    }
    .set_body(out + "}");
};


new object $help_node_editor_programming: $help_sys_editor;

var $root manager = $help_node_editor_programming;
var $root managed = [$help_node_editor_programming];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 840586832;
var $has_name name = ['prop, "Programming", "Programming"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["subj", [["level", "3"]], ["Glosary"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], ["Server-side edit"], 'do_dt]>, <$format, ["dd", [], ["The editor mode in which @edit command throws the user into the line editor built into the server."], 'do_dd]>, <$format, ["dt", [], ["Local edit"], 'do_dt]>, <$format, ["dd", [], ["Editor mode in which @edit downloads the text to the user, returns the user to normal work, and processes the text upload as it arrives."], 'do_dd]>, <$format, ["dt", [], ["Callback"], 'do_dt]>, <$format, ["dd", [], [<$format, ["tt", [], ["save"], 'do_tt]>, " command in the server edit, or upload in the local edit, will call a function that knows how to deal with the text. The function (and its extra arguments) are passed to the editor when it's started. Callback function expects two arguments, ", <$format, ["tt", [], ["text"], 'do_tt]>, " and ", <$format, ["tt", [], ["client_data"], 'do_tt]>, ", the first is the text upload, and the other is a list passed to the editor when it was run."], 'do_dd]>], 'do_dl]>, <$format, ["subj", [["level", "3"]], ["Editor objects"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], ["$editor_reference"], 'do_dt]>, <$format, ["dd", [], ["A parent to ", <$format, ["tt", [], ["$user"], 'do_tt]>, ", containing the invocation commands, a list of background editors and the foreground editor."], 'do_dd]>, <$format, ["dt", [], ["$editor_parser"], 'do_dt]>, <$format, ["dd", [], ["Editor command parser. Added to the list of $user's parsers to switch the command context for server editting."], 'do_dd]>, <$format, ["dt", [], ["$editor_session"], 'do_dt]>, <$format, ["dd", [], ["This object is spawned for each individual session. It contains all the data for the session: callback method and arguments, modification flag, cursor position and (for server edit) the text itself. It also runs the editor commands (for server edit). For the local edit, it main purpose is keeping track of the callbacks."], 'do_dd]>, <$format, ["dt", [], ["$editable"], 'do_dt]>, <$format, ["dd", [], ["This is a generic parent that keeps track of the datatype that an object may hold (with @edit object +type=<something> command)"], 'do_dd]>], 'do_dl]>, <$format, ["subj", [["level", "3"]], ["Calling the editor"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "The editor is called by running ", <$format, ["tt", [], ["user.invoke_editor(callback_object, callback_method, initial_text, client_data)"], 'do_tt]>, ", where ", <$format, ["tt", [], ["callback_object"], 'do_tt]>, " and ", <$format, ["tt", [], ["callback_method"], 'do_tt]>, " specify the callback, ", <$format, ["tt", [], ["initial_text"], 'do_tt]>, " is the text to be edited, and ", <$format, ["tt", [], ["client_data"], 'do_tt]>, " will be passed to the callback as additional arguments.", <$format, ["p", [], [], 'do_p]>, <$format, ["subj", [["level", "3"]], ["Extending @edit types"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "To add a new editable type to an object, first make sure that the object has $editable among its ancestors. Then do ", <$format, ["tt", [], ["object.set_edit_type([ list of types ])"], 'do_tt]>, ". For each type, define object.edit_<type> method, and the callback for the method. You're done!"], #[['this, $help_node_editor_programming]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_sys_channels: $help_sys;

var $root manager = $help_sys_channels;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 840768823;
var $has_name name = ['prop, "Channels", "Channels"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["Channels are a global way to communicate with other users. Commands available for using channels:", <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["@addcom <alias>=<channel>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Adds a channel alias to a channel <channel>. Provides a shortcut way of referring to a channel. For example, typing '@addcom pub=Public' will create a shortcut called 'pub' which refers to the [Public] channel."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["@delcom <alias>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["@delcom <alias> deletes your alias for the given channel."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["@channels"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Show all of the channel aliases and their channels you have defined (this list is only applicable to you)."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["<channel alias> <msg>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Used to speak on a channel. If the channel [Public] has the alias 'pub', you can send a message to it with the command 'pub Hi!'. Similarly, emotes work as well with 'pub :waves'"], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["<channel alias> on"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Used to turn on a channel. Typing '<alias> on' will turn on the channel specified by <alias>, such as 'pub'. When a channel is turned on, you listen and receive messages from anyone chantting on that channel."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["<channel alias> off"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Used to leave a channel."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["<channel alias> who"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Used to determine who is listening to a given channel. Typing '<alias> who' will provide a listing of users currently listening. For example, 'pub who' will list the users chatting or idling on the public channel, from the example above."], 'do_dd]>], 'do_dl]>], #[['this, $help_sys_channels]]]>;
var $root inited = 1;
var $root managed = [$help_sys_channels];
var $help_node index = $help_index_subsystem;
var $help_node nolist = 0;
var $help_node group = 1;


new object $help_sys_message: $help_sys;

var $root manager = $help_sys_message;
var $help_node index = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856117169;
var $root managed = [$help_sys_message];
var $has_name name = ['prop, "Messages", "Messages"];
var $help_node links = #[["Setting Messages", $help_cmd_msg], ["Defining Messages", $help_cmd_defmsg], ["ColdC Message Interface", $help_msg_coldc], ["Message Propagation", $help_msg_prop]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The message system is used to group several different Ctext messages under a specific message type for single evaluation. A message is composed of a base and any number of branches. The branches define each specific variation on the message, such as with teleport messages--there is the actor's message, the source message and the destination message. This message's base is \"teleport\" with the branches of \"actor\", \"source\" and \"dest\". By default if no branch is specified, the \"general\" branch is used instead (so referencing a message with no branch, and with the \"general\" branch are equivalent).", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_cmd_msg"]], ["Setting Messages"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_cmd_defmsg"]], ["Defining Messages"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_msg_coldc"]], ["ColdC Message Interface"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_msg_prop"]], ["Message Propagation"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['links, #[["Setting Messages", "$help_cmd_msg"], ["Defining Messages", "$help_cmd_defmsg"], ["ColdC Message Interface", "$help_msg_coldc"], ["Message Propagation", "$help_msg_prop"]]]]]>;
var $root inited = 1;
var $help_node group = 1;


new object $help_cmd_defmsg: $help_sys_message;

var $root manager = $help_cmd_defmsg;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856118984;
var $root managed = [$help_cmd_defmsg];
var $has_name name = ['prop, "@def-msg|@undef-msg", "@def-msg|@undef-msg"];
var $help_node links = #[["@msg", $help_cmd_msg], ["Messages", $help_sys_message]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: `", <$format, ["tt", [], ["@def-msg|@undef-msg <target>:<msg> [options]"], 'do_tt]>, "` ", <$format, ["np", [], [], 'do_np]>, "This command is used to define and undefine a message base. Because multiple branches for one base can exist, you cannot define the default values for the message with this command, use ", <$format, ["link", [["node", "$help_cmd_msg"]], ["@msg"], 'do_link]>, " for this instead, after the message is defined. More information on Messages can be found in the section ", <$format, ["link", [["node", "$help_sys_message"]], ["Messages"], 'do_link]>, ". Options can be: ", <$format, ["dfn", [["nobound", 1]], [<$format, ["table", [["cols", "25%,75%"]], [<$format, ["tr", [], [<$format, ["td", [], ["+b?ranches"], 'do_td]>, <$format, ["td", [], ["Define the branches, in a comma delimited list."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["+c?ompiler"], 'do_td]>, <$format, ["td", [], ["Define the compiler. Defaults to $compiler."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["+e?valuator"], 'do_td]>, <$format, ["td", [], ["Define the evaluator. Defaults to $bs_eval."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["+g?etter"], 'do_td]>, <$format, ["td", [], ["Define the getter. Defaults to 'standard_get_msg"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "An example of defining the message \"open\" with the branches \"actor\" and \"general\":", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@def-msg mybox:open +b=general,actor", <$format, ["br", [], [], 'do_br]>, "@msg mybox:open = General Message", <$format, ["br", [], [], 'do_br]>, "@msg mybox:open.actor = Actor's Message"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "You can also specify a two-part branch, with the final part being variable. What this means is the third part of the message name can be variable, and when the message is evaluated the appropriate branch will be used--if it exists. For instance, the message ", <$format, ["tt", [], ["\"invoke\""], 'do_tt]>, " on ", <$format, ["tt", [], ["$path"], 'do_tt]>, " has the branch ", <$format, ["tt", [], ["\"source\""], 'do_tt]>, " which is variable--meaning you add a third part to it. In this example the third part is a way for the path--i.e. one of its sources or destinations. So a possible message set for this would look like:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["invoke.source = [actor] goes through [this].", <$format, ["br", [], [], 'do_br]>, "invoke.source.courtyard = [actor] leaves the courtyard."], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In this example, the default 'source' is used for all messages unless the source is the courtyard, when the second message is used instead. ", <$format, ["np", [], [], 'do_np]>, "Variable messages are specified when defining the branches--in one of two wa ys. Either an asterisk character is placed where the variable portion should be, or a unique token specified in parenthesis is placed there, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["invoke.actor.($source)"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If no token is specified, then a dollar sign followed by the branch name is used instead. When evaluating the message the interpreter will look for a ctext variable by that name. If it exists, it will build a branch using the objname of the value of that variable, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["source.place_621"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If this branch is defined, then it will use it instead of the default branch."], #[['links, #[["@msg", "$help_cmd_msg"], ["Messages", "$help_sys_message"]]]]]>;
var $root inited = 1;


new object $help_msg_coldc: $help_sys_message;

var $root manager = $help_msg_coldc;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856117601;
var $root managed = [$help_msg_coldc];
var $has_name name = ['prop, "ColdC Interface", "ColdC Interface"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The message subsystem is contained on the $foundation object. It uses two object variables: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "25%,75%"]], [<$format, ["tr", [], [<$format, ["td", [], [",msgs"], 'do_td]>, <$format, ["td", [], ["Local instances of a defined message"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [",defined_msgs"], 'do_td]>, <$format, ["td", [], ["Defined messages and attributes"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "And the following methods:", <$format, ["dl", [], [<$format, ["dt", [], [".", <$format, ["method", [["foundation.defined_msgs", 1]], ["defined_msgs"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns the defined_msgs variable from the current object."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["foundation.all_defined_msgs", 1]], ["all_defined_msgs"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns all messages defined by the current object and all ancestors up to $foundation."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["foundation.msgs", 1]], ["msgs"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns any local messages instances."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["foundation.all_msgs", 1]], ["all_msgs"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns all messages and instances, local or default."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["foundation.define_msg", 1]], ["define_msg"], 'do_method]>, "(", <$format, ["var", [], ["name"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Define a new message."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["foundation.undefine_msg", 1]], ["undefine_msg"], 'do_method]>, "(", <$format, ["var", [], ["name"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Undefine a message (will clear any instances)."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["foundation.get_msg", 1]], ["get_msg"], 'do_method]>, "(", <$format, ["var", [], ["name"], 'do_var]>, ", ", <$format, ["var", [], ["definer"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Get all branches (local or default) of the message."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["foundation.set_msg", 1]], ["set_msg"], 'do_method]>, "(", <$format, ["var", [], ["name"], 'do_var]>, ", ", <$format, ["var", [], ["branch"], 'do_var]>, ", ", <$format, ["var", [], ["definer"], 'do_var]>, ", ", <$format, ["var", [], ["value"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Set the value of a branch of a message."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["foundation.clear_msg", 1]], ["clear_msg"], 'do_method]>, "(", <$format, ["var", [], ["name"], 'do_var]>, ", [", <$format, ["var", [], ["branches"], 'do_var]>, "])"], 'do_dt]>, <$format, ["dd", [], ["Clear the local instance and branches of a message. If no branches are defined all branches are cleared."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["foundation.get_msg_attr", 1]], ["get_msg_attr"], 'do_method]>, "(", <$format, ["var", [], ["name"], 'do_var]>, ", ", <$format, ["var", [], ["attr"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Get the specified attribute for a message."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["foundation.set_msg_attr", 1]], ["set_msg_attr"], 'do_method]>, "(", <$format, ["var", [], ["name"], 'do_var]>, ", ", <$format, ["var", [], ["attr"], 'do_var]>, ", ", <$format, ["var", [], ["value"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Set the specified attribute for a message."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["foundation.msg_definer", 1]], ["msg_definer"], 'do_method]>, "(", <$format, ["var", [], ["name"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Determine the definer for a message."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["foundation.get_default_msg", 1]], ["get_default_msg"], 'do_method]>, "(", <$format, ["var", [], ["name"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Get the default branches for a message."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["foundation.eval_message", 1]], ["eval_message"], 'do_method]>, "(", <$format, ["var", [], ["name"], 'do_var]>, ", ", <$format, ["var", [], ["definer"], 'do_var]>, ", ", <$format, ["var", [], ["vars"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Evaluate a message"], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;


new object $help_cmd_msg: $help_sys_message;

var $root manager = $help_cmd_msg;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856117601;
var $root managed = [$help_cmd_msg];
var $has_name name = ['prop, "@msg", "@msg"];
var $help_node links = #[["CML", $help_cml]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: `", <$format, ["tt", [], ["@msg|@message [-clear] [<target>:][<msg>=<value>]"], 'do_tt]>, "` ", <$format, ["np", [], [], 'do_np]>, "You can view and set messages with this command. When no message is given (and only the target is specified) it will list all messages on the target object. If no target is specified, the target will default to the current object. If a message and value is specified, it will set the value as appropriate. The value is be written in ", <$format, ["link", [["node", "$help_cml"]], ["CML"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "If the message is undefined on an object, it will default to the value given on the defining object. To revert a message back to the default value use the -clear option, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@msg -clear teleport.actor"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Some examples of setting and viewing messages:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> @msg", <$format, ["br", [], [], 'do_br]>, "-- Messages on Brandon ($brandon):", <$format, ["br", [], [], 'do_br]>, "teleport.actor = You teleport to [dest].", <$format, ["br", [], [], 'do_br]>, "teleport.dest = [actor] teleports here from [source].", <$format, ["br", [], [], 'do_br]>, "teleport.source = [actor] teleports to [dest]."], 'do_dfn]>, " ", <$format, ["dfn", [], ["> @msg north:invoke.actor=You walk up [exit].", <$format, ["br", [], [], 'do_br]>, "-- Message changed to:", <$format, ["br", [], [], 'do_br]>, "invoke.actor = You walk up [exit]."], 'do_dfn]>], #[['this, $help_cmd_msg]]]>;
var $root inited = 1;


new object $help_msg_prop: $help_sys_message;

var $root manager = $help_msg_prop;
var $help_node index = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863604499;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Message Propagation", "Message Propagation"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Messages can be propagated - i.e. transmitted through objects that partially garble or mute parts of the message. Each message has 'senses' associated with it - audibility, visibility, smell, and so on. A rule of the thumb would be that 0 is imperceptible, 10 is average, 20 corresponds to atomic blast, in every way. Propagating the message lowers the sense values, and can modify the text of the message. Once all the message's sense values are lowered below zero, it will stop propagating. ", <$format, ["np", [], [], 'do_np]>, "The general syntax of the message propagators is as follows: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\n\nsense=value; sense=value; ... [/prefix or effect]"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["np", [], [], 'do_np]>, "In the above, each sense will be decreased by given value after the propagation. Senses that aren't mentioned in the propagator specification are not propagated (use any=value to override this). Prefix, if specified, will be prepended to the message. Alternatively, specifying it as ", <$format, ["quote", [], ["/.method_name"], 'do_quote]>, " will call a method from $propagator_effects, allowing more thorough modification of the text. ", <$format, ["np", [], [], 'do_np]>, "Within message, {sense:name} will return the value of the sense, as perceived by the player. Combined with {switch}, this can be used for gradual garbling of the information the player receives."], #[]]>;
var $root inited = 1;
var $root managed = [$help_msg_prop];


new object $help_sys_word: $help_sys;

var $root manager = $help_sys_word;
var $help_node index = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856384074;
var $root managed = [$help_sys_word];
var $has_name name = ['prop, "Word Generator", "Word Generator"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "This random word generator uses syllables and word patterns, and is inspired by a similar generator written by Ross Smith (Infact, the Lovecraftian dictionary came from his generator). ", <$format, ["np", [], [], 'do_np]>, "The generator uses different patterns to generate the word, where each pattern has a chance of being chosen. First is the number of syllables in a word. Once the syllables are chosen a syllable pattern is selected for each syllable. From the syllable pattern vowel or consanant patterns are chosen. It is possible to use two dictionaries for consanants, so as to have 'first' and 'last' consanant patterns. The syllable pattern must be composed of either V (vowel), C (consanant), or LC (last consanant) tokens seperated by dashes, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["C-V-LC"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Which would imply the syllable pattern of a Consanant-Vowel-Last Consanant. ", <$format, ["np", [], [], 'do_np]>, "The various patterns are defined by submitting a configuration to the word generator object (spawn $word for your own generator). This can be done with the simple evaluation command (which will prompt you for the configuration lines):", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [";$my_word.submit_chances(.read())"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "You can also list the configuration with:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [";.tell($my_word.format_chances())"], 'do_dfn]>, " ", <$format, ["subj", [["level", "3"]], ["Configuration"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "The configuration takes one pattern and chance per line, with an optional comment character of \"#\" which is discarded. The pattern must begin with a directive designating the pattern. Directives can be any of: ", <$format, ["dfn", [["ind", "4"], ["nobound", 1]], [<$format, ["table", [["cols", "10%,90%"]], [<$format, ["tr", [], [<$format, ["td", [], ["S"], 'do_td]>, <$format, ["td", [], ["Number of Syllables"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["SP"], 'do_td]>, <$format, ["td", [], ["Syllable Patterns"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["C"], 'do_td]>, <$format, ["td", [], ["Consanants"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["LC"], 'do_td]>, <$format, ["td", [], ["Last Consanants"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["V"], 'do_td]>, <$format, ["td", [], ["Vowels"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "There is no limit to the amount of patterns submitted. A very simple configuration would be: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\nS 2 3\nS 3 1\n\nSP V 2\nSP V-C 4\nSP C-V 2\n\nV a 10\nV e 10\nV i 10\n\nFC th 1\nFC b 4\nFC f 4\nFC qu 1\n\nLC bh 1\nLC d 4\nLC b 4"], 'do_quote]>], 'do_dfn]>], #[['this, $help_sys_word]]]>;
var $root inited = 1;
var $help_node nolist = 0;
var $help_node group = 1;


new object $help_ranges: $help_sys;

var $root manager = $help_ranges;
var $help_node index = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 865132499;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Ranges", "Ranges"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Ranges are used to specify a set of numbers to identify which part of a set is the target of the operation. ", <$format, ["np", [], [], 'do_np]>, "They are relatively simple, with a few special identifiers with significant meaning.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["<begin>-<end>"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, <$format, ["tt", [], ["<begin>"], 'do_tt]>, " specifies where the range should begin and will be either a number or one of the special identifiers. ", <$format, ["tt", [], ["<end>"], 'do_tt]>, " specifies the end of the range and again, will be either a number of one of the special identifiers.", <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], ["Special Identifiers: ", <$format, ["dt", [], [<$format, ["tt", [], ["'^'"], 'do_tt]>], 'do_dt]>, <$format, ["dd", [], ["First item"], 'do_dd]>, <$format, ["dt", [], [<$format, ["tt", [], ["'.'"], 'do_tt]>], 'do_dt]>, <$format, ["dd", [], ["Current position"], 'do_dd]>, <$format, ["dt", [], [<$format, ["tt", [], ["'$'"], 'do_tt]>], 'do_dt]>, <$format, ["dd", [], ["Last item"], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_ranges];
var $help_node group = 1;


new object $help_sys_bad_commands: $help_sys;

var $root manager = $help_sys_bad_commands;
var $help_node index = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 870917437;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Bad Commands", "Bad Commands"];
var $help_node links = #[["channel", $help_sys_channels], ["@new", $help_cmd_new], ["@spawn", $help_cmd_spawn], ["@set", $help_cmd_set], ["@page", $help_cmd_page]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A number of other systems commonly use commands which do not fit into the command layout that ColdCore uses, therefore, these commands are handled by a special method that informs the player that these commands have changed. The current commands that have been listed as bad commands are: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "30%,70%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["Bad Command"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["New Command"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+com"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["<", <$format, ["link", [["node", "$help_sys_channels"]], ["channel"], 'do_link]>, " alias> on|off|who|<message>"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["@alias"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["@add-name-alias|@add-command-alias"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["@check|@paranoid"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["@monitor"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["@create"], 'do_tt]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_cmd_new"]], ["@new"], 'do_link]>, "|", <$format, ["link", [["node", "$help_cmd_spawn"]], ["@spawn"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["@gender"], 'do_tt]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_cmd_set"]], ["@set"], 'do_link]>, " gender = male|female|neuter"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["@lock"], 'do_tt]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_cmd_set"]], ["@set"], 'do_link]>, " <objref>:lock = <lock>"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["@unlock"], 'do_tt]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_cmd_set"]], ["@set"], 'do_link]>, " <objref>:lock = "], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["@version"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["@status"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["news"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["@news"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["page"], 'do_tt]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_cmd_page"]], ["@page"], 'do_link]>, " <player> with <message>"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["quit"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["@quit"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["uptime"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["@status"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["who"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["@who"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["channel", "$help_sys_channels"], ["@new", "$help_cmd_new"], ["@spawn", "$help_cmd_spawn"], ["@set", "$help_cmd_set"], ["@page", "$help_cmd_page"]]]]]>;
var $root inited = 1;
var $root managed = [$help_sys_bad_commands];


new object $help_sys_parser: $help_sys;

var $root manager = $help_sys_parser;
var $help_node index = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 887832194;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Command Parsing System|Command Parser", "Command Parsing System|Command Parser"];
var $help_node links = #[["Command Caches", $help_obj_command_cache], ["Command Modules", $help_parser_command_modules]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Brandon still has to write this. For now, reference:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "help_obj_command_cache"]], ["Command Caches"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "help_parser_command_modules"]], ["Command Modules"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['links, #[["Command Caches", "help_obj_command_cache"], ["Command Modules", "help_parser_command_modules"]]]]]>;
var $root inited = 1;
var $root managed = [$help_sys_parser];


new object $help_obj_command_cache: $help_sys_parser;

var $root manager = $help_obj_command_cache;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 887836027;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Command Cache", "Command Cache"];
var $help_node links = #[["Creation and Destruction Methods", $help_obj_command_cache_dmeths], ["Cache Server Methods", $help_obj_command_cache_smeths], ["Cache Client Methods", $help_obj_command_cache_cmeths]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The $command_cache object is broken into two roles--caching commands, and interfacing the cache for commands (this primarily involves looking up commands in the cache)--or from another viewpoint, the Cache Server and Cache Client (respectively). While any object will always cache its own locally defined commands (those immedately defined on itself), an object has to be specially marked to cache all commands on itself and its ancestors. These objects are generally the parent class for users. Most other objects (primarily Command Modules) should only have locally defined commands. ", <$format, ["subj", [["level", "2"]], ["Cache Server"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "If an object is a Cache Server, it will also fall into one of two Cache Server categories. EIther it is a cache for its own commands (a Local Cache), or it is a cache for all commands defined on its ancestors and itself (a General Cache). ", <$format, ["np", [], [], 'do_np]>, "The default behavior of a Cache Server is as a Local Cache. To configure an object as a General Cache, simply add the flag 'general_cache to the object, using the command @chmod:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@chmod +general_cache $new_cache_server"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Keep in mind, an object only needs to be marked as a general cache if it needs to cache not only its own commands, but also those commands defined on its ancestors. This is generally not the case. ", <$format, ["subj", [["level", "2"]], ["Cache Client"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "A cache client will lookup commands on all of its parents--which should be defined as General Caches, and on any of its Command Modules. Command Modules are objects which group a set of commands, allowing people to add or remove entire sets of commands, depending upon the interface they desire. ", <$format, ["subj", [["level", "2"]], ["Remote Command Cache"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "An additional cache has been created that is not intended for use as an ancestor. Instead, it is intended as the general repository for all remote commands. It behaves slightly different than standard caches, and plays the role as both the client and server for itself. ", <$format, ["subj", [["level", "2"]], ["Method Definitions"], 'do_subj]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_obj_command_cache_dmeths"]], ["Creation and Destruction Methods"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_obj_command_cache_smeths"]], ["Cache Server Methods"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_obj_command_cache_cmeths"]], ["Cache Client Methods"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['links, #[["Creation and Destruction Methods", "$help_obj_command_cache_dmeths"], ["Cache Server Methods", "$help_obj_command_cache_smeths"], ["Cache Client Methods", "$help_obj_command_cache_cmeths"]]]]]>;
var $root inited = 1;
var $root managed = [$help_obj_command_cache];


new object $help_obj_command_cache_smeths: $help_obj_command_cache;

var $root manager = $help_obj_command_cache_smeths;
var $root managed = [$help_obj_command_cache_smeths];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 887946512;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Server Methods", "Server Methods"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [["ind", "8"]], [<$format, ["dt", [], [".", <$format, ["method", [["command_cache.cache_server_init", 1]], ["cache_server_init"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Called by cache clients to notify prepare the server for use. MUST be called before a server will function (and is called automatically when the client starts)."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.cache_server_uninit", 1]], ["cache_server_uninit"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Notifies the cache that one of its clients is going away. The server will do a cursory check and may purge its cache if it determines it is no longer needed."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.is_general_cache", 1]], ["is_general_cache"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns true if the server is configured as a General Cache."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.purge_cache", 1]], ["purge_cache"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Clears the command (and shortcut) cache."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.rehash_cache", 1]], ["rehash_cache"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Builds the command (and shortcut) cache."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.add_object_to_cache", 1]], ["add_object_to_cache"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Adds all commands defined on an object to the cache."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.add_to_cache", 1]], ["add_to_cache"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Adds a command to the cache."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.del_from_cache", 1]], ["del_from_cache"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Removes a command from the cache."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.shortcut_cache", 1]], ["shortcut_cache"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns the shortcut cache."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.command_cache", 1]], ["command_cache"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Returns the command cache."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;


new object $help_obj_command_cache_cmeths: $help_obj_command_cache;

var $root manager = $help_obj_command_cache_cmeths;
var $root managed = [$help_obj_command_cache_cmeths];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 887946512;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Client Methods", "Client Methods"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [["ind", "8"]], [<$format, ["dt", [], [".", <$format, ["method", [["command_cache.cache_client_init", 1]], ["cache_client_init"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Must be called before the client can lookup commands."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.cache_client_uninit", 1]], ["cache_client_uninit"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Called when the client will stop looking up commands (e.g. the user logs out)."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.match_shortcut", 1]], ["match_shortcut"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Used to lookup a shortcut in any of the client's Cache Servers. Returns either zero if no shortcuts are found, or a list where the first element is ", <$format, ["tt", [], ["'shortcut"], 'do_tt]>], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.match_command", 1]], ["match_command"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Used to lookup a command in any of the client's Cache Servers. Returns either zero if no matches are found, or a list where the first element is either ", <$format, ["tt", [], ["'partial"], 'do_tt]>, " or ", <$format, ["tt", [], ["'command"], 'do_tt]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.match_command", 1]], ["match_remote_command"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Used by $remote_cache to lookup a command in the remote cache. Returns either zero if no matches are found, or a list where the first element is either ", <$format, ["tt", [], ["'partial"], 'do_tt]>, " or ", <$format, ["tt", [], ["'remote"], 'do_tt]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.add_command_module", 1]], ["add_command_module"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Add a command module to the client."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.del_command_module", 1]], ["del_command_module"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Remove a command module from the client."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.command_modules", 1]], ["command_modules"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["List the command modules used by the client."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;


new object $help_obj_command_cache_dmeths: $help_obj_command_cache;

var $root manager = $help_obj_command_cache_dmeths;
var $root managed = [$help_obj_command_cache_dmeths];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 887946526;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Creation and Destruction Methods", "Creation and Destruction Methods"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [["ind", "8"]], [<$format, ["dt", [], [".", <$format, ["method", [["command_cache.uninit_command_cache", 1]], ["uninit_command_cache"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Unlinks the cache client from any command module objects."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["command_cache.core_command_cache", 1]], ["core_command_cache"], 'do_method]>, "()"], 'do_dt]>, <$format, ["dd", [], ["Purges the cache when a core is extracted."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;


new object $help_parser_command_modules: $help_sys_parser;

var $root manager = $help_parser_command_modules;
var $help_node index = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 889587644;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Command Modules", "Command Modules"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Command Modules are a mechanism for extending command sets without adding new objects to a user's command heirarchy. Command Module objects must be a child of $user_interfaces. Commands on a Command Module must use sender() instead of this() to reference the user (as remote commands do). ", <$format, ["np", [], [], 'do_np]>, "To add a Command Module, type:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set command-modules=+$command_module"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Where ", <$format, ["tt", [], ["$command_module"], 'do_tt]>, " is the Object Name of the Command Module you are adding. You remove Command Modules in a similar manner, using the dash (", <$format, ["tt", [], ["-"], 'do_tt]>, ") character instead of the plus (", <$format, ["tt", [], ["+"], 'do_tt]>, ") character."], #[]]>;
var $root inited = 1;
var $root managed = [$help_parser_command_modules];


new object $gender: $has_name;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $gender pronouns = 0;
var $gender gender = 0;
var $gender cgender_name = 0;
var $gender gender_name = 0;
var $gender person = 0;
var $gender has = 0;
var $gender number = 0;
var $gender context = [];
var $has_name name = ['normal, "Gendered Object", "a Gendered Object"];
var $gender vpronouns = 0;
var $gender apronouns = 0;
var $root manager = $gender;
var $root managed = [$gender];

root method .init_gender() {
    cgender_name = "";
    gender_name = "";
    
    // these should be inited by hand, later.
    pronouns = #[['pr, "itself"], ['pp, "its"], ['po, "it"], ['ps, "it"], ['pq, "its"], ['prc, "Itself"], ['ppc, "Its"], ['poc, "It"], ['psc, "It"], ['pqc, "Its"], ['have, "has"]];
};

public method .pronoun() {
    arg pronoun;
    
    return (> pronouns[pronoun] <);
};

public method .gender() {
    return gender;
};

public method .set_gender_names() {
    arg name, cname;
    
    .perms(sender());
    cgender_name = cname;
    gender_name = name;
};

public method .set_pronouns() {
    arg nmbr, ps, po, pp, pq, pr, psc, poc, ppc, pqc, prc;
    var x;
    
    .perms(sender(), 'manager);
    pronouns = #[['pr, pr], ['pp, pp], ['po, po], ['ps, ps], ['pq, pq], ['prc, prc], ['ppc, ppc], ['poc, poc], ['psc, psc], ['pqc, pqc]];
    number = nmbr;
    context = [ps, po, pp, pq, pr, psc, poc, ppc, pqc, prc];
};

public method .pronouns() {
    return pronouns;
};

public method .gender_name() {
    arg @caps;
    
    [(caps ?= 'null)] = caps;
    switch (caps) {
        case 'caps:
            return cgender_name;
        default:
            return gender_name;
    }
};

public method .context() {
    return context;
};

public method .cml_pronouns() {
    return cml_pronouns;
};

public method .vpronouns() {
    return vpronouns;
};

public method .apronouns() {
    return apronouns;
};

public method .number() {
    return number;
};


new object $gender_first_person: $gender;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $gender cgender_name = "";
var $gender gender_name = "";
var $gender pronouns = #[['pr, "yourself"], ['pp, "your"], ['po, "you"], ['ps, "you"], ['pq, "yours"], ['prc, "Yourself"], ['ppc, "Your"], ['poc, "You"], ['psc, "You"], ['pqc, "Yours"]];
var $gender number = 1;
var $gender context = ["yourself", "your", "you", "you", "yours", "Yourself", "Your", "You", "You", "Yours"];
var $has_name name = ['normal, "Gender, First Person", "a Gender, First Person"];
var $gender vpronouns = #[["vpr", "yourself"], ["vpp", "your"], ["vpo", "you"], ["vps", "you"], ["vpq", "yours"], ["vprc", "Yourself"], ["vppc", "Your"], ["vpoc", "You"], ["vpsc", "You"], ["vpqc", "Yours"]];
var $gender apronouns = #[["apr", "yourself"], ["app", "your"], ["apo", "you"], ["aps", "you"], ["apq", "yours"], ["aprc", "Yourself"], ["appc", "Your"], ["apoc", "You"], ["apsc", "You"], ["apqc", "Yours"]];
var $root manager = $gender_first_person;
var $root managed = [$gender_first_person];


new object $gender_female: $gender;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $gender cgender_name = "Female";
var $gender gender_name = "female";
var $gender pronouns = #[['pr, "herself"], ['pp, "her"], ['po, "her"], ['ps, "she"], ['pq, "hers"], ['prc, "Herself"], ['ppc, "Her"], ['poc, "Her"], ['psc, "She"], ['pqc, "Hers"]];
var $gender number = 'singular;
var $gender context = ["herself", "her", "her", "she", "hers", "Herself", "Her", "Her", "She", "Hers"];
var $has_name name = ['prop, "female", "female"];
var $gender vpronouns = #[["vpr", "herself"], ["vpp", "her"], ["vpo", "her"], ["vps", "she"], ["vpq", "hers"], ["vprc", "Herself"], ["vppc", "Her"], ["vpoc", "Her"], ["vpsc", "She"], ["vpqc", "Hers"]];
var $gender apronouns = #[["apr", "herself"], ["app", "her"], ["apo", "her"], ["aps", "she"], ["apq", "hers"], ["aprc", "Herself"], ["appc", "Her"], ["apoc", "Her"], ["apsc", "She"], ["apqc", "Hers"]];
var $root manager = $gender_female;
var $root managed = [$gender_female];


new object $gender_first_person_plural: $gender;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $gender cgender_name = "";
var $gender gender_name = "";
var $gender pronouns = #[['pr, "yourselves"], ['pp, "your"], ['po, "you"], ['ps, "you"], ['pq, "yours"], ['prc, "Yourselves"], ['ppc, "Your"], ['poc, "You"], ['psc, "You"], ['pqc, "Yours"]];
var $gender number = 2;
var $gender context = ["yourselves", "your", "you", "you", "yours", "Yourselves", "Your", "You", "You", "Yours"];
var $has_name name = ['normal, "Gender, First Person Plural", "a Gender, First Person Plural"];
var $gender vpronouns = #[["vpr", "yourselves"], ["vpp", "your"], ["vpo", "you"], ["vps", "you"], ["vpq", "yours"], ["vprc", "Yourselves"], ["vppc", "Your"], ["vpoc", "You"], ["vpsc", "You"], ["vpqc", "Yours"]];
var $gender apronouns = #[["apr", "yourselves"], ["app", "your"], ["apo", "you"], ["aps", "you"], ["apq", "yours"], ["aprc", "Yourselves"], ["appc", "Your"], ["apoc", "You"], ["apsc", "You"], ["apqc", "Yours"]];
var $root manager = $gender_first_person_plural;
var $root managed = [$gender_first_person_plural];


new object $gender_male: $gender;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $gender cgender_name = "Male";
var $gender gender_name = "male";
var $gender pronouns = #[['pr, "himself"], ['pp, "his"], ['po, "him"], ['ps, "he"], ['pq, "his"], ['prc, "Himself"], ['ppc, "His"], ['poc, "Him"], ['psc, "He"], ['pqc, "His"]];
var $gender number = 'singular;
var $gender context = ["himself", "his", "him", "he", "his", "Himself", "His", "Him", "He", "His"];
var $has_name name = ['prop, "male", "male"];
var $gender vpronouns = #[["vpr", "himself"], ["vpp", "his"], ["vpo", "him"], ["vps", "he"], ["vpq", "his"], ["vprc", "Himself"], ["vppc", "His"], ["vpoc", "Him"], ["vpsc", "He"], ["vpqc", "His"]];
var $gender apronouns = #[["apr", "himself"], ["app", "his"], ["apo", "him"], ["aps", "he"], ["apq", "his"], ["aprc", "Himself"], ["appc", "His"], ["apoc", "Him"], ["apsc", "He"], ["apqc", "His"]];
var $root manager = $gender_male;
var $root managed = [$gender_male];


new object $gender_plural: $gender;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $gender cgender_name = "Plural";
var $gender gender_name = "plural";
var $gender pronouns = #[['pr, "themselves"], ['pp, "their"], ['po, "them"], ['ps, "they"], ['pq, "theirs"], ['prc, "Themselves"], ['ppc, "Their"], ['poc, "Them"], ['psc, "They"], ['pqc, "Theirs"]];
var $gender number = 2;
var $gender context = ["themselves", "their", "them", "they", "theirs", "Themselves", "Their", "Them", "They", "Theirs"];
var $has_name name = ['prop, "plural", "plural"];
var $gender vpronouns = #[["vpr", "themselves"], ["vpp", "their"], ["vpo", "them"], ["vps", "they"], ["vpq", "theirs"], ["vprc", "Themselves"], ["vppc", "Their"], ["vpoc", "Them"], ["vpsc", "They"], ["vpqc", "Theirs"]];
var $gender apronouns = #[["apr", "themselves"], ["app", "their"], ["apo", "them"], ["aps", "they"], ["apq", "theirs"], ["aprc", "Themselves"], ["appc", "Their"], ["apoc", "Them"], ["apsc", "They"], ["apqc", "Theirs"]];
var $root manager = $gender_plural;
var $root managed = [$gender_plural];


new object $gender_neuter: $gender;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $gender cgender_name = "Neuter";
var $gender gender_name = "neuter";
var $gender pronouns = #[['pr, "itself"], ['pp, "its"], ['po, "it"], ['ps, "it"], ['pq, "its"], ['prc, "Itself"], ['ppc, "Its"], ['poc, "It"], ['psc, "It"], ['pqc, "Its"]];
var $gender number = 'singular;
var $gender context = ["itself", "its", "it", "it", "its", "Itself", "Its", "It", "It", "Its"];
var $has_name name = ['prop, "neuter", "neuter"];
var $gender vpronouns = #[["vpr", "itself"], ["vpp", "its"], ["vpo", "it"], ["vps", "it"], ["vpq", "its"], ["vprc", "Itself"], ["vppc", "Its"], ["vpoc", "It"], ["vpsc", "It"], ["vpqc", "Its"]];
var $gender apronouns = #[["apr", "itself"], ["app", "its"], ["apo", "it"], ["aps", "it"], ["apq", "its"], ["aprc", "Itself"], ["appc", "Its"], ["apoc", "It"], ["apsc", "It"], ["apqc", "Its"]];
var $root manager = $gender_neuter;
var $root managed = [$gender_neuter];


new object $argroup: $has_name;

var $root manager = $argroup;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 891385398;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Problem Group", "Problem Group"];
var $root inited = 1;
var $argroup last_id = 360;
var $root credit = ["Created 31-Mar-1998, Brandon Gillespie"];
var $root managed = [$argroup];
var $argroup requests = #[];

public method .next_id() {
    // last_id is only tracked on the definer
    if (this() != definer())
        throw(~perm, "You have no business calling this method.");
    return ++last_id;
};

public method .submit_request() {
    arg summary, text, tb;
    var id, request;
    
    id = $argroup.next_id();
    request = $action_request.submit_request(id, summary, text, tb, sender());
    return .add_request(request);
};

root method .core_argroup() {
    requests = #[];
};

public method .add_request() {
    arg request;
    var info;
    
    requests = dict_add(requests, request.id(), request.general_info());
    return request;
};

public method .request_claimed() {
    arg who;
    var id;
    
    (> .perms(caller(), $action_request) <);
    id = sender().id();
    requests = dict_add(requests, id, replace(requests[id], 5, who));
};

public method .request_resolved() {
    arg when;
    var id;
    
    (> .perms(caller(), $action_request) <);
    id = sender().id();
    requests = dict_add(requests, id, replace(requests[id], 2, when));
};

public method .del_request() {
    arg id;
    
    if (dict_contains(requests, id))
        requests = dict_del(requests, id);
};

public method .requests() {
    return requests;
};

root method .init_argroup() {
    requests = #[];
};


new object $general_problems: $argroup;

var $root manager = $general_problems;
var $root quota_exempt = 0;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 891385463;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "General", "General"];
var $root inited = 1;
var $root managed = [$general_problems];
var $argroup requests = #[];


new object $command_problems: $argroup;

var $root manager = $command_problems;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 891396498;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Command", "Command"];
var $root inited = 1;
var $root managed = [$command_problems];
var $argroup requests = #[];


new object $vr_problems: $argroup;

var $root manager = $vr_problems;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 891396592;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Virtual Reality", "Virtual Reality"];
var $root inited = 1;
var $root managed = [$vr_problems];
var $argroup requests = #[];


new object $client_problems: $argroup;

var $root manager = $client_problems;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 891396654;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Client", "Client"];
var $root inited = 1;
var $root managed = [$client_problems];
var $argroup requests = #[];


new object $dismissed_problems: $argroup;

var $root manager = $dismissed_problems;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 891447478;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Dismissed", "Dismissed"];
var $root inited = 1;
var $root managed = [$dismissed_problems];
var $argroup requests = #[];


new object $contrib_group: $argroup;

var $root manager = $contrib_group;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 913807315;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Contrib Submission", "Contrib Submission"];
var $root inited = 1;
var $root managed = [$contrib_group];
var $argroup requests = #[];


new object $world_time: $foundation;

var $root manager = $world_time;
var $world_time speedup = 3;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848446570;
var $world_time time_units = [[31536000, "year", "years", "yr", "yrs"], [2592000, "month", "months", "mo", "mos"], [604800, "week", "weeks", "wk", "wks"], [86400, "day", "days", "dy", "dys"], [3600, "hour", "hours", "hr", "hrs"], [60, "minute", "minutes", "min", "mins"], [1, "second", "seconds", "sec", "secs"]];
var $root inited = 1;
var $world_time zone_offset = 0;
var $world_time start_time = 873375987;
var $root managed = [$world_time];
var $root help_node = $help_obj_world_time;

public method .from_english() {
    arg string, @units;
    var words, len, nsec, n, i, entry, unit;
    
    [(units ?= time_units)] = units;
    words = string.explode();
    words = words.setremove_all(["and"]);
    if (listlen(words) == 1) {
        if (!(words = regexp(words[1], "^([0-9]+)(.*)$")))
            throw(~args, "Invalid time.");
    }
    len = listlen(words);
    if (len % 2)
        throw(~args, ("Unrecognized time '" + string) + "', no descriptor.");
    nsec = (n = 0);
    for i in [1 .. len] {
        if ((i % 2) == 1) {
            if ((words[i]).is_numeric())
                n = (words[i]).to_number();
            else if ((words[i]) in ["a", "an"])
                n = 1;
            else if ((words[i]) == "no")
                n = 0;
            else
                throw(~invarg, ("Invalid time element '" + n) + "'.");
        } else {
            unit = words[i];
            unit = unit.strip(",");
            nsec += (> (units[.parse_unit(unit, units)])[1] <) * n;
        }
    }
    return nsec;
};

public method .local_time() {
    return (time() - start_time) * speedup;
};

public method .daytime() {
    arg zone, dayscale;
    var t, t1, t2;
    
    t = (((.local_time()) / 3600) + zone) % 24;
    t1 = 6 - dayscale;
    t2 = 18 + dayscale;
    switch (t) {
        case 0 .. 2:
            return [t, 'night, 'night];
        case 3 .. t1 - 1:
            return [t, 'predawn, 'night];
        case t1:
            return [t, 'dawn, 'day];
        case t1 + 1 .. 11:
            return [t, 'morning, 'day];
        case 12:
            return [t, 'noon, 'day];
        case 13 .. t2 - 1:
            return [t, 'afternoon, 'day];
        case t2:
            return [t, 'sunset, 'day];
        case t2 + 1 .. 22:
            return [t, 'evening, 'night];
        case 23:
            return [t, 'night, 'night];
    }
};

public method .time_units() {
    return time_units;
};

public method .parse_unit() {
    arg unit, @units;
    var i;
    
    [(units ?= time_units)] = units;
    i = find i in [1 .. units.length()] where (unit in ((units[i]).subrange(2)));
    if (i)
        return i;
    throw(~invarg, ("Invalid time unit '" + unit) + "', no descriptor?");
};

public method .from_unit_list() {
    arg time, ulist;
    var t, s, i;
    
    s = [];
    for i in (ulist) {
        t = time / ((time_units[i])[1]);
        if (t)
            s += [((t + " ") + ((time_units[i])[2])) + ((t != 1) ? "s" : "")];
        time = time % ((time_units[i])[1]);
    }
    return s.to_english();
};

public method .current_season() {
    var t;
    
    // This is not very flexible, but works well enough. Note that southern
    // hemisphere needs another object, with opposite seasons.
    return ["spring", "summer", "fall", "winter"][(((.local_time()) / 2592000) % 4) + 1];
};


new object $user_parsers: $misc;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root manager = $user_parsers;
var $user_parsers priority = 0;
var $root managed = [$user_parsers];

public method .parse() {
    arg user, str, next_parser, @other_parsers;
    
    // Minimum parser routine.
    return next_parser.parse(user, str, @other_parsers);
};

public method .priority() {
    return priority || 1000;
};

public method .set_priority() {
    arg new;
    
    (> .perms(sender(), 'manager) <);
    priority = new;
};


new object $null_parser: $user_parsers;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $null_parser;
var $root managed = [$null_parser];
var $user_parsers priority = 10000;

public method .parse() {
    arg user, str, @anything_else;
    var i;
    
    for i in [1 .. str.length()] {
        if ((str[i]) != " ")
            return ['failed];
    }
    return ['ok];
};


new object $command_aliases_parser: $user_parsers;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $command_aliases_parser;
var $root managed = [$command_aliases_parser];
var $user_parsers priority = 750;

public method .parse() {
    arg user, str, next_parser, @other_parsers;
    var alias, match, i, result, old;
    
    for alias in (user.command_aliases()) {
        match = str.match_pattern(alias[1]);
        if (match != 0) {
            old = str;
            str = "";
            for i in (alias[2]) {
                if (type(i) == 'integer)
                    str += match[i];
                else
                    str += i;
            }
        }
    }
    result = next_parser.parse(user, str, @other_parsers);
    if (old && ((result[1]) == 'failed))
        return ['error, ("Command converted to \"" + str) + "\" but not understood."];
    return result;
};


new object $command_parser: $user_parsers;

var $root manager = $command_parser;
var $root created_on = 796680318;
var $root inited = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root managed = [$command_parser];

public method .parse() {
    arg u, str, next_parser, @other_parsers;
    var l, cmd, c, p, obj, exits;
    
    cmd = str.explode();
    if (cmd) {
        cmd = [str, cmd[1], ((cmd.subrange(2)).join()) || ""];
        p = [];
        if ((c = u.match_shortcut(@cmd))) {
            if ((c[1]) == 'shortcut)
                return .shortcut(u, @c[2]);
            p = c[2];
        }
        if ((c = u.match_command(@cmd))) {
            if ((c[1]) == 'command)
                return .local(u, @c[2]);
            p += c[2];
        }
        l = u.location();
        if ((c = (| l.match_shortcut(@cmd) |))) {
            if ((c[1]) == 'shortcut)
                return .shortcut(l, @c[2]);
            p += c[2];
        }
        if ((c = (| l.match_command(@cmd) |))) {
            if ((c[1]) == 'command)
                return .local(l, @c[2]);
            p += c[2];
        }
        if ((c = $remote_cache.match_remote_command(@cmd))) {
            if ((c[1]) == 'remote)
                return .remote(u, @c[2]);
            p += c[2];
        }
        if ((exits = (| (u.location()).exits() |) || [])) {
            catch any {
                obj = exits.match_object(str);
                return ['command, obj, 'invoke];
            } with {
                if (error() == ~ambig) {
                    exits = (traceback()[1])[3];
                    return ['error, ((("\"" + str) + "\" can match ") + ((exits.mmap('namef, 'ref)).to_english("", " or "))) + "."];
                }
            }
        }
        if (p)
            return .partial(u, cmd, p);
    }
    return next_parser.parse(u, str, @other_parsers);
};

public method .partial() {
    arg user, args, templates;
    var part, line;
    
    for part in (templates)
        templates = templates.replace(part in templates, toliteral(part));
    if ((templates.length()) == 1)
        line = toliteral(args[2]) + " could match ";
    else if ((templates.length()) == 2)
        line = toliteral(args[2]) + " could match either ";
    else
        line = toliteral(args[2]) + " could match any of ";
    return ['error, (line + (templates.to_english("", " or "))) + "."];
};

public method .shortcut() {
    arg user, method, parsed;
    
    return ['command, user, method, @parsed];
};

public method .complete() {
    arg cmd, user, obj, match, info;
    var x, method, parsed;
    
    method = info[2];
    info = info[4];
    parsed = info.keys();
    for x in [1 .. match.length()] {
        if (x in parsed)
            match = match.replace(x, (> $command_lib.convert_arg((info[x])[1], match[x], user, ((info[x])[2]) ? ((info[x])[2]) : user, user) <));
    }
    return [user, method, (cmd.explode())[1], @match];
};

public method .grasp_for_remote_command() {
    arg str, cmd, args;
    var reg, obj, cdef, match, matched, info;
    
    reg = args.match_regexp("[$#][a-z_0-9][a-z_0-9]*");
    if (!reg)
        return 0;
    obj = (| $object_lib.to_dbref(args.subrange(@reg[1])) |);
    if (!obj)
        return 0;
    info = (| obj.get_command_info('remote, cmd) |);
    if (!info)
        return 0;
    matched = [];
    for cdef in (info) {
        match = args.match_template(cdef[2]);
        if (match != 0)
            matched += [[match.length(), obj, [str, cmd, @match], @cdef.subrange(3)]];
    }
    if (matched) {
        matched = matched.sort(matched.slice(1));
        return ['remote, matched];
    }
    return ['partial, [[str, cmd], info.slice(3)]];
};

public method .local() {
    arg user, @matches;
    var parsed, match, out;
    
    parsed = [];
    out = [];
    for match in (matches) {
        match = ._local(user, @match);
        if ((match[1]) == 'command)
            out += [match];
        else
            parsed = [match[2]] + parsed;
    }
    if (listlen(out) == 1)
        return out[1];
    if (listlen(out) > 1) {
        out = [("Sorry, \"" + (((matches[1])[2])[1])) + "\" could match any of:"];
        for match in (matches)
            out += [(("    \"" + (match[4])) + "\" on ") + ((match[3]).namef('ref))];
        return ['error, out];
    }
    return ['error, parsed.compress()];
};

public method .remote() {
    arg user, @matches;
    var parsed, match;
    
    parsed = [];
    for match in (matches) {
        match = ._remote(user, @match);
        if ((match[1]) == 'command)
            return match;
        parsed = [match[2]] + parsed;
    }
    return ['error, parsed.compress()];
};

public method .handle_error() {
    arg traceback;
    
    return (traceback[1])[2];
};

public method ._remote() {
    arg user, nmatch, definer, match, template, method, info;
    var x, value, that, cmd;
    
    cmd = match[2];
    catch any {
        for x in [1 .. nmatch] {
            if (dict_contains(info, x)) {
                if (((info[x])[1]) == 'this) {
                    that = (> user.match_environment(match[x + 2]) <);
                    if (!(that.is(definer)))
                        return ['error, ((("You cannot " + (match[2])) + " ") + (that.name())) + "."];
                    value = that;
                } else {
                    value = (> .convert_arg(cmd, (info[x])[1], match[x + 2], user, ((info[x])[2]) || [definer], user) <);
                }
                match = match.replace(x + 2, value);
            }
        }
    } with {
        if (error() == ~syntax)
            return ['error, (((traceback()[1])[2]) + template) + "\""];
        return ['error, (traceback()[1])[2]];
    }
    if (!that)
        return ['error, "An error was encountered: no target object found."];
    return ['command, that, method, @match];
};

public method ._local() {
    arg user, nmatch, match, obj, template, method, info;
    var x, cmd;
    
    cmd = match[2];
    catch any {
        for x in [1 .. nmatch] {
            if (dict_contains(info, x))
                match = match.replace(x + 2, (> .convert_arg(cmd, (info[x])[1], match[x + 2], user, (info[x])[2], user) <));
        }
    } with {
        if (error() == ~syntax)
            return ['error, (((traceback()[1])[2]) + template) + "\""];
        return ['error, (traceback()[1])[2]];
    }
    return ['command, obj, method, @match];
};

public method .convert_arg() {
    arg cmd, type, str, me, argargs, target;
    var obj, args, anc, out, x, y, list;
    
    switch (type) {
        case 'list:
            out = [];
            if (!str)
                return [(> .convert_arg(cmd, argargs[1], "", me, argargs[2], target) <)];
    
            // or do the whole list
            if ("," in str)
                list = str.explode_english_list(",");
            else
                list = explode(str);
            for x in (list) {
                catch ~ambig {
                    out = out.setadd(.convert_arg(cmd, argargs[1], x, me, argargs[2], target));
                } with {
                    if ((| (traceback()[1])[3] |) && (!((argargs[1]) in ['user, 'user_opt]))) {
                        for y in ((traceback()[1])[3])
                            out = out.setadd((> .convert_arg(cmd, argargs[1], tostr(y), me, argargs[2], target) <));
                    } else {
                        rethrow(error());
                    }
                }
            }
            return out;
        case 'any:
            return str;
        case 'any_opt:
            args = (> $parse_lib.opt(str, @argargs) <);
            return args;
        case 'object:
            return (> me.match_environment(str) <);
        case 'object_opt:
            args = (> $parse_lib.opt(str, @argargs) <);
            if (!(args[1]))
                throw(~syntax, "No reference specified for command \"");
            obj = (> me.match_environment((args[1])[1]) <);
            return [obj, delete(args[1], 1), args[2]];
        case 'objref:
            return (> $parse_lib.ref(str, me) <);
        case 'objref_opt:
            args = (> $parse_lib.opt(str, @argargs) <);
            if (!(args[1]))
                throw(~syntax, "No reference specified for command \"");
            obj = (> $parse_lib.ref((args[1])[1], me) <);
            return [obj, delete(args[1], 1), args[2]];
        case 'user:
            if (!str)
                throw(~match, "No user specified.");
            if (str == "me")
                return me;
            return (| $user_db.search(str) |) || throw(~match, ("Unable to find user " + str) + ".");
        case 'user_opt:
            args = (> $parse_lib.opt(str, @argargs) <);
            if (!(args[1]))
                throw(~syntax, "Nobody specified for command \"");
            if (str == "me")
                return me;
            return [(> $user_db.search((args[1])[1]) <), args[2]];
        case 'number:
            return (> str.to_number() <);
        case 'number_opt:
            args = (> $parse_lib.opt(str, @argargs) <);
            if (!(args[1]))
                throw(~syntax, "No number specified for command \"");
            return [(> str.to_number() <), args[2]];
        case 'descendant:
            obj = (> me.match_environment(str) <);
            anc = argargs ? (argargs[1]) : user;
            if (!(obj.has_ancestor(anc)))
                throw(~parse, strfmt("You cannot %s %s because it is not %s!", cmd, obj.name(), anc.name()));
            return obj;
        case 'descendant_opt:
            args = (> $parse_lib.opt(str, @argargs) <);
            if (!(args[1]))
                throw(~syntax, "No descendant specified for command \"");
            obj = (> me.match_environment((args[1])[1]) <);
            anc = argargs ? (argargs[1]) : user;
            if (!(obj.has_ancestor(anc)))
                throw(~parse, strfmt("You cannot %s %s because it is not %s!", cmd, obj.name(), anc.name()));
            return [obj, args[2]];
        default:
            throw(~ack, ("Support for the type '" + type) + " is incomplete!");
    }
};


new object $editor_parser: $user_parsers;

var $root manager = $editor_parser;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root created_on = 820684599;
var $root inited = 1;
var $root managed = [$editor_parser];
var $user_parsers priority = 250;
var $editor_parser commands = #[["ap?pend", 'append_cmd], ["a?fter", 'after_cmd], ["d?elete|e?rase", 'delete_cmd], ["done|quit", 'quit_cmd], ["h?elp", 'help_cmd], ["i?nsert", 'insert_cmd], ["line", 'line_cmd], ["l?ist|ls", 'list_cmd], ["m?ove|mv", 'move_cmd], ["save|comp?ile", 'save_cmd], ["store", 'store_cmd], ["sed|sub", 'subst_cmd], ["send|mail", 'send_cmd], ["c?opy|cp", 'copy_cmd], ["f?ill|w?rap", 'fill_cmd], ["j?oin", 'join_cmd]];
var $editor_parser command_help = #[['insert_cmd, ["Syntax: i?nsert [<text>] OR '<text>", "", "Add <text> before current line.  You may also use a single-quote (') as a shortcut character.  If text does not exist you will be prompted for the input."]], ['after_cmd, ["Syntax: a?fter [<text>] OR _<text>", "", "Add <text> after current line.  You may also use an underscore (_) as a shortcut character.  If text does not exist you will be prompted for the input."]], ['append_cmd, ["Syntax: ap?pend <text> OR ,<text>", "", "Add <text> after current line.  You may also use a comma (,) as a shortcut character."]], ['delete_cmd, ["Syntax: d?elete [<range>]", "", "Delete <range> or current line."]], ['copy_cmd, ["Syntax: copy [<range>] [to] <line>", "", "Copy <range> of text or current line to <line>."]], ['quit_cmd, ["Syntax: done|quit", "", "Close editor without saving changes."]], ['fill_cmd, ["Syntax: fill <range> <line width>", "", "Fill <range> of lines to fit within <line width> appropriately (either by expanding or joining)."]], ['help_cmd, ["Syntax: help [<command>]", "", "Basic editor help."]], ['line_cmd, ["Syntax: line <line>", "", "Change the current line to <line>.  You can also use a period (.) as a shortcut character."]], ['move_cmd, ["Syntax: move [<range>] [to] <line>", "", "Move <range> or current line to <line>."]], ['list_cmd, ["Syntax: list [<range>] [-n?umbers]", "", "List <range> or all of edit buffer.  The option -n?umbers may be used to not specify line numbers."]], ['subst_cmd, ["Syntax: s?ub|sed <old> <new> [<range>] [<options>]", "", "Search for <old> and replace it with <new> in <range> (defaulting to the current line).  The character following the command is used as a seperator (a space in the example).  This allows for the sed-like syntax: s/old/new/. The command 'sed' will use strsed() with regular expressions, the command 'sub' or 's' will use strsub() with literal matching.  Options are any one of:", "", "        g      Globally match and replace (do it multiple times)", "        s      Single match and replace (do it only on the first occurance)", "        c      Case matters when matching.", "        i      Case doesn't matter when matching.", "", "Option defaults for sed are: si", "Option defaults for sub are: gi"]], ['save_cmd, ["Syntax: save|comp?ile [as] [<ref>]", "", "Save document, if arguments are given will save alternate copy."]], ['store_cmd, ["Syntax: store", "", "Store editor--do not save changes.  Editor can be resumed with @reedit."]], ['send_cmd, ["Syntax: send|mail <mail-recipient>", "", "Used to send current contents of editor to a mail recipient."]], ['join_cmd, ["Syntax: j?oin <range> \"<sep>\"", "", "Join <range> lines together as one line, seperated by <sep> (default as space)"]]];
var $editor_parser shortcuts = #[["^'", 'insert_cmd], [",", 'append_cmd], ["_", 'after_cmd], [".", 'line_cmd]];

public method .parse() {
    arg u, str, next_parser, @other_parsers;
    var word, cmd, argstr, c, m;
    
    while (str && ((str[1]) == " "))
        str = str.subrange(2);
    if (!str)
        return next_parser.parse(u, str, @other_parsers);
    if ((str[1]) == ">")
        return next_parser.parse(u, str.subrange(2), @other_parsers);
    
    // special cased shortcuts
    for cmd in (shortcuts) {
        if ((str[1]) in (cmd[1]))
            return ['match, u.active_editor(), cmd[2], str[1], "", substr(str, 2)];
    }
    
    // handle standard commands
    // special case 'sub|sed/...'
    if ((word = regexp(str, "^(sed|sub|s)[^a-z]"))) {
        word = word[1];
        argstr = substr(str, strlen(word) + 1);
        return ['match, u.active_editor(), 'subst_cmd, word, "sed|sub", argstr];
    } else if ((word = (| str.word(1) |))) {
        if (" " in str)
            argstr = substr(str, (" " in str) + 1);
        else
            argstr = "";
        for cmd in (commands.keys()) {
            if ((m = match_template(word, cmd)))
                return ['match, u.active_editor(), commands[cmd], word, cmd, argstr];
        }
    }
    
    // didn't match, move on
    return next_parser.parse(u, str, @other_parsers);
};

public method .command_help() {
    return command_help;
};

public method .commands() {
    return commands;
};


new object $channel_parser: $user_parsers;

var $root manager = $channel_parser;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 838745026;
var $root inited = 1;
var $root managed = [$channel_parser];
var $user_parsers priority = 5000;

public method .parse() {
    arg user, str, next_parser, @other_parsers;
    var cname, first_word, parse_list;
    
    str = str.trim();
    if (!str)
        return next_parser.parse(user, str, @other_parsers);
    parse_list = str.explode();
    first_word = parse_list[1];
    cname = user.channel_alias(first_word);
    if ((cname != "") && ((parse_list.length()) > 1))
        return ['command, user, 'broadcast, cname, str.subrange((first_word.length()) + 2)];
    return next_parser.parse(user, str, @other_parsers);
};


new object $chargen_parser: $user_parsers;

var $root manager = $chargen_parser;
var $user_parsers priority = 700;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863732681;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $root managed = [$chargen_parser];

public method .parse() {
    arg user, str, next_parser, @other_parsers;
    var m, cmd, args;
    
    str = str.trim();
    
    // direct drop-through
    if (str && ((str[1]) == ">"))
        return next_parser.parse(user, substr(str, 2), @other_parsers);
    
    // shortcut?
    if ((m = regexp(str, "^(\+|-)([0-9a-z]+) *(.*)$"))) {
        if ((m[1]) == "-")
            str = (("lower " + (m[3])) + " ") + (m[2]);
        else
            str = (("raise " + (m[3])) + " ") + (m[2]);
    }
    cmd = explode(str);
    if (cmd && ((cmd[1]) in ["help", "lower", "raise", "sheet", "done", "abort"])) {
        args = sublist(cmd, 2);
        cmd = lowercase(cmd[1]);
        return ['command, user, tosym(cmd + "_charcmd")] + args;
    }
    return next_parser.parse(user, str, @other_parsers);
};


new object $filters: $misc;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root manager = $filters;
var $root managed = [$filters];

public method .compress() {
    arg input;
    var e, output;
    
    // only goes 1 element deep--sorry, anybody sending anything past that will
    // be shot.
    output = [];
    if (type(input) == 'list) {
        for e in (input) {
            if (type(e) == 'list)
                output += e;
            else
                output += [e];
        }
    } else {
        output = [input];
    }
    return output;
};


new object $wrap_filter: $filters;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $wrap_filter;
var $root managed = [$wrap_filter];

public method .filter_text() {
    arg input;
    var len, output, e, line;
    
    return $string.wrap_line(input, sender().linelen());
};


new object $editor_session: $misc;

var $root manager = $editor_session;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root created_on = 820684587;
var $root inited = 1;
var $editor_session finisher = 0;
var $editor_session sender = 0;
var $editor_session text = 0;
var $editor_session line = 0;
var $editor_session modified = 0;
var $editor_session client_data = 0;
var $editor_session finisher_object = 0;
var $root managed = [$editor_session];

public method .startup() {
    arg fin_object, finish_method, initial_text, cdata;
    
    (> .perms(sender()) <);
    if (type(initial_text) == 'string)
        initial_text = [initial_text];
    sender = sender();
    finisher = finish_method;
    finisher_object = fin_object;
    text = initial_text;
    line = 1;
    modified = 0;
    client_data = cdata;
    if ((| (sender().local_editor()) == 'mcp |)) {
        // Next time, when you have a clever idea about edit name, check
        // it for non-method editting sessions
        sender.ptell([(("#$# edit name: " + (.session_name())) + " upload: @mcp-upload-session ") + (.name()), @text, "."], #[['nomod, 1]]);
        text = 'mcp;
        sender.store_editor();
        return 0;
    } else {
        return 1;
    }
};

public method .abort_cmd() {
    arg @args;
    
    (> .perms(caller(), 'command) <);
    sender.quit_editor();
    return "Aborted. Editor cleared.";
};

public method .insert_cmd() {
    arg cmd, tmpl, what;
    
    (> .perms(caller(), 'command) <);
    modified = 1;
    if (what || match_regexp(cmd, "^[^a-z]")) {
        text = insert(text, line, what);
        line++;
        return ("Line " + tostr(line - 1)) + " added.";
    } else {
        return .read_text(0, sender());
    }
};

public method .save_cmd() {
    arg cmd, tmpl, args;
    var result, m;
    
    (> .perms(caller(), $user, this()) <);
    if ((m = match_template(args, "as *")))
        return "Save as support is not yet completed.";
    catch ~perm {
        if ((> (result = sender.do_save(finisher_object, finisher, text, client_data)) <) == 'clear) {
            sender.quit_editor();
            return "Done. Editor cleared.";
        }
        if ((result[1]) == 'failure)
            return .compile_errors(@result[2]);
        modified = 0;
        return (result[2]) + ["Save completed."];
    } with {
        return (traceback()[1])[2];
    }
};

public method .delete_cmd() {
    arg cmd, tmpl, what;
    var start, end, gone, foo, len;
    
    (> .perms(caller(), 'command) <);
    catch any
        start = ._parse_range(what);
    with
        return "Illegal range, can't delete.";
    [start, end] = start;
    len = end - start;
    gone = sublist(text, start, (end - start) || 1);
    text = sublist(text, 1, start - 1) + sublist(text, end + 1);
    modified = 1;
    line = start;
    return ((((((("Deleted " + ((end - start) + 1)) + " line") + ((end == start) ? "" : "s")) + " (\"") + ((gone[1]).chop(20))) + "\"), current line is ") + line) + ".";
};

public method .line_cmd() {
    arg cmd, tmpl, number;
    
    (> .perms(caller(), 'command) <);
    number = number.trim();
    catch ~nonum
        number = (number == "$") ? (text.length()) : (number.to_number());
    with
        return "You must set to a line number.";
    if ((number < 1) || (number > ((text.length()) + 1)))
        return "Out of range.";
    else
        line = number;
    return ("Current line set to " + tostr(line)) + ".";
};

public method ._parse_range() {
    arg what, @args;
    var start, end, range, allow_pastend, colon;
    
    if (what == "%")
        what = "1-$";
    what = strsub(what, "$", tostr(listlen(text)));
    what = strsub(what, ".", tostr(line));
    what = strsub(what, ",", "-");
    allow_pastend = (| args[1] |) ? 1 : 0;
    if ((| args[2] |) && stridx(what, ":")) {
        what = strsub(what, ":", "-");
        colon = 1;
    }
    if (!what) {
        start = (end = line);
    } else {
        range = (> $parse_lib.range(what) <);
        start = range[1];
        if (start == 'specific)
            throw(~range, "Illegal range.");
        end = ((range[2]) == 'single) ? start : (range[2]);
    }
    if ((start < 1) || ((colon && (end < 0)) || ((!colon) && ((end > (listlen(text) + allow_pastend)) || (end < start)))))
        throw(~range, "Illegal range.");
    return [start, colon ? (-end) : end];
};

public method .help_cmd() {
    arg cmd, tmpl, what;
    var parse;
    
    what = what.trim();
    if (!what)
        return ["Editor commands (use 'help <cmd>' for detailed information):"] + (((($editor_parser.commands()).keys()).vcolumnize(3, (sender().linelen()) - 5)).prefix("    "));
    parse = $editor_parser.parse(sender(), what, $null_parser);
    if ((parse[1]) in ['ok, 'failed])
        return ("Unable to find editor command '" + what) + "'.";
    return ($editor_parser.command_help())[parse[3]];
};

public method .quit_cmd() {
    arg cmd, tmpl, @args;
    var ans;
    
    (> .perms(caller(), 'command) <);
    if (modified) {
        ans = (> sender.prompt("Discard changes? [yes] ") <);
        if (!(ans.is_boolean()))
            return "Ok.  Editor not cleared.";
    }
    sender.quit_editor();
    return "Done. Editor cleared.";
};

public method .fill_cmd() {
    arg cmd, tmpl, what;
    var start, end, width;
    
    (> .perms(caller(), 'command) <);
    what = what.explode();
    catch any
        start = ._parse_range(what[1]);
    with
        return "Illegal range, can't fill.";
    end = start[2];
    start = start[1];
    width = ((what.length()) > 1) ? ((what[2]).to_number()) : 75;
    text = ((text.subrange(1, start - 1)) + (((text.subrange(start, (end - start) + 1)).join(" ")).wrap_lines(width))) + (text.subrange(end + 1));
    modified = 1;
    line = start;
    return ("Fill completed. Current set to " + tostr(start)) + ".";
};

public method .subst_cmd() {
    arg cmd, tmpl, args;
    var start, end, opts, changed, sep, h, range;
    
    (> .perms(caller(), 'command) <);
    h = ($editor_parser.command_help())['subst_cmd];
    if (!args)
        return h;
    sep = args[1];
    args = substr(args, 2);
    args = explode(args, sep, 'keep_blanks);
    if ((!args) || (listlen(args) < 2))
        return h + ["", "! Invalid number of arguments."];
    if (text == [])
        return h + ["", "! There is no text to search and replace in."];
    if (listlen(args) > 2) {
        [opts, range] = (args[3]).regexp("([gsci]*)(.*)");
        if ((!range) && (listlen(args) > 3))
            range = args[3];
    } else {
        opts = "";
    }
    if (range) {
        catch any
            start = ._parse_range(range);
        with
            return h + ["", "! " + ((traceback()[1])[2])];
        [start, end] = start;
    } else {
        start = line;
        end = line;
    }
    if (cmd == "sed")
        changed = .sed(start, end, args[1], args[2], opts);
    else
        changed = .sub(start, end, args[1], args[2], opts);
    modified = changed;
    if (changed == 1)
        return changed + " line changed.";
    else if (changed > 1)
        return changed + " lines changed.";
    else
        return "No lines changed.";
};

public method .session_name() {
    var tmp;
    
    // cruft this up at a later time
    switch (finisher) {
        case '_edit_method_callback:
            return ((("Method " + (client_data[1])) + ".") + (client_data[2])) + "()";
        case '_edit_messages_callback:
            return "Messages on " + (finisher_object.namef('ref));
        case '_edit_mail_callback:
            return "Mail for " + (((client_data[2]).mmap('mail_name)).to_english());
        case '_edit_variable_callback:
            return (("Object Variable " + (client_data[1])) + ",") + (client_data[2]);
        default:
            tmp = strsed(tostr(finisher), "_edit_", "");
            tmp = strsed(tmp, "_callback", "");
            return "%l/%l".format(finisher_object.name(), tmp);
    }
};

public method .is_resumable() {
    return type(text) != 'symbol;
};

public method .mcp_upload() {
    arg newtext;
    var err;
    
    (> .perms(sender()) <);
    if ((> (err = sender.do_save(finisher_object, finisher, newtext, client_data)) <) == 'clear) {
        sender.quit_editor();
        return "Done. Editor cleared.";
    }
    if (type(err) != 'list)
        modified = 0;
    return err ? err : "Save completed.";
};

public method .startup_sender(): nooverride {
    return sender;
};

public method .compile_errors() {
    arg @err;
    var m;
    
    if ((m = regexp(err[1], "Line ([0-9]+)"))) {
        line = min((text.length()) + 1, toint(m[1]));
        return [.list_cmd("", "", m[1])] + err;
    }
    return err;
};

public method .list_cmd() {
    arg cmd, tmpl, rangestr;
    var start, end, start_preview, end_postview, preview, middle, postview, linelen, i, l, lineno, rows, chop, diff, lines, first_preview_line;
    
    (> .perms(caller(), $user, definer()) <);
    if (text == [])
        return "There is no text.";
    rangestr = rangestr.trim();
    rows = (| sender().get_rows() |) || 20;
    l = text.length();
    if (!rangestr) {
        start = line;
        start_preview = (rows - 1) / 2;
        end = line;
        end_postview = rows / 2;
    } else {
        catch any
            [start, end] = ._parse_range(rangestr, 0, 1);
        with
            return "Illegal list range.";
        if (end < 1) {
            end_postview = (chop = -end);
            end = start;
        }
    }
    preview = (middle = (postview = []));
    linelen = sender.linelen();
    
    // sigh.. there's gotta be a better way to do this.. I'm still thinking.
    // this works for now, tho.  -R
    //
    // get the explicitly specified bit of text.
    for i in [start .. min(end, l)]
        middle += .format_line(i, linelen);
    
    // count any wrapped lines as taking up part of the postview.
    if (end_postview == (middle.length()))
        end_postview = 0;
    else
        end_postview -= (middle.length()) - 1;
    
    // if it's too much for the postview, take it out of the preview, too.
    if (end_postview < 0) {
        start_preview = max(start_preview + end_postview, 0);
        end_postview = 0;
    }
    
    // the following will cause [End] to always show after the current line if
    // it's the last line when the user types 'list' by itself, even if there
    // wouldn't otherwise be any space for a postview. 
    if ((!rangestr) && ((end_postview == 0) && (end == l))) {
        start_preview = max(start_preview - 1, 0);
        ++end_postview;
    }
    
    // get the preview text.
    i = start - 1;
    while (i && ((preview.length()) < start_preview)) {
        preview = (.format_line(i, linelen)) + preview;
        i -= 1;
    }
    first_preview_line = i;
    
    // if we're too close to the beginning for the full amount of preview, add
    // the excess to the postview length.
    if ((preview.length()) < start_preview)
        end_postview += start_preview - (preview.length());
    
    // get the postview text.
    for i in [end + 1 .. end + end_postview] {
        if (i > l) {
            postview += [(((l + 1) == line) ? "=>" : "") + "[End]"];
            break;
        }
        lines = .format_line(i, linelen);
        postview += lines;
        if ((postview.length()) == end_postview) {
            break;
        } else if ((postview.length()) > end_postview) {
            diff = ((postview.length()) - end_postview) + 1;
            postview = postview.subrange(1, end_postview - 1);
            if (diff == (lines.length()))
                postview += ["[..next line..]"];
            else
                postview += [((("[.." + (diff.to_english_text())) + " more row") + ((diff > 1) ? "s" : "")) + "..]"];
            break;
        }
    }
    
    // if we're too close to the end for the full amount of postview, add the
    // excess to the preview.
    if ((postview.length()) < end_postview) {
        start_preview += end_postview - (postview.length());
    
        // add to the preview text if necessary to fill the enlarged demand.
        i = first_preview_line;
        while (i && ((preview.length()) < start_preview)) {
            preview = (.format_line(i, linelen)) + preview;
            i -= 1;
        }
    }
    
    // cut preview to size.
    if ((preview.length()) > start_preview)
        preview = preview.subrange(((preview.length()) - start_preview) + 1);
    
    // if the user specified a fixed number of lines, and even with no
    // preview/postview it's too much, chop off the end of the middle portion too
    if (chop && ((middle.length()) > chop)) {
        diff = (middle.length()) - chop;
        middle = (middle.subrange(1, chop)) + [((("[.." + (diff.to_english_text())) + " more row") + ((diff > 1) ? "s" : "")) + "..]"];
    }
    return (preview + middle) + postview;
};

private method .read_text() {
    arg offset, sender;
    var newtext, start;
    
    if ((> (newtext = sender.read()) <)) {
        if (newtext == 'aborted)
            return;
        modified = 1;
        text = listgraft(text, line + offset, newtext);
        start = line + offset;
        line = (line + (newtext.length())) + offset;
        if (listlen(newtext) == 1)
            return ("Line " + start) + " added.";
        return ((("Lines " + start) + " to ") + (start + listlen(newtext))) + " added.";
    } else {
        return "Text unchanged.";
    }
};

public method .after_cmd() {
    arg cmd, tmpl, what;
    var offset;
    
    (> .perms(caller(), 'command) <);
    if (line > listlen(text))
        offset = line - listlen(text);
    if (what || match_regexp(cmd, "^[^a-z]")) {
        modified = 1;
        text = insert(text, (line + 1) - offset, what);
        line += 2 - offset;
        return ("Line " + (line - 1)) + " added.";
    } else {
        return .read_text(1 - offset, sender());
    }
};

public method .append_cmd() {
    arg cmd, tmpl, what;
    var offset;
    
    (> .perms(caller(), 'command) <);
    modified = 1;
    if (line > listlen(text)) {
        text += [what];
        return ("Line " + listlen(text)) + " added.";
    } else if (line == 1) {
        text = [what] + text;
        line = 2;
        return "Line 1 added.";
    } else {
        text = replace(text, line, (text[line]) + what);
        return ("Appended to line " + tostr(line)) + ".";
    }
};

public method .store_cmd() {
    arg cmd, tmpl, @args;
    
    (> .perms(caller(), 'command) <);
    return sender.store_editor();
};

public method .copy_cmd() {
    arg cmd, tmpl, args;
    var m, range, toline, copy, start, end;
    
    (> .perms(caller(), 'command) <);
    if ((m = match_template(args, "* to *")))
        [range, m, toline] = m;
    else if (listlen((m = explode(args))) > 1)
        [range, toline] = m;
    else
        toline = args;
    if (!toline)
        return "Copy to where?";
    toline = toint(toline);
    if ((toline < 1) || (toline > (listlen(text) + 1)))
        return ((("Line " + toline) + " is outside the possible range (1 .. ") + (listlen(text) + 1)) + ").";
    if (range) {
        if (!(range = (| ._parse_range(args, 'allow) |)))
            return "Illegal range, cannot copy.";
    } else if (line > listlen(text)) {
        return "Illegal range, cannot copy.";
    } else {
        range = [line, line];
    }
    [start, end] = range;
    copy = sublist(text, start, (end - start) + 1);
    text = listgraft(text, toline, copy);
    line = toline + listlen(copy);
    if (start == end)
        return ((("Line " + start) + " copied to line ") + toline) + ".";
    return ((((("Lines " + start) + " .. ") + end) + " copied to line ") + toline) + ".";
};

public method .move_cmd() {
    arg cmd, tmpl, args;
    var m, range, toline, move, start, end;
    
    (> .perms(caller(), 'command) <);
    if ((m = match_template(args, "* to *")))
        [range, m, toline] = m;
    else if (listlen((m = explode(args))) > 1)
        [range, toline] = m;
    else
        toline = args;
    if (!toline)
        return "Copy to where?";
    toline = (| ._parse_range(toline, 'allow) |);
    if ((!toline) || ((toline[1]) != (toline[2])))
        return "Invalid move destination reference.";
    toline = toline[1];
    if (range) {
        if (!(range = (| ._parse_range(args, 'allow) |)))
            return "Illegal range, cannot move.";
    } else if (line > listlen(text)) {
        return "Illegal range, cannot move.";
    } else {
        range = [line, line];
    }
    [start, end] = range;
    if ((toline == start) || ((toline == end) || ((toline > start) && (toline < end))))
        return "Source and destination lines conflict.";
    move = sublist(text, start, (end - start) + 1);
    if (toline > end) {
        text = listgraft(text, toline, move);
        text = sublist(text, 1, start - 1) + sublist(text, end + 1);
        line = toline;
    } else {
        text = sublist(text, 1, start - 1) + sublist(text, end + 1);
        text = listgraft(text, toline, move);
        line = toline + listlen(move);
    }
    if (start == end)
        return ((("Line " + start) + " moved to line ") + toline) + ".";
    return ((((("Lines " + start) + " .. ") + end) + " moved to line ") + toline) + ".";
};

public method .sed() {
    arg start, end, search, replace, opts;
    var x, line, changed;
    
    if (end > listlen(text))
        end = listlen(text);
    for x in [start .. end] {
        line = strsed(text[x], search, replace, opts);
        if (strcmp(line, text[x])) {
            text = replace(text, x, line);
            changed++;
        }
    }
    return changed;
};

public method .sub() {
    arg start, end, search, replace, opts;
    var x, line, changed, i;
    
    if (end > listlen(text))
        end = listlen(text);
    for x in [start .. end] {
        line = strsub(text[x], search, replace, opts);
        if (strcmp(line, text[x])) {
            text = replace(text, x, line);
            changed++;
        }
    }
    return changed;
};

public method .send_cmd() {
    arg cmd, tmpl, args;
    var err, m, list, recip, subj, mail, ismail, ret, cd, out;
    
    (> .perms(caller(), $user, this()) <);
    ismail = client_data && ((client_data[1]) == 'mail);
    if ((m = match_template(args, "to *")))
        args = m[2];
    else
        args = args.trim('left);
    list = [];
    for recip in (args.explode_english_list()) {
        if (recip == "me") {
            list = setadd(list, sender());
        } else {
            catch ~listnf
                list = list.setadd((> $mail_lib.match_mail_recipient(recip) <));
            with
                sender().tell(("The recipient \"" + recip) + "\" is invalid.");
        }
    }
    if (!list) {
        if (ismail)
            list = client_data[2];
        else
            return "No recipients specified.";
    }
    if (ismail) {
        cd = client_data;
        cd = replace(cd, 2, list);
    } else {
        cd = ['mail, list, ""];
    }
    ret = (> sender()._edit_mail_callback(text, cd) <);
    if ((ret[1]) == 'success) {
        if (ismail)
            sender.quit_editor();
        return [ret[2], "Done. Editor Cleared."];
    } else {
        return ret[2];
    }
};

public method .cleanup_session() {
    (> .perms(sender()) <);
    if (type(text) == 'symbol)
        return 1;
    return !modified;
};

protected method .format_line() {
    arg lineno, @linelen__shownumbers;
    var linelen, shownumbers, prefix, prefix_size, indent, textlen;
    
    linelen = (| linelen__shownumbers[1] |) || (sender.linelen());
    shownumbers = ((linelen__shownumbers.length()) > 1) ? (linelen__shownumbers[2]) : 1;
    if (shownumbers) {
        textlen = text.length();
        if (textlen < 10) {
            prefix_size = 5;
            indent = "     ";
        } else if (textlen < 1000) {
            prefix_size = 6;
            indent = "      ";
        } else {
            prefix_size = (tostr(textlen).length()) + 3;
            indent = pad("", prefix_size);
        }
        prefix = ((((lineno == line) ? "=>" : "") + lineno) + ": ").right(prefix_size);
        return (prefix + (text[lineno])).wrap_lines(linelen, indent);
    } else {
        return (text[lineno]).wrap_lines(linelen, "");
    }
};

public method .join_cmd() {
    arg cmd, tmpl, args;
    var range, width, sep, spos, epos;
    
    (> .perms(caller(), 'command) <);
    catch any
        range = ._parse_range(args.word(1));
    with
        return "Illegal range, can't join.";
    if (" " in args)
        sep = ((substr(args, (" " in args) + 1).trim()).unquote()) || " ";
    else
        sep = " ";
    [spos, epos] = range;
    text = (sublist(text, 1, spos - 1) + [join(sublist(text, spos, (epos - spos) + 1), sep)]) + sublist(text, epos + 1);
    modified = 1;
    line = spos;
    return ("Join completed. Current set to " + line) + ".";
};


new object $propagator_effects: $misc;

var $root manager = $propagator_effects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 861968399;
var $root inited = 1;
var $root managed = [$propagator_effects];


new object $adapter: $misc;

var $root manager = $adapter;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863769089;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $root managed = [$adapter];
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];

public method .process_args() {
    arg given_args, takes_args;
    var final_args, converter, this_arg, this_arg_data, arg_list;
    
    final_args = #[];
    for this_arg in (takes_args.keys()) {
        this_arg_data = takes_args[this_arg];
        if (!(given_args.contains(this_arg))) {
            if ((this_arg_data[1]) != [])
                final_args = final_args.add(this_arg, (this_arg_data[1])[1]);
            else
                throw(~missingarg, ("Argument " + this_arg) + " was not specified.");
        } else if (((this_arg_data[2]).length()) == 3) {
            converter = this_arg_data[2];
            final_args = final_args.add(this_arg, (> (converter[1]).(converter[2])(given_args[this_arg], @converter[3]) <));
        } else {
            final_args = final_args.add(this_arg, given_args[this_arg]);
        }
    }
    return final_args.add('arg_list, given_args.keys());
};


new object $bug_handler: $misc;

var $root manager = $bug_handler;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 866643320;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $bug_handler ticker = 0;
var $bug_handler ticket = 143;
var $bug_handler unclaimed_tally = 35;
var $root quota_exempt = 1;
var $root managed = [$bug_handler];

public method .categories() {
    // Why? I don't know:
    return $bug_report.children();
};

public method .increase_ticket() {
    ticket++;
};

public method .ticket() {
    return ticket;
};

public method .add_bug() {
    arg category, title, reporter, text;
    var bug;
    
    // Spawn a new bug and fill it with information:
    // Create a new bug object:
    if (!(category.is($bug_report)))
        throw(~stop, "Category must be a descendant of $bug_report.");
    bug = category.spawn();
    if (!bug)
        throw(~stop, "Unable to spawn new bug object!");
    
    // Set the bug information:
    bug.set_reporter(reporter);
    bug.set_text(text);
    bug.set_ticket_number(.ticket());
    .increase_ticket();
};

public method .info() {
    var cat, repnum;
    
    // Report information on the bug handler:
    repnum = 0;
    for cat in (.categories())
        repnum = repnum + ((cat.children()).length());
    return ["Next Ticket Number: " + tostr(ticket), "Total Categories: " + tostr((.categories()).length()), "Total Bug Reports: " + tostr(repnum)];
};

public method .rehash_unclaimed_tally() {
    var category, bug;
    
    unclaimed_tally = 0;
    for category in ($bug_handler.categories()) {
        for bug in (category.children()) {
            if ((!(bug.fixed())) && (!(bug.owner())))
                unclaimed_tally++;
            refresh();
        }
    }
};

public method .unclaimed_tally() {
    return unclaimed_tally;
};

public method .calculate_owned_by() {
    arg who;
    var category, bug, tally;
    
    // Return the number of bugs owned by 'who':
    tally = 0;
    for category in ($bug_handler.categories()) {
        for bug in (category.children()) {
            if ((!(bug.fixed())) && ((bug.owner()) == who))
                tally++;
            refresh();
        }
    }
    return tally;
};

public method .dismiss() {
    arg what;
    
    what.chparents($dismissed_bugs);
};


new object $action_request: $misc;

var $root manager = $action_request;
var $action_request id = 0;
var $root flags = ['variables, 'methods, 'code, 'fertile, 'core];
var $root created_on = 891384403;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $action_request resolved_on = 0;
var $action_request resolved_by = 0;
var $action_request traceback = 0;
var $action_request submitted_on = 0;
var $action_request submitted_by = 0;
var $action_request summary = 0;
var $action_request text = 0;
var $action_request group = 0;
var $root quota_exempt = 1;
var $action_request claimed_by = 0;
var $action_request submit_location = 0;
var $root credit = ["Created 31-Mar-1998, Brandon Gillespie"];
var $action_request comments = 0;
var $action_request claimed_on = 0;
var $root managed = [$action_request];

public method .id() {
    return id;
};

public method .resolved_on() {
    return resolved_on;
};

public method .resolved_by() {
    return resolved_by;
};

public method .traceback() {
    return traceback;
};

public method .submitted_on() {
    return submitted_on;
};

public method .submitted_by() {
    return submitted_by;
};

public method .summary() {
    return summary;
};

public method .text() {
    return text;
};

public method .group() {
    return group;
};

public method .submit_request() {
    arg id, summary, text, traceback, bywhom;
    var new, who, loc;
    
    if (caller() != $argroup)
        throw(~perm, "Caller is not $argroup.");
    new = .spawn();
    return new.set_request(id, sender(), summary, text, traceback, bywhom);
};

public method .submit_location() {
    return submit_location;
};

private method .set_request() {
    arg nid, ngroup, nsummary, ntext, ntb, nbywhom;
    
    id = nid;
    group = ngroup;
    summary = nsummary;
    text = ntext;
    if (ntb)
        traceback = ntb;
    submitted_by = nbywhom;
    submitted_on = time();
    submit_location = (| nbywhom.location() |) || 0;
    comments = [];
};

public method .format() {
    arg @html_view;
    var s, out, len, pre, c, r, row, cb, cm;
    
    len = user() ? (user().linelen()) : 79;
    if (!valid(submitted_by))
        submitted_by = $no_one;
    c = $cml_lib;
    r = [["align", "right"]];
    cb = [["bgcolor", "#eeeeee"]];
    out = [c.fmt_tr(c.fmt_td(c.fmt_subj("Ticket ID:", 3), @r), c.fmt_td(c.fmt_subj("#" + id, 3)))];
    out += [c.fmt_tr(._fmt_hd("Bug Report:", @r), c.fmt_td(this()))];
    if (submit_location)
        out += [c.fmt_tr(._fmt_hd("Reported From:", @r), c.fmt_td(submit_location.namef('ref)))];
    out += [c.fmt_tr(._fmt_hd("Reported By:", @r), c.fmt_td(submitted_by.namef('ref)))];
    out += [c.fmt_tr(._fmt_hd("Reported On:", @r), c.fmt_td($time.format("%d-%h-%Y", submitted_on)))];
    if (resolved_on) {
        out += [c.fmt_tr(._fmt_hd("Resolved By:", @r), c.fmt_td(resolved_by.namef('ref)))];
        out += [c.fmt_tr(._fmt_hd("Resolved On:", @r), c.fmt_td($time.format("%d-%h-%Y", resolved_on)))];
    } else {
        out += [c.fmt_tr(._fmt_hd("Resolved:", @r), c.fmt_td("UNRESOLVED"))];
    }
    if (claimed_on) {
        out += [c.fmt_tr(._fmt_hd("Claimed By:", @r), c.fmt_td(claimed_by.namef('ref)))];
        out += [c.fmt_tr(._fmt_hd("Claimed On:", @r), c.fmt_td($time.format("%d-%h-%Y", claimed_on)))];
    } else {
        out += [c.fmt_tr(._fmt_hd("Claimed:", @r), c.fmt_td("UNCLAIMED"))];
    }
    
    // hacky
    if (html_view)
        out += [c.fmt_tr(._fmt_hd("Bug Group:", @r), c.fmt_td(._gen_html_sgroup()))];
    else
        out += [c.fmt_tr(._fmt_hd("Bug Group:", @r), c.fmt_td(group.namef('ref)))];
    out += [c.fmt_tr(._fmt_hd("Summary:", @r), c.fmt_td(summary, @cb))];
    if (traceback)
        out += [c.fmt_tr(._fmt_hd("ASSOCIATED TRACEBACK:", @r), c.fmt_td(c.fmt_quote(traceback.join("\n")), @cb))];
    if (text) {
        out += [c.fmt_tr(c.fmt_td(c.fmt_hr(), ["colspan", 2]))];
        s = [];
        for row in (text)
            s += [row, c.fmt_p()];
        out += [c.fmt_tr(c.fmt_td(s, @cb, ["colspan", 2]))];
    }
    for cm in (comments) {
        s = [c.fmt_hr(), c.fmt_b([((("On " + ($time.format("%d-%h-%Y", cm[1]))) + " ") + (cm[2])) + " Comments:"]), c.fmt_p(), cm[3]];
        out += [c.fmt_tr(c.fmt_td(s, ["colspan", 2]))];
    }
    
    // hacky
    if (html_view)
        out += [c.fmt_tr(c.fmt_td([c.fmt_hr(), ._gen_html_cmt()], ["colspan", 2]))];
    return $ctext_frob.new_with([c.fmt_table("20%,80%", @out)]);
};

public method .add_comment() {
    arg cmt, @name;
    var c;
    
    //// Commenting out the perms check so people that aren't admins can at 
    //// least add comments. -- Bruce
    // (> group.perms(sender(), 'trusts) <);
    if (type(cmt) != 'list)
        throw(~type, "Comment must be a list of strings");
    if (sender() == $page_ar)
        [(name ?= sender().namef('ref))] = name;
    else
        name = sender().namef('ref);
    comments += [[time(), name, cmt]];
};

public method .comments() {
    return comments;
};

public method .resolve() {
    arg @who;
    
    (sender() == $page_ar) || (> group.perms(sender(), 'trusts) <);
    if (who && (sender() == $page_ar))
        who = who[1];
    else
        who = sender();
    resolved_on = time();
    resolved_by = who;
    group.request_resolved(resolved_on);
};

public method .claimed_by() {
    return claimed_by;
};

public method .claimed_on() {
    return claimed_on;
};

public method .claim() {
    (> group.perms(sender(), 'trusts) <);
    claimed_on = time();
    claimed_by = sender();
    group.request_claimed(claimed_by);
};

public method .change_group() {
    arg newgrp;
    
    (sender() == $page_ar) || (> group.perms(sender(), 'trusts) <);
    newgrp.add_request(this());
    group.del_request(id);
    group = newgrp;
};

public method .general_info() {
    return [this(), resolved_on, submitted_on, summary, claimed_by];
};

public method ._gen_html_sgroup() {
    var g, grp, f, v;
    
    grp = [];
    for g in ($argroup.children()) {
        v = [["value", ("\"" + g) + "\""]];
        if (g == group)
            v += [["selected", ""]];
        grp += [(<$format, ["option", v, g.name(), 'do_option]>)];
    }
    grp = [(<$format, ["select", [["name", "group"], ["onChange", "javascript:form.submit()"]], grp, 'do_select]>)];
    grp += [(<$format, ["input", [["type", "hidden"], ["name", "id"], ["value", .id()]], [], 'do_input]>)];
    grp = [(<$format, ["form", [["action", "/ar/change"]], grp, 'do_form]>)];
    return grp;
};

public method ._fmt_hd() {
    arg v, @flags;
    var b;
    
    return (<$format, ["td", flags, [(<$format, ["b", [], [v], 'do_b]>)], 'do_td]>);
};

public method ._gen_html_cmt() {
    var c, form;
    
    c = $cml_lib;
    form = [c.fmt_input(["type", "hidden"], ["name", "id"], ["value", .id()]), c.fmt_input(["type", "hidden"], ["name", "resolv"], ["value", "no"]), c.fmt_textarea([], ["rows", "4"], ["cols", "80"], ["name", "comment"]), c.fmt_table("40%,60%", c.fmt_tr(c.fmt_td(c.fmt_input(["type", "submit"], ["value", "\"Add Comment\""]), ["align", "center"]), c.fmt_td([" Pre-formatted text: ", c.fmt_input(["type", "checkbox"], ["name", "pre"])], ["align", "right"], ["valign", "center"])), c.fmt_tr(c.fmt_td(c.fmt_b(c.fmt_input(["type", "button"], ["onClick", "\"javascript:cmtForm.resolv.value='yes'; cmtForm.submit()\""], ["value", "RESOLVE"])), ["align", "center"]), c.fmt_td([" Mail Notification: ", c.fmt_input(["type", "checkbox"], ["name", "mailmsg"], ["value", "yes"], ["checked", ""])], ["align", "right"], ["valign", "center"])))];
    return c.fmt_form(form, ["name", "cmtForm"], ["action", "change"]);
};

root method .uninit_action_request() {
    (| group.del_request(id) |);
};


new object $symbol: $libraries;

var $root manager = $symbol;
var $root created_on = 811822782;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root managed = [$symbol];

public method .to_string() {
    arg sym;
    
    return tostr(sym);
};


new object $math: $libraries;

var $root manager = $math;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 845760297;
var $root inited = 1;
var $math pi = 3.14159;
var $math pi2 = 6.28318;
var $math origin_2d = [0.0, 0.0];
var $math origin_3d = [0.0, 0.0, 0.0];
var $math transmat_2d = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
var $math transmat_3d = [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0]];
var $root managed = [$math];
var $root help_node = $help_obj_math;
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];

public method .minor(): native;

public method .major(): native;

public method .add(): native;

public method .sub(): native;

public method .dot(): native;

public method .distance(): native;

public method .cross(): native;

public method .scale(): native;

public method .is_lower(): native;

public method .transpose(): native;

public method .polar_rectangular() {
    arg coords;
    
    return [(coords[1]) * cos(coords[2]), (coords[1]) * sin(coords[2])];
};

public method .rectangular_polar() {
    arg coords;
    var a;
    
    a = atan2(coords[2], coords[1]);
    if (a < 0)
        a += pi2;
    return [.distance(coords, origin_2d), a];
};

public method .pi() {
    return pi;
};

public method .pi2() {
    return pi2;
};

public method .deg_rad() {
    arg angle;
    
    return angle / 57.2958;
};

public method .rad_deg() {
    arg angle;
    
    return angle * 57.2958;
};

public method .matrix_add() {
    arg m1, m2;
    var i;
    
    return map i in [1 .. m1.length()] to (.add(m1[i], m2[i]));
};

public method .matrix_sub() {
    arg m1, m2;
    var i;
    
    return map i in [1 .. m2.length()] to (.sub(m1[i], m2[i]));
};

public method .matrix_mul() {
    arg m1, m2;
    var x, y;
    
    m2 = .transpose(m2);
    return map x in (m1) to (map y in (m2) to (.dot(x, y)));
};

public method .spherical_rectangular() {
    arg coords;
    var r, phi, theta, r1;
    
    r = coords[1];
    phi = coords[2];
    theta = coords[3];
    r1 = r * cos(theta);
    return [r1 * cos(phi), r1 * sin(phi), r * sin(theta)];
};

public method .rectangular_spherical() {
    arg coords;
    var a, d;
    
    a = atan2(coords[2], coords[1]);
    if (a < 0)
        a += pi2;
    return [(d = .distance(coords, origin_3d)), a, atan2(coords[3], .distance(coords.subrange(1, 2), origin_2d))];
};

public method .ident_mat() {
    arg n;
    var x, y;
    
    return map x in [1 .. n] to (map y in [1 .. n] to ((x == y) ? 1.0 : 0.0));
};

public method .translation_mat() {
    arg vector;
    var x, y;
    
    if ((vector.length()) == 2)
        return transmat_2d + [vector + [1.0]];
    else
        return transmat_3d + [vector + [1.0]];
};

public method .rectangular_cylindrical() {
    arg coords;
    var a;
    
    a = atan2(coords[2], coords[1]);
    if (a < 0)
        a += pi2;
    return [.distance(coords.subrange(1, 2), origin_2d), a, coords[3]];
};

public method .cylindrical_rectangular() {
    arg coords;
    
    return [(coords[1]) * cos(coords[2]), (coords[1]) * sin(coords[2]), coords[3]];
};

public method .matrix_scale() {
    arg s, m;
    var x;
    
    return map x in (m) to (.scale(s, x));
};

public method .tensor() {
    arg v1, v2;
    var x, y;
    
    return map x in (v1) to (map y in (v2) to (x * y));
};

public method .skew() {
    arg v;
    
    return [[0.0, v[3], -(v[2])], [-(v[3]), 0.0, v[1]], [v[2], -(v[1]), 0.0]];
};

public method .rotation_mat_3d() {
    arg axis, angle;
    var s, c, m, tens;
    
    s = sin(angle);
    c = cos(angle);
    if (type(axis) == 'list) {
        axis = .scale(1.0 / (.distance(axis, origin_3d)), axis);
        tens = .tensor(axis, axis);
        m = .matrix_add(tens, .matrix_add(.matrix_scale(s, .skew(axis)), .matrix_scale(c, .matrix_sub(.ident_mat(3), tens))));
        return [[@m[1], 0.0], [@m[2], 0.0], [@m[3], 0.0], [0.0, 0.0, 0.0, 1.0]];
    } else {
        switch (axis) {
            case 'z:
                return [[c, s, 0.0, 0.0], [-s, c, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]];
            case 'y:
                return [[c, 0.0, -s, 0.0], [0.0, 1.0, 0.0, 0.0], [s, 0.0, c, 0.0], [0.0, 0.0, 0.0, 1.0]];
            case 'x:
                return [[1.0, 0.0, 0.0, 0.0], [0.0, c, s, 0.0], [0.0, -s, c, 0.0], [0.0, 0.0, 0.0, 1.0]];
        }
    }
};

public method .transform_vect() {
    arg m, v;
    var x, outvect, flag;
    
    if ((m.length()) == ((v.length()) + 1)) {
        v += [1.0];
        flag = 1;
    }
    outvect = map x in (m) to (.dot(x, v));
    return flag ? (outvect.subrange(1, (outvect.length()) - 1)) : outvect;
};

public method .rotation_mat_2d() {
    arg angle;
    var s, c;
    
    s = sin(angle);
    c = cos(angle);
    return [[c, s, 0.0], [-s, c, 0.0], [0.0, 0.0, 1.0]];
};

public method .scale_mat() {
    arg scale;
    
    if ((scale.length()) == 2)
        return [[scale[1], 0.0, 0.0], [0, scale[2], 0.0], [0.0, 0.0, 1.0]];
    else
        return [[scale[1], 0.0, 0.0, 0.0], [0.0, scale[2], 0.0, 0.0], [0.0, 0.0, scale[3], 0.0], [0.0, 0.0, 0.0, 1]];
};

public method .runge() {
    arg x, y, h, f, data;
    var k1, k2, k3, k4, s;
    
    // returns the next timestep for differential equation y'=f(x,y,data)
    s = sender();
    k1 = s.f(x, y, data);
    k2 = s.f(x + (0.5 * h), .add(y, .scale(0.5 * h, k1)), data);
    k3 = s.f(x + (0.5 * h), .add(y, .scale(0.5 * h, k2)), data);
    k4 = s.f(x + h, .add(y, .scale(h, k3)), data);
    return .add(y, .scale(h / 6.0, .add(.add(k1, .scale(2.0, .add(k2, k3))), k4)));
};


new object $english_lib: $libraries;

var $root manager = $english_lib;
var $english_lib alphabet = "abcdefghijklmnopqrstuvwxyz";
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847697242;
var $english_lib capitalize_exceptions = ["the", "a", "an", "and", "for", "but", "or", "nor", "of", "with", "using", "at", "to", "in", "into", "on", "onto", "upon", "out", "from", "over", "under", "through", "underneath", "beneath", "behind", "beside", "about", "as", "off"];
var $root inited = 1;
var $english_lib vowel_exceptions = "^usu|uke|uvu|use|UPI|unit|univ|unic|uniq|unix|eur|uu|ubiq|union|one|once|uti|unif";
var $english_lib nonvowel_exceptions = "^historic|ydu|honor|honest|habitual|heir|RPG";
var $english_lib noun_exceptions = #[["child", "children"], ["deer", "deer"], ["moose", "moose"], ["mouse", "mice"]];
var $english_lib letter_names = ["ay", "bee", "see", "dee", "ee", "eff", "jee", "aitch", "eye", "jay", "kay", "el", "em", "en", "oh", "pee", "queue", "ar", "es", "tee", "you", "vee", "double-you", "ex", "why", "zee"];
var $english_lib cardinal_directions = ["north", "northeast", "east", "southeast", "south", "southwest", "west", "northwest"];
var $english_lib verb_exceptions = #[["has", "have"], ["is", "are"], ["was", "were"], ["'s", "'ve"], ["can", "can"], ["collapses", "collapse"]];
var $english_lib cardinal_direction_opposites = ["south", "southwest", "west", "northwest", "northeast", "east", "southeast"];
var $english_lib selector_words = ["all", "everything", "everyone", "everybody"];
var $root managed = [$english_lib];

public method .titleize() {
    arg string;
    var words;
    
    words = string.explode();
    if ((words.length()) < 2) {
        if (words)
            return string.capitalize();
        else
            return string;
    }
    return [(words[1]).capitalize(), @(words.subrange(2, (words.length()) - 2)).lmap('capitalize), (words[words.length()]).capitalize()].join();
};

public method .capitalize() {
    arg str;
    var m, word;
    
    // capitalize the first character of the first alphanumeric word found,
    // if it is not in the exceptions list.  Example:
    //
    //    $english_lib.capitalize(" @foo") => " @Foo"
    //
    if (!(m = regexp(str, "[a-z]+")))
        return str;
    word = (m[1]).capitalize();
    anticipate_assignment();
    return (word in capitalize_exceptions) ? str : strsed(str, "[a-z]+", word);
};

public method ._noun_singular() {
    arg string;
    var k;
    
    anticipate_assignment();
    if ((k = string in (noun_exceptions.values())))
        return (noun_exceptions.keys())[k];
    return ._remove_s(string);
};

public method ._noun_plural() {
    arg string;
    var k;
    
    anticipate_assignment();
    string = strsed(string, "^(a|an) +", "");
    if ((k = (| noun_exceptions[string] |)))
        return k;
    return ._add_s(string);
};

public method .vowel_exception() {
    arg word;
    var prefix;
    
    return match_regexp(word, vowel_exceptions) ? 1 : 0;
};

public method .nonvowel_exception() {
    arg word;
    var prefix;
    
    return match_regexp(word, nonvowel_exceptions) ? 1 : 0;
};

public method .indef_article() {
    arg word;
    
    if ((((word[1]) in "aeiou") && (!(.vowel_exception(word)))) || (.nonvowel_exception(word)))
        return "an";
    else
        return "a";
};

public method .get_conjugation() {
    arg spec, @plural;
    var i, vb;
    
    i = "/" in (spec + "/");
    if (plural && (plural[1])) {
        if (i < (spec.length()))
            vb = spec.subrange(i + 1);
        else
            vb = ._verb_plural(spec);
    } else if (i > 1) {
        vb = spec.subrange(1, i - 1);
    } else {
        vb = ._verb_singular(spec.subrange(2));
    }
    if (strcmp("a", (i == 1) ? (spec[2]) : spec) > 0)
        return vb.capitalize();
    else
        return vb;
};

public method .get_noun() {
    arg spec, @plural;
    var i, vb;
    
    i = "/" in (spec + "/");
    if (plural && (plural[1])) {
        if (i < (spec.length()))
            vb = spec.subrange(i + 1);
        else
            vb = ._noun_plural(spec);
    } else if (i > 1) {
        vb = spec.subrange(1, i - 1);
    } else {
        vb = ._noun_singular(spec.subrange(2));
    }
    
    // just pass to $string.capitalize()?
    if (strcmp("a", (i == 1) ? (spec[2]) : spec) > 0)
        return vb.capitalize();
    else
        return vb;
};

public method ._verb_singular() {
    arg string;
    var len, a;
    
    len = string.length();
    if ((len > 2) && match_regexp(string, "n't *$"))
        return (._verb_singular(string.subrange(1, len - 3))) + "n't";
    else if ((a = string in (verb_exceptions.values())))
        return (verb_excetions.keys())[a];
    return ._add_s(string, len);
};

public method ._verb_plural() {
    arg string;
    var len, a;
    
    len = string.length();
    if ((len > 2) && match_regexp(string, "n't *$"))
        return (._verb_plural(string.subrange(1, len - 3))) + "n't";
    else if ((a = (| verb_exceptions[string] |)))
        return a;
    return ._remove_s(string);
};

public method ._add_s() {
    arg str;
    var len;
    
    len = strlen(str);
    if (len < 2)
        return str + "s";
    if (((str[len]) == "y") && (!((str[len - 1]) in "aeiou")))
        return substr(str, 1, len - 1) + "ies";
    else if (((((str[len]) == "o") && (!((str[len - 1]) in "aeiouy"))) || ((str[len]) in "sx")) || ((len > 1) && ((substr(str, len - 1, 2) in "chsh") % 2)))
        return str + "es";
    else
        return str + "s";
};

public method ._remove_s() {
    arg str;
    var len;
    
    len = strlen(str);
    if ((len <= 3) || ((str[len]) != "s"))
        return str;
    else if ((str[len - 1]) != "e")
        return substr(str, 1, len - 1);
    else if (((((str[len - 2]) == "h") && ((str[len - 3]) in "cs")) || ((str[len - 2]) in "ox")) || (((str[len - 2]) == "s") && (!((str[len - 3]) in "aeiouy"))))
        return substr(str, 1, len - 2);
    else if ((str[len - 2]) == "i")
        return substr(str, 1, len - 3) + "y";
    else
        return substr(str, 1, len - 1);
};

public method .selector_words() {
    return selector_words;
};

public method .selector_word_default() {
    arg word, place;
    var tmp, item;
    
    if (word in ["everyone", "everybody"])
        return (place.contents()).mfilter('has_ancestor, $body);
    else
        return ((word in selector_words) && [get_var(tosym(word))]) || [];
};

public method .def_article() {
    arg string;
    
    // For completeness sake
    return "the";
};

public method .compress_names() {
    arg names, @args;
    var c, x, n, ret;
    
    if (names == (c = names.compress()))
        return names.to_english(@args);
    ret = [];
    for x in (c) {
        if ((n = names.count(x)) > 1)
            ret += [((n.to_english_text()) + " ") + (._noun_plural(x.strip_article()))];
        else
            ret += [x];
    }
    return ret.to_english(@args);
};


new object $time: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $time months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var $time days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var $root manager = $time;
var $root managed = [$time];
var $time time_units = [[31536000, "year", "years", "yr", "yrs"], [2592000, "month", "months", "mo", "mos"], [604800, "week", "weeks", "wk", "wks"], [86400, "day", "days", "dy", "dys"], [3600, "hour", "hours", "hr", "hrs"], [60, "minute", "minutes", "min", "mins"], [1, "second", "seconds", "sec", "secs"]];
var $root help_node = $help_obj_time;

public method .format(): native;

public method .elapsed() {
    arg time, @flag;
    var str, t, p;
    
    // compares args[1] with time() and returns hh:mm elapsed
    // will eventually make flags do things like 'long etc.  For now its
    // just your own time, rather than time().
    [(flag ?= 'stopwatch)] = flag;
    
    // time = time() - time;
    switch (flag) {
        case 'long:
            return .to_english(time);
        default:
            if (time > 356400)
                p = 3;
            else
                p = 2;
            return strfmt("%2{0}r:%2{0}r:%2{0}r", time / 3600, (time % 3600) / 60, time % 60);
    }
};

public method .dhms() {
    arg secs, @long;
    var ret_str, x;
    
    if (long)
        long = 1;
    if (secs > 86400) {
        x = secs / 86400;
        ret_str = x + (long ? (" day" + ((x < 2) ? "" : "s")) : "d");
    } else if (secs > 3600) {
        x = secs / 3600;
        ret_str = x + (long ? (" hr" + ((x < 2) ? "" : "s")) : "h");
    } else if (secs > 60) {
        x = secs / 60;
        ret_str = x + (long ? (" min" + ((x < 2) ? "" : "s")) : "m");
    } else {
        ret_str = secs + (long ? (" sec" + ((secs < 2) ? "" : "s")) : "s");
    }
    return ret_str;
};

public method .from_english() {
    arg string;
    
    return $world_time.from_english(string, time_units);
};

public method .to_english() {
    arg time, @reftime;
    var times, words, x, ctime, mnths, month, year, days, out, lt, rrk;
    
    // most of this was stolen from MOO (und ve are evil)
    if (time < 1)
        return "0 seconds";
    [(reftime ?= time())] = reftime;
    words = ["year", "month", "day", "hour", "minute", "second"];
    times = [];
    for x in ([60, 60, 24]) {
        times = [time % x, @times];
        time = time / x;
    }
    mnths = 0;
    lt = localtime(reftime);
    month = lt[6];
    if ((lt[7]) < 100)
        year = 1900 + (lt[7]);
    else
        year = lt[7];
    days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
    while (time >= (days + ((month == 2) && (((year % 4) == 0) && (!((year % 400) in [100, 200, 300])))))) {
        refresh();
        time -= days;
        mnths++;
        month++;
        if (month > 12) {
            year++;
            month = 1;
        }
    }
    times = [mnths / 12, mnths % 12, time, @times];
    out = [];
    for x in [1 .. 6] {
        if ((times[x]) > 0)
            out += [(((times[x]) + " ") + (words[x])) + (((times[x]) == 1) ? "" : "s")];
    }
    return out.to_english();
};

public method .realm_time() {
    arg realm, @season;
    var d, lt, hr, pm, min, tm;
    
    d = realm.get_setting("weather-time", $realm);
    lt = ((d[5]).local_time()) + (d[6]);
    hr = ((lt / 3600) + (d[6])) % 24;
    if (hr >= 12) {
        pm = "PM";
        if (hr > 12)
            hr -= 12;
    } else {
        pm = "AM";
    }
    min = (lt / 60) % 60;
    tm = strfmt("%2{0}r:%2{0}r ", hr, min) + pm;
    return [tm + (season ? ((" (" + (d[2])) + "time)") : ""), (d[3]).realm()];
};


new object $graph: $libraries;

var $root manager = $graph;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848800783;
var $root inited = 1;
var $root managed = [$graph];

public method .breadth_search() {
    arg node, data, neighbors, is_dest;
    var d, i, j, path;
    
    d = #[[node, 'source]];
    i = 1;
    while ((i <= ((d.keys()).length())) && (!(node = (d.keys())[i++]).(is_dest)(data))) {
        refresh();
        for j in (node.(neighbors)())
            d = d.add(j, node);
    }
    if (i <= ((d.keys()).length())) {
        refresh();
        path = [node];
        while ((node = d[node]) != 'source)
            path += [node];
        return path;
    } else {
        return 0;
    }
};

public method .topological_sort() {
    arg list, comparator;
    var i, j;
    
    i = list.length();
    while (i >= 1) {
        j = 2;
        while (j <= i) {
            if ((list[j - 1]).(comparator)(list[j]))
                list = list.swap(j - 1, j);
            refresh();
            j++;
        }
        i--;
    }
    return list;
};


new object $heap: $libraries;

var $root manager = $heap;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848818545;
var $root inited = 1;
var $root managed = [$heap];
var $root help_node = $help_heap;
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];

public method .push() {
    arg heap, element, priority_ind;
    var i, j;
    
    i = listlen(heap) + 1;
    if (i == 1)
        return [element];
    anticipate_assignment();
    heap += [0];
    while ((i > 1) && ((element[priority_ind]) < ((heap[(j = i / 2)])[priority_ind])))
        heap = replace(heap, i, heap[(i = j)]);
    heap = heap.replace(i, element);
    return heap;
};

public method .del() {
    arg heap, i, priority_ind;
    var j, len, min;
    
    len = listlen(heap);
    if (i > len)
        throw(~invarg, "Index %d out of bounds - can't delete".format(i));
    anticipate_assignment();
    while (i != len) {
        min = len;
        j = i * 2;
        if ((j < len) && (((heap[j])[priority_ind]) < ((heap[min])[priority_ind])))
            min = j;
        j++;
        if ((j < len) && (((heap[j])[priority_ind]) < ((heap[min])[priority_ind])))
            min = j;
        heap = replace(heap, i, heap[min]);
        i = min;
    }
    heap = heap.subrange(1, len - 1);
    return heap;
};


new object $place_lib: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $place_lib default_place = $place;
var $place_lib coordinate_shortcuts = #[["n?orth", [0, 0]], ["s?outh", [180, 0]], ["e?ast", [90, 0]], ["w?est", [270, 0]], ["ne|northeast", [45, 0]], ["se|southeast", [135, 0]], ["nw|northwest", [225, 0]], ["sw|southwest", [315, 0]], ["d?own", [-1, -90]], ["u?p", [-1, 90]]];
var $place_lib known_realms = [$realm_of_creation];
var $place_lib build_hints = #[[1, <$ctext_frob, [["This is the do-it-all system for building places. At any time you can enter \"@abort\" to abort building. To turn off these hints \"@set experienced\" in your regular command environment.", <$format, ["hr", [], [], 'do_hr]>], #[['this, $place_lib]]]>], [2, <$ctext_frob, [["The specified destination does not exist, therefore a new one will be created with the name you specified.", <$format, ["hr", [], [], 'do_hr]>], #[['this, $place_lib]]]>], [3, <$ctext_frob, [["Name aliases can be specified on the same line as the name. This is done by seperating them from the name with commas. Any number of aliases can be specified in this manner (such as \"Name, alias, alias, alias\"). Names types can be defined by appending ", <$format, ["tt", [], ["+type"], 'do_tt]>, ", where ", <$format, ["tt", [], ["type"], 'do_tt]>, " is one of ", <$format, ["tt", [], ["proper"], 'do_tt]>, ", ", <$format, ["tt", [], ["unique"], 'do_tt]>, " or ", <$format, ["tt", [], ["normal"], 'do_tt]>, ". Not specifying a type defaults to ", <$format, ["tt", [], ["normal"], 'do_tt]>, ".", <$format, ["hr", [], [], 'do_hr]>], #[['this, $place_lib]]]>], [4, <$ctext_frob, [["Realms are used to keep locations in relation with each other. To get a list of commonly known realms type ", <$format, ["tt", [], ["@realms"], 'do_tt]>, ".", <$format, ["hr", [], [], 'do_hr]>], #[['this, $place_lib]]]>], [5, <$ctext_frob, [["Coordinates are used to define a basic relation between locations by pointing in the direction each place is. They use the radial/azimuth system. More help on Coordinates can be found in help under ", <$format, ["tt", [], ["places"], 'do_tt]>, ". For now it may be easier to use a coordinate shorcut (such as ", <$format, ["tt", [], ["up"], 'do_tt]>, "). To get a list of coordinate shortcuts type ", <$format, ["tt", [], ["@shortcuts"], 'do_tt]>, " now. Note: coordinates are automatically inverted for return exits (so if you specify ", <$format, ["tt", [], ["down"], 'do_tt]>, " the return exit will use the coordinates of ", <$format, ["tt", [], ["up"], 'do_tt]>, ").", <$format, ["hr", [], [], 'do_hr]>], #[['this, $place_lib]]]>]];
var $root manager = $place_lib;
var $root managed = [$place_lib];
var $place_lib default_distance = 250;
var $place_lib opposite_directions = #[["n?orth", 2], ["s?outh", 1], ["e?ast", 4], ["w?est", 3], ["northeast|ne", 7], ["southeast|se", 8], ["southwest|sw", 5], ["northwest|nw", 6], ["up", 10], ["d?own", 9]];
var $place_lib default_exit = $path;
var $place_lib default_path = $path;

public method .is_place() {
    arg obj;
    
    if (!(obj.has_ancestor($place)))
        throw(~place, ("Object \"" + (obj.namef('ref))) + "\" is not a place.");
};

public method .coordinates() {
    arg str;
    var x;
    
    for x in (coordinate_shortcuts) {
        if (str.match_template(x[1]))
            return x[2];
    }
    throw(~coordnf, ("Unable to find coordinate shortcut for \"" + str) + "\".");
};

public method .coordinate_shortcuts() {
    return coordinate_shortcuts;
};

public method .valid_coordinates() {
    arg radial, azimuth;
    
    if ((radial > 360) || (radial < (-1)))
        throw(~invcoord, "Radial coordinate must be from -1 to 360 degrees.");
    if ((azimuth > 90) || (azimuth < (-90)))
        throw(~invcoord, "Azimuth coordinate must be from 90 to -90 degrees.");
};

public method .invert_coordinates() {
    arg radial, azimuth;
    
    radial += 180;
    if (radial > 360)
        radial = radial - 360;
    if (azimuth > 0)
        azimuth = -azimuth;
    else
        azimuth = abs(azimuth);
    return [radial, azimuth];
};

public method .known_realms() {
    return known_realms;
};

public method .match_realm() {
    arg str;
    var r;
    
    for r in ($realm.descendants()) {
        if (r.match_name(str))
            return r;
    }
    return (| $object_lib.to_dbref(str) |) || 0;
};

public method .add_known_realm() {
    arg obj;
    
    (> .perms(sender()) <);
    known_realms += [obj];
};

public method .del_known_realm() {
    arg obj;
    
    (> .perms(sender()) <);
    known_realms = known_realms.setremove(obj);
};

public method .del_build_hint() {
    arg hint_key;
    
    (> .perms(sender()) <);
    build_hints = build_hints.add(hint_key);
};

public method .build_hint() {
    arg hint;
    
    return build_hints[hint];
};

public method .build_hints() {
    return build_hints;
};

public method .add_build_hint() {
    arg hint_key, hint_text;
    
    (> .perms(sender()) <);
    build_hints = build_hints.add(hint_key, hint_text);
};

public method .opposite_direction() {
    arg dir;
    var key, od;
    
    od = opposite_directions;
    for key in (od.keys()) {
        if (match_template(dir, key))
            return (od.keys())[od[key]];
    }
    return 0;
};

public method .set_default() {
    arg what, value;
    
    (> .perms(sender()) <);
    what = tosym("default_" + what);
    return (> get_var(what, value) <);
};

public method .get_default() {
    arg what;
    
    what = tosym("default_" + what);
    return (> get_var(what) <);
};

public method .bfs() {
    arg source, dest;
    var e, p, q, r, s, v;
    
    if (source == dest)
        return [];
    q = [[source, []]];
    v = [];
    while ((q.length()) > 0) {
        p = q[1];
        q = q.delete(1);
        r = p[1];
        v = v + [r];
        for e in ((| r.visible_exits() |) || []) {
            s = e.dest(r);
            if (s in v)
                continue;
            if (s == dest)
                return (p[2]) + [e];
            q = q + [[s, (p[2]) + [e]]];
            refresh();
        }
    }
    throw(~noway, "I can't find a route.");
};

public method .regions() {
    var e, p, q, s, v, regions, source, visited;
    
    regions = [];
    visited = #[];
    for source in ($place.children()) {
        if (visited.contains(source))
            continue;
        q = [source];
        v = [];
        while ((q.length()) > 0) {
            p = q[1];
            q = q.delete(1);
            v = v + [p];
            visited = visited.add(p, 1);
            for e in ((| p.visible_exits() |) || []) {
                s = e.dest(p);
                if (visited.contains(s))
                    continue;
                q = q + [s];
                refresh();
            }
        }
        regions = regions + [v];
    }
    return regions;
};

public method .region() {
    arg source;
    var e, p, q, s, v, visited;
    
    visited = #[];
    q = [source];
    v = [];
    while ((q.length()) > 0) {
        p = q[1];
        q = q.delete(1);
        v = v + [p];
        visited = visited.add(p, 1);
        for e in ((| p.visible_exits() |) || []) {
            s = e.dest(p);
            if (visited.contains(s))
                continue;
            q = q + [s];
            refresh();
        }
    }
    return v;
};

public method .makemap() {
    arg source, @args;
    var dest, e, visited, indent, retval;
    
    visited = (| (args[1]) + [source] |) || [source];
    indent = (| args[2] |) || 0;
    retval = [];
    for e in ((| source.visible_exits() |) || []) {
        dest = e.dest(source);
        retval = retval + [(((("| " * max(0, indent - 1)) + ("+-" * (indent > 0))) + (e.path_name(source))) + " to ") + (dest.namef('ref))];
        if (!(dest in visited)) {
            retval = retval + (.makemap(dest, visited, indent + 1));
            visited = visited + [dest];
        }
        refresh();
    }
    return retval;
};

public method .find_invalid() {
    var l, o, r;
    
    r = [];
    for l in ($location.descendants()) {
        for o in (l.contents()) {
            if ((type(o) == 'objnum) && (!valid(o)))
                r = r + [[l, o]];
        }
    }
    return r;
};


new object $data_lib: $libraries;

var $root manager = $data_lib;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 849996459;
var $root inited = 1;
var $root managed = [$data_lib];
var $root help_node = $help_obj_data_lib;

public method .unparse_indent() {
    arg value;
    var s, i, len;
    
    refresh();
    switch (type(value)) {
        case 'list:
            if (!value)
                return ["[]"];
            s = map i in [1 .. (len = value.length())] to ((.unparse_indent(value[i])).affix((i < len) ? "," : "")).sum();
            s ?= [];
            if (((s.mmap('length)).sum()) < 60) {
                return [("[" + (s.join())) + "]"];
            } else {
                s = s.prefix("  ");
                s = s.replace(1, (s[1]).subrange(3));
                return (["[ "].affix(s)).affix("]");
            }
        case 'dictionary:
            s = map i in [1 .. (len = (value.keys()).length())] to ((.unparse_indent([(value.keys())[i], value[(value.keys())[i]]])).affix((i < len) ? "," : "")).sum();
            s ?= [];
            if (((s.mmap('length)).sum()) < 60) {
                return [("#[" + (s.join())) + "]"];
            } else {
                s = s.prefix("  ");
                s = s.replace(1, (s[1]).subrange(3));
                return (["#["].affix(s)).affix("]");
            }
        case 'frob:
            return (((["<"].affix(class(value))).affix(",")).affix(.unparse_indent(value.value()))).affix(">");
        default:
            return [toliteral(value)];
    }
};

public method .data_map() {
    arg val, method, options, @args;
    var i, args, object, class;
    
    object = (| options['object] |);
    switch (type(val)) {
        case 'list:
            if ((| options['list] |))
                return object ? object.(method)(val, @args) : val.(method)(@args);
            return map i in (val) to (refresh() && (.data_map(i, method, options, @args)));
        case 'dictionary:
            if ((| options['dictionary] |))
                return object ? object.(method)(val, @args) : val.(method)(@args);
            if ((| options['keys] |))
                return hash i in (val) to ([.data_map(i[1], method, options, @args), refresh() && (.data_map(i[2], method, options, @args))]);
            return hash i in (val) to ([i[1], refresh() && (.data_map(i[2], method, options, @args))]);
        case 'frob:
            if ((| (class = options['class]) |)) {
                if ((| class(val) in class |))
                    return object ? object.(method)(val, @args) : val.(method)(@args);
                else
                    return val;
            }
            return (<class(val), (.data_map(val.value(), method, options, @args))>);
        default:
            if ((| options['all] |) || (| options[type(val)] |))
                return object ? object.(method)(val, @args) : val.(method)(@args);
            return val;
    }
};

public method .is_valid_type() {
    arg type;
    
    return type in ['integer, 'float, 'string, 'buffer, 'symbol, 'list, 'objnum, 'dictionary, 'error, 'frob];
};

public method .unparse_indent_html() {
    arg value;
    var chunk, chunk_out, out, object_parse, obj_regexp, line, word;
    
    obj_regexp = "\$[a-zA-Z0-9_]+";
    out = [];
    value = .unparse_indent(value);
    value = value.mmap('html_escape);
    for line in (value) {
        object_parse = line.global_regexp(obj_regexp);
        chunk_out = "";
        while (object_parse) {
            [chunk, (word ?= 0), @object_parse] = object_parse;
            chunk_out += chunk;
            if (word) {
                if ((| $object_lib.to_dbref(word) |))
                    chunk_out += $page_bin_index._make_string_to_display_href(word);
                else
                    chunk_out += word;
            }
        }
        out += [chunk_out];
    }
    return out;
};


new object $filtered_frob: $libraries;

var $root manager = $filtered_frob;
var $filtered_frob default_value = #[['sight, 10], ['hearing, 10]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 860590309;
var $root inited = 1;
var $root managed = [$filtered_frob];

public method .default_value() {
    return default_value;
};

public method .propagate() {
    arg value, prop;
    var i, out, dflt, l, eff, f, n;
    
    if ((type(value) == 'frob) && (class(value) == $message_frob))
        value = .new_with(value, sender());
    out = #[];
    eff = prop.effect();
    f = prop.senses();
    dflt = (f.contains('any)) ? (f['any]) : 1000000;
    n = 0;
    for i in (value) {
        if ((i[1]) in ['message, 'propagator, 'effects]) {
            out = out.add(@i);
        } else {
            if (f.contains(i[1]))
                l = (i[2]) - (f[i[1]]);
            else
                l = (i[2]) - dflt;
            if (l > 0) {
                out = out.add(i[1], l);
                n++;
            }
        }
    }
    if (!n)
        return 0;
    if (eff)
        out = out.add('effects, ((| out.effects() |) || []) + [eff]);
    return (<this(), out>);
};

public method .is_noticed() {
    arg value, f;
    var i;
    
    return find i in [1 .. listlen(value)] where ((value[i]) >= (f[i]));
};

public method .new_with_message() {
    arg msg, sender;
    
    return (<(.this()), (((.default_value()).add('message, msg)).add('propagator, sender))>);
};

public method .new_with() {
    arg msg, sender;
    
    if (type(msg) != 'frob)
        msg = (<$message_frob, msg>);
    return (<this(), (((.default_value()).add('message, msg)).add('propagator, sender))>);
};

public method .message() {
    arg what;
    
    return what['message];
};

public method .effects() {
    arg what;
    
    return (what.contains('effects)) ? (what['effects]) : [];
};

public method .sensory() {
    arg what;
    
    (| (what = what.del('message)) |);
    (| (what = what.del('effects)) |);
    (| (what = what.del('propagator)) |);
    return what;
};


new object $cml_lib: $libraries;

var $root manager = $cml_lib;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863748283;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $cml_lib sep = <$format, ["hr", [["sep", "3"]], [], 'do_hr]>;
var $cml_lib br = <$format, ["br", [], [], 'do_br]>;
var $cml_lib p = <$format, ["p", [], [], 'do_p]>;
var $cml_lib hr = <$format, ["hr", [], [], 'do_hr]>;
var $root managed = [$cml_lib];

public method .format_obj_tag() {
    arg context, object, name, @args;
    var opt, src;
    
    if (args) {
        [opt, (src ?= sender())] = args;
        return (<$format, ["obj", [["context", context], ["name", name], ["options", opt]], [object, src], 'do_obj]>);
    } else {
        return (<$format, ["obj", [["context", context], ["name", name]], [object], 'do_obj]>);
    }
};

public method .format_br_tag() {
    return br;
};

public method .format_table_tag() {
    arg cols, @contents;
    
    return (<$format, ["table", [["cols", cols]], contents, 'do_table]>);
};

public method .format_tr_tag() {
    arg @contents;
    
    return (<$format, ["tr", [], contents, 'do_tr]>);
};

public method .format_td_tag() {
    arg contents, @flags;
    var spanning, color;
    
    return (<$format, ["td", flags, [contents], 'do_td]>);
};

public method .format_hr_tag() {
    return hr;
};

public method .generate_english_tag() {
    arg list;
    
    return (<$generator, ["english", [], list, 'gen_english]>);
};

public method .format_sep_tag() {
    return sep;
};

public method .format_invoke_tag() {
    arg object, method, name;
    
    return (<$format, ["invoke", [["object", object], ["method", method]], [name], 'do_invoke]>);
};

public method .generate_join_tag() {
    arg list, @sep;
    
    [(sep ?= ", ")] = sep;
    return (<$generator, ["join", [["separator", sep]], list, 'gen_join]>);
};

public method .format_pre_tag() {
    arg args;
    
    return (<$format, ["pre", [], [args], 'do_pre]>);
};

public method .format_p_tag() {
    return p;
};

public method .format_subj_tag() {
    arg text, @level;
    
    [(level ?= 4)] = level;
    return (<$format, ["subj", [["level", level]], [text], 'do_subj]>);
};

public method .format_dfn_tag() {
    arg args;
    
    return (<$format, ["dfn", [], args, 'do_dfn]>);
};

public method .fmt_obj() {
    arg context, object, name, @args;
    var opt, src;
    
    if (args) {
        [opt, (src ?= sender())] = args;
        return (<$format, ["obj", [["context", context], ["name", name], ["options", opt]], [object, src], 'do_obj]>);
    } else {
        return (<$format, ["obj", [["context", context], ["name", name]], [object], 'do_obj]>);
    }
};

public method .fmt_br() {
    return br;
};

public method .fmt_table() {
    arg cols, @contents;
    
    return (<$format, ["table", [["cols", cols]], contents, 'do_table]>);
};

public method .fmt_tr() {
    arg @contents;
    
    return (<$format, ["tr", [], contents, 'do_tr]>);
};

public method .fmt_td() {
    arg contents, @flags;
    var spanning, color;
    
    return (<$format, ["td", flags, [contents], 'do_td]>);
};

public method .fmt_hr() {
    arg @flags;
    
    if (flags)
        return (<$format, ["hr", flags, [], 'do_hr]>);
    return hr;
};

public method .gen_english() {
    arg list;
    
    return (<$generator, ["english", [], list, 'gen_english]>);
};

public method .fmt_sep() {
    return sep;
};

public method .fmt_invoke() {
    arg object, method, name;
    
    return (<$format, ["invoke", [["object", object], ["method", method]], [name], 'do_invoke]>);
};

public method .gen_join() {
    arg list, @sep;
    
    [(sep ?= ", ")] = sep;
    return (<$generator, ["join", [["separator", sep]], list, 'gen_join]>);
};

public method .fmt_pre() {
    arg args;
    
    return (<$format, ["pre", [], [args], 'do_pre]>);
};

public method .fmt_p() {
    return p;
};

public method .fmt_subj() {
    arg text, @level;
    
    [(level ?= 4)] = level;
    return (<$format, ["subj", [["level", level]], [text], 'do_subj]>);
};

public method .fmt_dfn() {
    arg args;
    
    return (<$format, ["dfn", [], args, 'do_dfn]>);
};

public method .fmt_href() {
    arg url, str;
    
    return (<$format, ["a", [["href", url]], [str], 'do_href]>);
};

public method .fmt_b() {
    arg contents;
    
    return (<$format, ["b", [], [contents], 'do_b]>);
};

public method .fmt_quote() {
    arg args;
    
    return (<$format, ["quote", [], [args], 'do_quote]>);
};

public method .fmt_textarea() {
    arg contents, @flags;
    
    return (<$format, ["textarea", flags, [contents], 'do_textarea]>);
};

public method .fmt_input() {
    arg @flags;
    
    return (<$format, ["input", flags, [], 'do_input]>);
};

public method .fmt_form() {
    arg form, @flags;
    
    return (<$format, ["form", flags, form, 'do_form]>);
};

public method .format_font_tag() {
    arg text, color;
    
    return (<$format, ["font", [["color", color]], [text], 'do_font]>);
};


new object $http_lib: $libraries;

var $root manager = $http_lib;
var $http_lib errors = #[[400, ["<head><title>400 Bad Request</title></head>", "<body>", "<center><h1>400 Bad Request</h1></center>", "%s", "</body>"]], [403, ["<head><title>403 Permission Denied</title></head>", "<body>", "<center><h1>403 Permission Denied</h1></center>", "%s", "</body>"]], [404, ["<head><title>404 Not Found</title></head>", "<center><h1>404 Not Found</h1></center>", "%s", "</body>"]]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863767420;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $http_lib codes = #[[200, "Ok"], [201, "Created"], [202, "Accepted"], [203, "Provisional Information"], [204, "No Content"], [300, "Multiple Choices"], [301, "Moved Permanently"], [302, "Moved Temporarily"], [303, "See Other"], [304, "Not Modified"], [400, "Bad Request"], [401, "Unauthorized"], [402, "Payment Required"], [403, "Forbidden"], [404, "Not Found"], [405, "Method Not Allowed"], [406, "None Acceptable"], [407, "Proxy Authentication Required"], [408, "Request Timeout"], [409, "Conflict"], [410, "Gone"], [500, "Internal Server Error"], [501, "Not Implemented"], [502, "Bad Gateway"], [503, "Service Unavailable"], [504, "Gateway Timeout"]];
var $http_lib html_version = "text/html";
var $root managed = [$http_lib];

public method .explode_url() {
    arg line;
    var args, i;
    
    i = "?" in line;
    if (i) {
        args = substr(line, i + 1);
        line = substr(line, 1, i - 1);
    }
    if (args)
        return [#[['path, line]], .explode_http_encoding(args)];
    else
        return [#[['path, line]], #[]];
};

public method .explode_http_encoding() {
    arg args;
    var fields, field, values, key, value;
    
    fields = #[];
    
    // temporary hack--we should actually be using .add_elem  --brandon
    for field in (args.explode("&")) {
        field = explode(field, "=");
        key = $http.decode(field[1]);
        if (listlen(field) > 1)
            value = $http.decode(field[2]);
        else
            value = "";
        if (dict_contains(fields, key))
            fields = dict_add(fields, key, ((fields[key]) + ", ") + value);
        else
            fields = dict_add(fields, key, value);
    }
    return fields;
};

public method .html_version() {
    return html_version;
};

public method .get_code() {
    arg c;
    
    return (> codes[c] <);
};

public method .explode_http_encoding2() {
    arg args;
    var fields, field;
    
    fields = #[];
    for field in (args.explode("&")) {
        field = field.explode("=", 1);
        fields = fields.add_elem($http.decode(field[1]), $http.decode(field[2]));
    }
    return fields;
};


new object $converters: $libraries;

var $root manager = $converters;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863769001;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $root managed = [$converters];
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];

public method .to_object() {
    arg string, @required_parent;
    var object, parent;
    
    [(parent ?= $root)] = required_parent;
    object = (| $object_lib.to_dbref(string) |);
    if (!object)
        throw(~objnf, ("Object " + string) + " not found.");
    if (!(object.has_ancestor(parent)))
        throw(~invobj, ((("Object " + string) + ", doesn't have the ancestor, ") + parent) + ".");
    return object;
};

public method .to_num() {
    arg number;
    
    return (> toint(number) <);
};

public method .parse_ref() {
    arg ref, object, flags;
    var lookup_result;
    
    if ((ref[1]) != "$")
        ref = "$" + ref;
    lookup_result = (> $parse_lib.ref(ref, $user) <);
    if ((lookup_result[1]) in flags)
        return lookup_result;
    else
        throw(~type, "Reference was of the improper type");
};

public method .to_boolean() {
    arg string, @extra;
    
    return ((string[1]) == "y") ? 1 : 0;
};

public method .to_help_node() {
    arg string;
    var obj;
    
    catch ~objnf
        obj = (> .to_object(string) <);
    with
        obj = (> .to_object("help_" + string) <);
    if (obj.is($help_node))
        return obj;
    else if (obj.help_node())
        return obj.help_node();
    else
        throw(~invobj, string + " is not a help node and doesn't have an assigned help node.");
};

public method .parse_textarea() {
    arg string;
    
    string = (string.replace($http.decode("%0d"), "")).explode($http.decode("%0a"), 1);
    return string;
};

public method .parse_textarea_joined() {
    arg string;
    
    anticipate_assignment();
    string = strsub(string, $http.decode("%0d"), "");
    string = strsub(string, $http.decode("%0a"), " ");
    return string;
};


new object $security_lib: $libraries;

var $root manager = $security_lib;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 864002483;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $root managed = [$security_lib];
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];

public method .check_userdb_with_password() {
    arg interface;
    var user, auth, req;
    
    if (!(| (auth = interface.get_info('browser_auth)) |))
        return ['basic, (interface.get_info('directory_object)).get_realm()];
    if (!(| (user = $user_db.search((auth[2])[1])) |))
        return [auth[1], (interface.get_info('directory_object)).get_realm()];
    if (!(user.check_password((auth[2])[2])))
        return [auth[1], (interface.get_info('directory_object)).get_realm()];
    interface.set_info('run_as, user);
    return 0;
};

public method .check_userdb_with_optional() {
    arg interface;
    var user, auth;
    
    if (!(| (auth = interface.get_info('browser_auth)) |))
        return 0;
    if (!(| (user = $user_db.search((auth[2])[1])) |))
        return 0;
    if (!(user.check_password((auth[2])[2])))
        return 0;
    interface.set_info('run_as, user);
    return 1;
};

public method .bounce_to_auth() {
    arg interface, destination;
    var user;
    
    if (!(.check_userdb_with_optional(interface)))
        return ['redirect, destination];
    else
        return 0;
};

public method .check_pop3_password() {
    arg maildrop, passwd;
    
    (> .perms(caller(), $pop3_interface) <);
    return maildrop.check_password(passwd);
};

public method .check_password() {
    arg object, passwd, @cinfo;
    
    (> .perms(caller(), $login_interface, $pop3_interface) <);
    return object.check_password(passwd, @cinfo);
};


new object $mime_lib: $libraries;

var $root manager = $mime_lib;
var $mime_lib mime_types = #[["ez", "application/andrew-inset"], ["hqx", "application/mac-binhex40"], ["cpt", "application/mac-compactpro"], ["doc", "application/msword"], ["bin", "application/octet-stream"], ["dms", "application/octet-stream"], ["lha", "application/octet-stream"], ["lzh", "application/octet-stream"], ["exe", "application/octet-stream"], ["class", "application/octet-stream"], ["so", "application/octet-stream"], ["dll", "application/octet-stream"], ["oda", "application/oda"], ["pdf", "application/pdf"], ["ai", "application/postscript"], ["eps", "application/postscript"], ["ps", "application/postscript"], ["smi", "application/smil"], ["smil", "application/smil"], ["mif", "application/vnd.mif"], ["xls", "application/vnd.ms-excel"], ["ppt", "application/vnd.ms-powerpoint"], ["wbxml", "application/vnd.wap.wbxml"], ["wmlc", "application/vnd.wap.wmlc"], ["wmlsc", "application/vnd.wap.wmlscriptc"], ["bcpio", "application/x-bcpio"], ["vcd", "application/x-cdlink"], ["pgn", "application/x-chess-pgn"], ["cpio", "application/x-cpio"], ["csh", "application/x-csh"], ["dcr", "application/x-director"], ["dir", "application/x-director"], ["dxr", "application/x-director"], ["dvi", "application/x-dvi"], ["spl", "application/x-futuresplash"], ["gtar", "application/x-gtar"], ["hdf", "application/x-hdf"], ["js", "application/x-javascript"], ["skp", "application/x-koan"], ["skd", "application/x-koan"], ["skt", "application/x-koan"], ["skm", "application/x-koan"], ["latex", "application/x-latex"], ["nc", "application/x-netcdf"], ["cdf", "application/x-netcdf"], ["sh", "application/x-sh"], ["shar", "application/x-shar"], ["swf", "application/x-shockwave-flash"], ["sit", "application/x-stuffit"], ["sv4cpio", "application/x-sv4cpio"], ["sv4crc", "application/x-sv4crc"], ["tar", "application/x-tar"], ["tcl", "application/x-tcl"], ["tex", "application/x-tex"], ["texinfo", "application/x-texinfo"], ["texi", "application/x-texinfo"], ["t", "application/x-troff"], ["tr", "application/x-troff"], ["roff", "application/x-troff"], ["man", "application/x-troff-man"], ["me", "application/x-troff-me"], ["ms", "application/x-troff-ms"], ["ustar", "application/x-ustar"], ["src", "application/x-wais-source"], ["zip", "application/zip"], ["au", "audio/basic"], ["snd", "audio/basic"], ["mid", "audio/midi"], ["midi", "audio/midi"], ["kar", "audio/midi"], ["mpga", "audio/mpeg"], ["mp2", "audio/mpeg"], ["mp3", "audio/mpeg"], ["aif", "audio/x-aiff"], ["aiff", "audio/x-aiff"], ["aifc", "audio/x-aiff"], ["ram", "audio/x-pn-realaudio"], ["rm", "audio/x-pn-realaudio"], ["rpm", "audio/x-pn-realaudio-plugin"], ["ra", "audio/x-realaudio"], ["wav", "audio/x-wav"], ["pdb", "chemical/x-pdb"], ["xyz", "chemical/x-xyz"], ["bmp", "image/bmp"], ["gif", "image/gif"], ["ief", "image/ief"], ["jpeg", "image/jpeg"], ["jpg", "image/jpeg"], ["jpe", "image/jpeg"], ["png", "image/png"], ["tiff", "image/tiff"], ["tif", "image/tiff"], ["wbmp", "image/vnd.wap.wbmp"], ["ras", "image/x-cmu-raster"], ["pnm", "image/x-portable-anymap"], ["pbm", "image/x-portable-bitmap"], ["pgm", "image/x-portable-graymap"], ["ppm", "image/x-portable-pixmap"], ["rgb", "image/x-rgb"], ["xbm", "image/x-xbitmap"], ["xpm", "image/x-xpixmap"], ["xwd", "image/x-xwindowdump"], ["igs", "model/iges"], ["iges", "model/iges"], ["msh", "model/mesh"], ["mesh", "model/mesh"], ["silo", "model/mesh"], ["wrl", "model/vrml"], ["vrml", "model/vrml"], ["css", "text/css"], ["html", "text/html"], ["htm", "text/html"], ["asc", "text/plain"], ["txt", "text/plain"], ["rtx", "text/richtext"], ["rtf", "text/rtf"], ["sgml", "text/sgml"], ["sgm", "text/sgml"], ["tsv", "text/tab-separated-values"], ["wml", "text/vnd.wap.wml"], ["wmls", "text/vnd.wap.wmlscript"], ["etx", "text/x-setext"], ["xml", "text/xml"], ["mpeg", "video/mpeg"], ["mpg", "video/mpeg"], ["mpe", "video/mpeg"], ["qt", "video/quicktime"], ["mov", "video/quicktime"], ["avi", "video/x-msvideo"], ["movie", "video/x-sgi-movie"], ["ice", "x-conference/x-cooltalk"]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 885275032;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $root trusted_by = [$file];
var $root managed = [$mime_lib];

public method .mime_type() {
    arg filename;
    var ext;
    
    ext = substr(filename, stridx(filename, ".", -1) + 1);
    catch ~keynf
        return mime_types[ext];
    with
        return "text/plain";
};

public method .rehash() {
    var line, i, f;
    
    (> .perms(sender(), 'system) <);
    $file.open("/mime.types");
    mime_types = #[];
    catch ~eof {
        while (1) {
            line = $file.fread();
            if (line && ((line[1]) != "#")) {
                line = line.explode();
                for i in (line.subrange(2))
                    mime_types = mime_types.add(i, line[1]);
            }
        }
    }
    $file.close();
};


new object $float: $libraries;

var $root manager = $float;
var $float powers_of_ten = [10.0, 100.0, 1000.0, 10000.0, 100000.0, 1e+06];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 909982362;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $root help_node = $help_obj_float;
var $root managed = [$float];

public method .floor() {
    arg float;
    
    return tofloat(toint(float));
};

public method .ceiling() {
    arg float;
    
    return tofloat(toint(float) + 1);
};

public method .round() {
    arg float;
    
    return round(float);
};

public method .round_to() {
    arg float, places;
    var place_value;
    
    if ((places < 1) || (places > 6))
        throw(~range, "Second argument must between 1 and 6.");
    place_value = powers_of_ten[places];
    return round(float * place_value) / place_value;
};

public method .to_integer() {
    arg float;
    
    return toint(float);
};

public method .log() {
    arg base, value;
    
    return log(value) / log(base);
};

public method .fractional_part() {
    arg float;
    
    return abs(float - toint(float));
};


new object $directories: $core;

var $root manager = $directories;
var $directories lock = 0;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 863765302;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $directories entries = #[["home", $page_home_index], ["bin", $page_bin_index], ["~", $page_home_index], ["desktop", $page_desktop_login], ["ar", $page_ar], ["file", $page_file_index], ["", $page_root_index], ["set", $page_set]];
var $directories default_page = $page_root_index;
var $root managed = [$directories];
var $root defined_settings = #[["default-page", #[['get, ['get_default_page]], ['set, ['set_default_page]], ['parse, ['parse_default_page]]]], ["http-auth-realm", #[['get, ['get_http_auth_realm]], ['set, ['set_http_auth_realm]]]], ["default-css", #[['get, ['get_default_css]], ['set, ['set_default_css]], ['parse, ['is_type, 'string]]]], ["server-name-img", #[['get, ['get_server_name_img]], ['set, ['set_server_name_img]], ['parse, ['is_type, 'string]]]]];
var $directories http_auth_realm = "the Cold Dark";
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
var $directories default_css = "tcd.css";
var $directories server_name_img = "";

public method .find_page() {
    arg orig_url, interface;
    var url, page;
    
    url = orig_url.explode("/");
    if ((| ((url[1])[1]) == "~" |))
        url = ["~", (url[1]).subrange(2), @url.subrange(2)];
    
    // hit the directories before objects, allow them to override
    if ((page = (> .find_page__mapped(url, interface, orig_url) <)) != 'pagenf)
        return page;
    return (> .find_page__objref(url, interface) <);
};

public method .default_page() {
    return default_page;
};

public method .get_lock() {
    return lock;
};

root method .init_directories() {
    entries = #[];
    default_page = $page_root_index;
};

public method .build_header() {
    arg header, info, args, @opts;
    var title, head, css, out;
    
    title = $motd.server_name();
    [(opts ?= #[])] = opts;
    if (dict_contains(opts, 'title))
        title += ": " + (opts['title]);
    out = ["<head>", ("<title>" + title) + "</title>"];
    if ((css = .get_default_css()))
        out += [("<link rel=\"stylesheet\" href=\"/file/" + css) + "\">"];
    if (dict_contains(opts, 'header))
        out += opts['header];
    out += ["</head>"];
    if (!dict_contains(opts, 'nobody))
        out += ["<body>"];
    return out;
};

public method .build_footer() {
    arg header, info, args, @opts;
    
    return [("<hr size=1 noshade><a target=_top href=\"/\">" + ($motd.server_name())) + "</a></body>"];
};

public method .get_realm() {
    return http_auth_realm || ($motd.server_name());
};

public method .entry() {
    arg str;
    
    return (> entries[str] <);
};

root method .uninit_directories() {
    lock = 0;
    entries = 0;
    default_page = 0;
};

root method .core_directories() {
    var elem;
    
    for elem in (entries) {
        if (!valid(elem[2]))
            entries = entries.del(elem[1]);
    }
};

public method .parse_default_page() {
    arg value, @args;
    var object;
    
    catch ~objnf, ~namenf, ~invdbref {
        object = $object_lib.to_dbref(value);
        if (object.is($page))
            return object;
    } with {
        throw(~check, "default-page must be a valid descendant of $page.");
    }
    throw(~check, "default-page must be a valid descendant of $page.");
};

public method .get_default_page() {
    arg name, definer;
    
    return default_page;
};

public method .set_default_page() {
    arg name, definer, value;
    
    default_page = value;
};

public method .entries() {
    return entries;
};

public method .add_entry() {
    arg name, target;
    
    entries = entries.add(name, target);
};

public method .del_entry() {
    arg name;
    
    entries = (> entries.del(name) <);
};

public method .set_http_auth_realm() {
    arg name, definer, value;
    
    http_auth_realm = value;
};

public method .get_http_auth_realm() {
    arg name, definer;
    
    return http_auth_realm || ($motd.server_name());
};

public method .find_page__objref() {
    arg url, interface;
    var page, script_name, meth, found, lock, obj;
    
    script_name = "";
    if ((| (obj = $object_lib.to_dbref(url[1])) |)) {
        page = obj;
        script_name += "/" + (url[1]);
        url = url.subrange(2);
        if ((| (meth = tosym(url[1])) |)) {
            if ((| page.find_method(meth) |)) {
                interface.set_info('generate, meth);
                script_name += "/" + (url[1]);
                url = url.subrange(2);
                found = 1;
                if ((page.has_ancestor($page)) && (page.get_lock()))
                    lock = page;
            } else {
                return 'pagenf;
            }
        } else if ((| page.find_method('generate) |)) {
            interface.set_info('generate, 'generate);
            script_name;
            found = 1;
            if ((page.has_ancestor($page)) && (page.get_lock()))
                lock = page;
        } else {
            return 'pagenf;
        }
        interface.set_info('script_name, script_name);
        interface.set_info('path_info, "/" + (url.join("/")));
        interface.set_info('directory_object, $directories);
        interface.set_info('lock_object, lock);
        return page;
    }
    return 'pagenf;
};

public method .find_page__mapped() {
    arg url, interface, orig_url;
    var dir, lock, page, script_name, meth;
    
    script_name = "";
    dir = $directories;
    page = $directories;
    if (dir.get_lock())
        lock = dir;
    catch ~keynf {
        while (url && (page.has_ancestor($directories))) {
            page = dir.entry(url[1]);
            script_name += "/" + (url[1]);
            url = url.subrange(2);
            if (page.get_lock())
                lock = page;
            if (page.has_ancestor($directories))
                dir = page;
        }
    }
    if (page.has_ancestor($directories)) {
        if ((!url) && ((orig_url.last()) != "/")) {
            return ['redirect, orig_url + "/"];
        } else {
            if (url)
                return 'pagenf;
            page = page.default_page();
            if (page.get_lock())
                lock = page;
        }
    }
    if (url && (| (meth = tosym(url[1])) |)) {
        if ((| page.find_method(meth) |)) {
            interface.set_info('generate, meth);
            script_name += "/" + (url[1]);
            url = url.subrange(2);
        } else {
            interface.set_info('generate, 'generate);
        }
    } else {
        interface.set_info('generate, 'generate);
    }
    if (page) {
        interface.set_info('script_name, script_name);
        interface.set_info('path_info, "/" + (url.join("/")));
        interface.set_info('directory_object, dir);
        interface.set_info('lock_object, lock);
        return page;
    } else {
        return 'pagenf;
    }
};

public method .get_default_css() {
    arg @args;
    
    return default_css;
};

public method .get_server_name_img() {
    arg @args;
    
    return server_name_img;
};

protected method .set_default_css() {
    arg name, definer, value, @args;
    
    // called by @set
    default_css = value;
};

public method .set_server_name_img() {
    arg name, definer, value, @args;
    
    server_name_img = value;
};


new object $dir_desktop: $directories;

var $root manager = $dir_desktop;
var $directories lock = [$security_lib, 'bounce_to_auth, ["/login"]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 864277943;
var $dmi_data descriptions = #[];
var $directories entries = #[["web_prefs", $page_set]];
var $directories default_page = $page_desktop_login;
var $root inited = 1;
var $root managed = [$dir_desktop];
var $directories http_auth_realm = 0;


new object $group: $root;

var $root manager = $group;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 904653573;
var $root inited = 1;
var $root defined_settings = #[["group", #[['get, ['get_group]], ['set, ['set_group]], ['parse, ['parse_group]], ['format, ['format_group]]]]];
var $group group = #[];
var $root managed = [$group];

public method .get_group() {
    arg @args;
    
    return group;
};

protected method .set_group() {
    arg name, definer, value;
    
    if (this() == definer())
        throw(~invgroup, "You cannot change the base group " + definer());
    switch (value[1]) {
        case 'set:
            group = value[2];
        case 'add:
            group = dict_add(group, value[2], 1);
        case 'del:
            group = dict_del(group, value[2]);
        default:
            throw(~type, "Unknown action: " + (value[1]));
    }
};

public method .del_from_group() {
    arg target;
    
    (> .perms(sender()) <);
    group = dict_del(group, target);
};

root method .init_group() {
    group = #[];
};

public method .includes() {
    arg target;
    
    if (!dict_contains(group, target)) {
        if (this() == definer())
            return 0;
    
        //   if (this() == definer())
        //       return $sys.is_system(target);
        return (parents()[1]).includes(target);
    }
    return 1;
};

public method .add_to_group() {
    arg target;
    
    (> .perms(sender()) <);
    group = dict_add(group, target, 1);
};

root method .uninit_group() {
    if (sender() != definer())
        clear_var('group);
    else
        group = #[];
};

public method .parse_group() {
    arg value, @args;
    var action, list, item, out;
    
    if (value && ((value[1]) in ["+", "-"])) {
        if ((value[1]) == "-")
            action = 'del;
        else
            action = 'add;
        list = [substr(value, 2)];
    } else {
        action = 'set;
        list = value.explode_english_list();
    }
    out = hash item in (list) to ([(> $object_lib.to_dbref(item) <), 1]);
    if (action == 'set)
        return [action, out];
    else
        return [action, dict_keys(out)[1]];
};

public method .format_group() {
    arg data;
    
    return join(dict_keys(data), ", ");
};

public method .parse_grouplist() {
    arg value, method, @args;
    var action, list, item, out;
    
    if (value && ((value[1]) in ["+", "-"])) {
        if ((value[1]) == "-")
            action = 'del;
        else
            action = 'add;
        list = [substr(value, 2)];
    } else {
        action = 'set;
        list = value.explode_english_list();
    }
    out = #[];
    for item in (list) {
        if (method) {
            catch ~methodnf
                item = (> sender().(method)(item, action, @args) <);
            with
                item = (> .(method)(item, action, @args) <);
        }
        out = dict_add(out, item, 1);
    }
    if (action == 'set)
        return [action, out];
    else
        return [action, out[1]];
};

public method .is_group() {
    return 1;
};

public method .name() {
    arg @args;
    var n, x;
    
    n = tostr(.objname());
    if ((x = stridx(n, "_group", -1)) > 1)
        return substr(n, 1, x - 1);
    return n;
};


new object $core_group: $group;

var $root manager = $core_group;
var $root managed = [$core_group];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 904657222;
var $root inited = 1;
var $group group = #[];


new object $create_for_others_group: $core_group;

var $root manager = $create_for_others_group;
var $root managed = [$create_for_others_group];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 904657034;
var $root inited = 1;
var $group group = #[];


new object $create_for_sender_group: $create_for_others_group;

var $root manager = $create_for_sender_group;
var $root managed = [$create_for_sender_group];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 904657041;
var $root inited = 1;
var $group group = #[];


new object $syslog_group: $core_group;

var $root manager = $syslog_group;
var $root managed = [$syslog_group];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 904656992;
var $root inited = 1;
var $group group = #[[$daemon, 1], [$connection, 1], [$dns, 1], [$guest, 1], [$user, 1], [$body, 1], [$sys, 1], [$root, 1], [$login_interface, 1], [$http_interface, 1], [$connection_interface, 1]];


new object $changelog_group: $core_group;

var $root manager = $changelog_group;
var $root managed = [$changelog_group];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 906983574;
var $group group = #[[$root, 1]];
var $root inited = 1;


new object $systrust_group: $core_group;

var $root manager = $systrust_group;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 913800511;
var $group group = #[[$scheduler, 1], [$directories, 1]];
var $root inited = 1;
var $root managed = [$systrust_group];


new object $staff_group: $group;

var $root manager = $staff_group;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 904657230;
var $root inited = 1;
var $root managed = [$staff_group];
var $group group = #[];


new object $building_group: $staff_group;

var $root manager = $building_group;
var $root flags = ['variables, 'methods, 'code, 'fertile, 'core];
var $root created_on = 904655977;
var $group group = #[];
var $root inited = 1;
var $root managed = [$building_group];


new object $programming_group: $staff_group;

var $root manager = $programming_group;
var $root managed = [$programming_group];
var $root flags = ['variables, 'methods, 'code, 'fertile, 'core];
var $root created_on = 904657855;
var $root inited = 1;
var $group group = #[];


new object $conditional_group: $group;

var $root manager = $conditional_group;
var $root flags = ['variables, 'methods, 'code, 'fertile, 'core];
var $root created_on = 904657262;
var $root inited = 1;
var $root managed = [$conditional_group];
var $group group = <$false_lock_frob, #[]>;

public method .includes() {
    arg target;
    
    if (!((.get_group()).try(target))) {
        if (this() == definer())
            return $sys.is_system(target);
        return (parents()[1]).includes(target);
    }
    return 1;
};

protected method .set_group() {
    arg name, definer, value;
    var list;
    
    // just ignore any itemlist stuff
    value = value[2];
    if ((type(value) != 'frob) || (!(frob_class(value).is($logic_frob))))
        throw(~invlogic, "Conditional groups must be set as $logic_frobs");
    pass(name, definer, ['set, value]);
};

public method .del_from_group() {
    arg target;
    
    // do something, quick... perhaps throw an error 
    throw(~invlogic, "You can only set conditional groups with @set group:group=...");
};

public method .add_to_group() {
    arg target;
    
    // do something, quick... perhaps throw an error
    throw(~invlogic, "You can only set conditional groups with @set group:group=...");
};

root method .init_conditional_group() {
    .set_group(0, 0, ['set, $false_lock_frob.new()]);
};

public method .parse_group() {
    arg value, @args;
    
    if (value in ["none", "nobody"])
        value = "no";
    else if (value in ["anybody", "everybody"])
        value = "yes";
    return ['set, (> $lock_frob.parse(value, user() || this()) <)];
};

root method .format_group() {
    arg value;
    var unparse;
    
    unparse = value.unparse();
    if (unparse == "yes")
        return "anybody";
    else if (unparse == "no")
        return "nobody";
    return unparse;
};