Commit Diff


commit - 9f1fdc128738b2ed76258ac22a8574c681f3df3a
commit + d1f529f46f957c78a3db73b42c2fcd2d3c9f8a34
blob - /dev/null
blob + f50c348ab07a49e6da41b215e2de6f7ba1d44315 (mode 644)
--- /dev/null
+++ src/cmd/upas/alias/aliasmail.c
@@ -0,0 +1,281 @@
+#include "common.h"
+
+/*
+ *  WARNING!  This turns all upper case names into lower case
+ *  local ones.
+ */
+
+/* predeclared */
+static String	*getdbfiles(void);
+static int	translate(char*, char**, String*, String*);
+static int	lookup(String**, String*, String*);
+static int	compare(String*, char*);
+static char*	mklower(char*);
+
+static int debug;
+static int from;
+static char *namefiles = "namefiles";
+#define DEBUG if(debug)
+
+/* loop through the names to be translated */
+void
+main(int argc, char *argv[])
+{
+	String *s;
+	String *alias;		/* the alias for the name */
+	char **names;		/* names of this system */
+	String *files;		/* list of files to search */
+	int i, rv;
+	char *p;
+
+	ARGBEGIN {
+	case 'd':
+		debug = 1;
+		break;
+	case 'f':
+		from = 1;
+		break;
+	case 'n':
+		namefiles = ARGF();
+		break;
+	} ARGEND
+	if (chdir(unsharp(UPASLIB)) < 0) {
+		perror("translate(chdir):");
+		exit9(1);
+	}
+
+	/* get environmental info */
+	names = sysnames_read();
+	files = getdbfiles();
+	alias = s_new();
+
+	/* loop through the names to be translated (from standard input) */
+	for(i=0; i<argc; i++) {
+		s = unescapespecial(s_copy(mklower(argv[i])));
+		if(strchr(s_to_c(s), '!') == 0)
+			rv = translate(s_to_c(s), names, files, alias);
+		else
+			rv = -1;
+		if(from){
+			if (rv >= 0 && *s_to_c(alias) != '\0'){
+				p = strchr(s_to_c(alias), '\n');
+				if(p)
+					*p = 0;
+				p = strchr(s_to_c(alias), '!');
+				if(p) {
+					*p = 0;
+					print("%s", s_to_c(alias));
+				} else {
+					p = strchr(s_to_c(alias), '@');
+					if(p)
+						print("%s", p+1);
+					else
+						print("%s", s_to_c(alias));
+				}
+			}
+		} else {
+			if (rv < 0 || *s_to_c(alias) == '\0')
+				print("local!%s\n", s_to_c(s));
+			else {
+				/* this must be a write, not a print */
+				write(1, s_to_c(alias), strlen(s_to_c(alias)));
+			}
+		}
+		s_free(s);
+	}
+	exits(0);
+}
+
+/* get the list of dbfiles to search */
+static String *
+getdbfiles(void)
+{
+	Sinstack *sp;
+	String *files = s_new();
+	char *nf;
+
+	if(from)
+		nf = "fromfiles";
+	else
+		nf = namefiles;
+
+	/* system wide aliases */
+	if ((sp = s_allocinstack(nf)) != 0){
+		while(s_rdinstack(sp, files))
+			s_append(files, " ");
+		s_freeinstack(sp);
+	}
+
+
+	DEBUG print("files are %s\n", s_to_c(files));
+
+	return files;
+}
+
+/* loop through the translation files */
+static int
+translate(char *name,		/* name to translate */
+	char **namev,		/* names of this system */
+	String *files,		/* names of system alias files */
+	String *alias)		/* where to put the alias */
+{
+	String *file = s_new();
+	String **fullnamev;
+	int n, rv;
+
+	rv = -1;
+
+	DEBUG print("translate(%s, %s, %s)\n", name,
+		s_to_c(files), s_to_c(alias));
+
+	/* create the full name to avoid loops (system!name) */
+	for(n = 0; namev[n]; n++)
+		;
+	fullnamev = (String**)malloc(sizeof(String*)*(n+2));
+	n = 0;
+	fullnamev[n++] = s_copy(name);
+	for(; *namev; namev++){
+		fullnamev[n] = s_copy(*namev);
+		s_append(fullnamev[n], "!");
+		s_append(fullnamev[n], name);
+		n++;
+	}
+	fullnamev[n] = 0;
+
+	/* look at system-wide names */
+	s_restart(files);
+	while (s_parse(files, s_restart(file)) != 0) {
+		if (lookup(fullnamev, file, alias)==0) {
+			rv = 0;
+			goto out;
+		}
+	}
+
+out:
+	for(n = 0; fullnamev[n]; n++)
+		s_free(fullnamev[n]);
+	s_free(file);
+	free(fullnamev);
+	return rv;
+}
+
+/*
+ *  very dumb conversion to bang format
+ */
+static String*
+attobang(String *token)
+{
+	char *p;
+	String *tok;
+
+	p = strchr(s_to_c(token), '@');
+	if(p == 0)
+		return token;
+
+	p++;
+	tok = s_copy(p);
+	s_append(tok, "!");
+	s_nappend(tok, s_to_c(token), p - s_to_c(token) - 1);
+
+	return tok;
+}
+
+/*  Loop through the entries in a translation file looking for a match.
+ *  Return 0 if found, -1 otherwise.
+ */
+static int
+lookup(
+	String **namev,
+	String *file,
+	String *alias)	/* returned String */
+{
+	String *line = s_new();
+	String *token = s_new();
+	String *bangtoken;
+	int i, rv = -1;
+	char *name =  s_to_c(namev[0]);
+	Sinstack *sp;
+
+	DEBUG print("lookup(%s, %s, %s, %s)\n", s_to_c(namev[0]), s_to_c(namev[1]),
+		s_to_c(file), s_to_c(alias));
+
+	s_reset(alias);
+	if ((sp = s_allocinstack(s_to_c(file))) == 0)
+		return -1;
+
+	/* look for a match */
+	while (s_rdinstack(sp, s_restart(line))!=0) {
+		DEBUG print("line is %s\n", s_to_c(line));
+		s_restart(token);
+		if (s_parse(s_restart(line), token)==0)
+			continue;
+		if (compare(token, "#include")==0){
+			if(s_parse(line, s_restart(token))!=0) {
+				if(lookup(namev, line, alias) == 0)
+					break;
+			}
+			continue;
+		}
+		if (compare(token, name)!=0)
+			continue;
+		/* match found, get the alias */
+		while(s_parse(line, s_restart(token))!=0) {
+			bangtoken = attobang(token);
+
+			/* avoid definition loops */
+			for(i = 0; namev[i]; i++)
+				if(compare(bangtoken, s_to_c(namev[i]))==0) {
+					s_append(alias, "local");
+					s_append(alias, "!");
+					s_append(alias, name);
+					break;
+				}
+
+			if(namev[i] == 0)
+				s_append(alias, s_to_c(token));
+			s_append(alias, "\n");
+
+			if(bangtoken != token)
+				s_free(bangtoken);
+		}
+		rv = 0;
+		break;
+	}
+	s_free(line);
+	s_free(token);
+	s_freeinstack(sp);
+	return rv;
+}
+
+#define lower(c) ((c)>='A' && (c)<='Z' ? (c)-('A'-'a'):(c))
+
+/* compare two Strings (case insensitive) */
+static int
+compare(String *s1,
+	char *p2)
+{
+	char *p1 = s_to_c(s1);
+	int rv;
+
+	DEBUG print("comparing %s to %s\n", p1, p2);
+	while((rv = lower(*p1) - lower(*p2)) == 0) {
+		if (*p1 == '\0')
+			break;
+		p1++;
+		p2++;
+	}
+	return rv;
+}
+
+static char*
+mklower(char *name)
+{
+	char *p;
+	char c;
+
+	for(p = name; *p; p++){
+		c = *p;
+		*p = lower(c);
+	}
+	return name;
+}
blob - /dev/null
blob + d7f8f91c46d48191b3de42d5e41d3792e438e035 (mode 644)
--- /dev/null
+++ src/cmd/upas/alias/mkfile
@@ -0,0 +1,21 @@
+<$PLAN9/src/mkhdr
+
+TARG=aliasmail
+
+OFILES=aliasmail.$O\
+
+LIB=../common/libcommon.a\
+
+HFILES=../common/common.h\
+	 ../common/sys.h\
+
+
+BIN=$PLAN9/bin/upas
+
+UPDATE=\
+	mkfile\
+	$HFILES\
+	${OFILES:%.$O=%.c}\
+
+<$PLAN9/src/mkone
+CFLAGS=$CFLAGS -I../common
blob - /dev/null
blob + 6be960ff67b826cfc544f9e8ef2c24af9df76c00 (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/addhash.c
@@ -0,0 +1,66 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <regexp.h>
+#include "hash.h"
+
+Hash hash;
+
+void
+usage(void)
+{
+	fprint(2, "addhash [-o out] file scale [file scale]...\n");
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	int i, fd, n;
+	char err[ERRMAX], *out;
+	Biobuf *b, bout;
+
+	out = nil;
+	ARGBEGIN{
+	case 'o':
+		out = EARGF(usage());
+		break;
+	default:
+		usage();
+	}ARGEND;
+
+	if(argc==0 || argc%2)
+		usage();
+
+	while(argc > 0){
+		if((b = Bopenlock(argv[0], OREAD)) == nil)
+			sysfatal("open %s: %r", argv[0]);
+		n = atoi(argv[1]);
+		if(n == 0)
+			sysfatal("0 scale given");
+		Breadhash(b, &hash, n);
+		Bterm(b);
+		argv += 2;
+		argc -= 2;
+	}
+
+	fd = 1;
+	if(out){
+		for(i=0; i<120; i++){
+			if((fd = create(out, OWRITE, 0666|DMEXCL)) >= 0)
+				break;
+			rerrstr(err, sizeof err);
+			if(strstr(err, "file is locked")==nil && strstr(err, "exclusive lock")==nil)
+				break;
+			sleep(1000);
+		}
+		if(fd < 0)
+			sysfatal("could not open %s: %r\n", out);
+	}
+		
+	Binit(&bout, fd, OWRITE);
+	Bwritehash(&bout, &hash);
+	Bterm(&bout);
+	exits(0);
+}
+
blob - /dev/null
blob + a040429065e7346fb2fbb8200e93b4dafec28669 (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/bayes.c
@@ -0,0 +1,232 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <regexp.h>
+#include "hash.h"
+
+enum
+{
+	MAXTAB = 256,
+	MAXBEST = 32,
+};
+
+typedef struct Table Table;
+struct Table
+{
+	char *file;
+	Hash *hash;
+	int nmsg;
+};
+
+typedef struct Word Word;
+struct Word
+{
+	Stringtab *s;	/* from hmsg */
+	int count[MAXTAB];	/* counts from each table */
+	double p[MAXTAB];	/* probabilities from each table */
+	double mp;	/* max probability */
+	int mi;		/* w.p[w.mi] = w.mp */
+};
+
+Table tab[MAXTAB];
+int ntab;
+
+Word best[MAXBEST];
+int mbest;
+int nbest;
+
+int debug;
+
+void
+usage(void)
+{
+	fprint(2, "usage: bayes [-D] [-m maxword] boxhash ... ~ msghash ...\n");
+	exits("usage");
+}
+
+void*
+emalloc(int n)
+{
+	void *v;
+
+	v = mallocz(n, 1);
+	if(v == nil)
+		sysfatal("out of memory");
+	return v;
+}
+
+void
+noteword(Word *w)
+{
+	int i;
+
+	for(i=nbest-1; i>=0; i--)
+		if(w->mp < best[i].mp)
+			break;
+	i++;
+
+	if(i >= mbest)
+		return;
+	if(nbest == mbest)
+		nbest--;
+	if(i < nbest)
+		memmove(&best[i+1], &best[i], (nbest-i)*sizeof(best[0]));
+	best[i] = *w;
+	nbest++;
+}
+
+Hash*
+hread(char *s)
+{
+	Hash *h;
+	Biobuf *b;
+
+	if((b = Bopenlock(s, OREAD)) == nil)
+		sysfatal("open %s: %r", s);
+
+	h = emalloc(sizeof(Hash));
+	Breadhash(b, h, 1);
+	Bterm(b);
+	return h;
+}
+
+void
+main(int argc, char **argv)
+{
+	int i, j, a, mi, oi, tot, keywords;
+	double totp, p, xp[MAXTAB];
+	Hash *hmsg;
+	Word w;
+	Stringtab *s, *t;
+	Biobuf bout;
+
+	mbest = 15;
+	keywords = 0;
+	ARGBEGIN{
+	case 'D':
+		debug = 1;
+		break;
+	case 'k':
+		keywords = 1;
+		break;
+	case 'm':
+		mbest = atoi(EARGF(usage()));
+		if(mbest > MAXBEST)
+			sysfatal("cannot keep more than %d words", MAXBEST);
+		break;
+	default:
+		usage();
+	}ARGEND
+
+	for(i=0; i<argc; i++)
+		if(strcmp(argv[i], "~") == 0)
+			break;
+
+	if(i > MAXTAB)
+		sysfatal("cannot handle more than %d tables", MAXTAB);
+
+	if(i+1 >= argc)
+		usage();
+
+	for(i=0; i<argc; i++){
+		if(strcmp(argv[i], "~") == 0)
+			break;
+		tab[ntab].file = argv[i];
+		tab[ntab].hash = hread(argv[i]);
+		s = findstab(tab[ntab].hash, "*nmsg*", 6, 1);
+		if(s == nil || s->count == 0)
+			tab[ntab].nmsg = 1;
+		else
+			tab[ntab].nmsg = s->count;
+		ntab++;
+	}
+
+	Binit(&bout, 1, OWRITE);
+
+	oi = ++i;
+	for(a=i; a<argc; a++){
+		hmsg = hread(argv[a]);
+		nbest = 0;
+		for(s=hmsg->all; s; s=s->link){
+			w.s = s;
+			tot = 0;
+			totp = 0.0;
+			for(i=0; i<ntab; i++){
+				t = findstab(tab[i].hash, s->str, s->n, 0);
+				if(t == nil)
+					w.count[i] = 0;
+				else
+					w.count[i] = t->count;
+				tot += w.count[i];
+				p = w.count[i]/(double)tab[i].nmsg;
+				if(p >= 1.0)
+					p = 1.0;
+				w.p[i] = p;
+				totp += p;
+			}
+
+			if(tot < 5){		/* word does not appear enough; give to box 0 */
+				w.p[0] = 0.5;
+				for(i=1; i<ntab; i++)
+					w.p[i] = 0.1;
+				w.mp = 0.5;
+				w.mi = 0;
+				noteword(&w);
+				continue;
+			}
+
+			w.mp = 0.0;
+			for(i=0; i<ntab; i++){
+				p = w.p[i];
+				p /= totp;
+				if(p < 0.01)
+					p = 0.01;
+				else if(p > 0.99)
+					p = 0.99;
+				if(p > w.mp){
+					w.mp = p;
+					w.mi = i;
+				}
+				w.p[i] = p;
+			}
+			noteword(&w);
+		}
+
+		totp = 0.0;
+		for(i=0; i<ntab; i++){
+			p = 1.0;
+			for(j=0; j<nbest; j++)
+				p *= best[j].p[i];
+			xp[i] = p;
+			totp += p;
+		}
+		for(i=0; i<ntab; i++)
+			xp[i] /= totp;
+		mi = 0;
+		for(i=1; i<ntab; i++)
+			if(xp[i] > xp[mi])
+				mi = i;
+		if(oi != argc-1)
+			Bprint(&bout, "%s: ", argv[a]);
+		Bprint(&bout, "%s %f", tab[mi].file, xp[mi]);
+		if(keywords){
+			for(i=0; i<nbest; i++){
+				Bprint(&bout, " ");
+				Bwrite(&bout, best[i].s->str, best[i].s->n);
+				Bprint(&bout, " %f", best[i].p[mi]);
+			}
+		}
+		freehash(hmsg);
+		Bprint(&bout, "\n");
+		if(debug){
+			for(i=0; i<nbest; i++){
+				Bwrite(&bout, best[i].s->str, best[i].s->n);
+				Bprint(&bout, " %f", best[i].p[mi]);
+				if(best[i].p[mi] < best[i].mp)
+					Bprint(&bout, " (%f %s)", best[i].mp, tab[best[i].mi].file);
+				Bprint(&bout, "\n");
+			}
+		}
+	}
+	Bterm(&bout);
+}
blob - /dev/null
blob + b1dd8b26ef4786e9dc464f5320d37bf084d73831 (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/classify.re
@@ -0,0 +1,403 @@
+# dreprog
+7 27 0 6 0 6
+0 1 1 0 0
+1 0 1 0 0
+0 0 5 0 0 32 1 33 0 65568 1 65569 0
+0 0 5 0 0 109 2 110 0 65645 2 65646 0
+0 0 5 0 0 111 3 112 0 65647 3 65648 0
+0 0 5 0 0 114 4 115 0 65650 4 65651 0
+0 0 5 0 0 70 5 71 0 65606 5 65607 0
+# dreprog
+5 74 0 0 0 0
+0 0 20 0 2 33 1 34 2 39 1 40 2 48 4 58 2 65 1 123 2 161 1 65536 2 65569 1 65570 2 65575 1 65576 2 65584 4 65594 2 65601 1 65659 2 65697 1
+1 0 20 0 2 33 1 34 2 39 1 40 2 48 4 58 2 65 1 123 2 161 1 65536 2 65569 1 65570 2 65575 1 65576 2 65584 4 65594 2 65601 1 65659 2 65697 1
+0 1 1 0 2
+0 0 5 0 2 48 4 58 2 65584 4 65594 2
+1 0 28 0 2 33 1 34 2 39 1 40 2 44 3 45 2 46 3 47 2 48 4 58 2 65 1 123 2 161 1 65536 2 65569 1 65570 2 65575 1 65576 2 65580 3 65581 2 65582 3 65583 2 65584 4 65594 2 65601 1 65659 2 65697 1
+# dreprog
+385 9817 0 319 0 319
+0 0 41 0 1 60 320 61 1 66 321 67 1 69 322 70 323 71 1 78 324 79 1 83 325 84 1 98 321 99 1 101 322 102 323 103 1 110 324 111 1 115 325 116 1 65596 320 65597 1 65602 321 65603 1 65605 322 65606 323 65607 1 65614 324 65615 1 65619 325 65620 1 65634 321 65635 1 65637 322 65638 323 65639 1 65646 324 65647 1 65651 325 65652 1
+1 0 1 0 2
+0 1 1 0 2
+1 0 5 0 2 33 38 91 2 65569 3 65627 2
+1 0 25 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+1 0 21 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 79 48 80 39 91 40 111 54 112 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65615 15 65616 4 65627 5 65647 22 65648 5 65659 2
+1 0 25 0 344 9 87 10 32 11 344 13 87 14 344 32 87 33 349 45 45 46 349 62 38 63 349 91 344 65545 87 65546 32 65547 344 65549 87 65550 344 65568 87 65569 49 65581 51 65582 49 65598 3 65599 49 65627 344
+1 0 39 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 55 66 39 69 58 70 39 91 40 97 348 98 40 101 351 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 56 65602 4 65605 62 65606 4 65627 5 65633 343 65634 5 65637 64 65638 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 83 59 84 39 91 40 115 352 116 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65619 14 65620 4 65627 5 65651 342 65652 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 73 66 74 39 91 40 105 68 106 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65609 63 65610 4 65627 5 65641 24 65642 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 78 69 79 39 91 40 110 67 111 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65614 70 65615 4 65627 5 65646 65 65647 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 71 70 39 91 40 101 72 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 331 65606 4 65627 5 65637 74 65638 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 81 70 39 91 40 101 76 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 84 65606 4 65627 5 65637 86 65638 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 77 350 78 39 91 40 109 82 110 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65613 353 65614 4 65627 5 65645 354 65646 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 85 112 86 39 91 40 117 114 118 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65621 333 65622 4 65627 5 65653 21 65654 5 65659 2
+1 0 10 0 41 9 2 11 41 32 2 33 41 65536 16 65545 2 65547 16 65568 2 65569 16
+1 0 21 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 232 62 2 65 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 233 65598 2 65601 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 186 70 40 101 186 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 17 65606 5 65637 17 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 77 136 78 40 109 136 110 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65613 18 65614 5 65645 18 65646 5 65659 2
+1 0 35 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 80 66 40 69 61 70 40 97 80 98 40 101 61 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 19 65602 5 65605 78 65606 5 65633 19 65634 5 65637 78 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 78 164 79 40 110 164 111 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65614 23 65615 5 65646 23 65647 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 85 114 86 40 117 114 118 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65621 21 65622 5 65653 21 65654 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 68 215 69 40 100 215 101 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65604 85 65605 5 65636 85 65637 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 76 126 77 40 108 126 109 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65612 57 65613 5 65644 57 65645 5 65659 2
+0 0 27 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 87 62 327 63 87 79 93 80 87 111 93 112 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 87 65598 327 65599 87 65615 93 65616 87 65647 93 65648 87
+0 0 31 0 344 9 92 10 94 11 344 13 92 14 344 32 92 33 344 70 365 71 344 73 366 74 344 102 365 103 344 105 366 106 344 65545 92 65546 94 65547 344 65549 92 65550 344 65568 92 65569 344 65606 365 65607 344 65609 366 65610 344 65638 365 65639 344 65641 366 65642 344
+0 0 39 0 344 9 26 10 27 11 344 13 26 14 344 32 26 33 344 65 28 66 344 70 25 71 344 73 346 74 344 97 28 98 344 102 25 103 344 105 346 106 344 65545 26 65546 27 65547 344 65549 26 65550 344 65568 26 65569 344 65601 28 65602 344 65606 25 65607 344 65609 346 65610 344 65633 28 65634 344 65638 25 65639 344 65641 346 65642 344
+0 0 17 0 344 9 2 11 344 13 2 14 344 32 2 33 344 62 2 63 344 65545 2 65547 344 65549 2 65550 344 65568 2 65569 344 65598 2 65599 344
+0 0 23 0 29 9 199 10 202 11 29 13 199 14 29 32 199 33 29 45 157 46 29 62 204 63 29 65545 199 65546 202 65547 29 65549 199 65550 29 65568 199 65569 29 65581 157 65582 29 65598 204 65599 29
+0 0 9 0 2 85 37 86 2 117 37 118 2 65621 37 65622 2 65653 37 65654 2
+0 0 9 0 2 68 53 69 2 100 53 101 2 65604 53 65605 2 65636 53 65637 2
+0 0 9 0 32 10 2 11 32 62 1 63 32 65546 2 65547 32 65598 1 65599 32
+0 0 9 0 2 77 36 78 2 109 36 110 2 65613 36 65614 2 65645 36 65646 2
+0 0 9 0 2 76 101 77 2 108 101 109 2 65612 101 65613 2 65644 101 65645 2
+0 0 9 0 2 87 103 88 2 119 103 120 2 65623 103 65624 2 65655 103 65656 2
+0 0 9 0 2 84 104 85 2 116 104 117 2 65620 104 65621 2 65652 104 65653 2
+0 0 9 0 2 78 105 79 2 110 105 111 2 65614 105 65615 2 65646 105 65647 2
+0 0 5 0 2 33 38 91 2 65569 3 65627 2
+0 0 25 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+0 0 21 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65659 2
+0 0 10 0 41 9 2 11 41 32 2 33 41 65536 16 65545 2 65547 16 65568 2 65569 16
+0 0 25 0 344 9 87 10 32 11 344 13 87 14 344 32 87 33 349 45 45 46 349 62 38 63 349 91 344 65545 87 65546 32 65547 344 65549 87 65550 344 65568 87 65569 49 65581 51 65582 49 65598 3 65599 49 65627 344
+1 0 29 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 95 62 49 63 95 79 108 80 95 91 87 111 93 112 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 106 65598 49 65599 106 65615 110 65616 106 65627 87 65647 93 65648 87
+0 0 19 0 344 9 2 11 344 13 2 14 344 32 2 33 349 62 38 63 349 91 344 65545 2 65547 344 65549 2 65550 344 65568 2 65569 49 65598 3 65599 49 65627 344
+0 0 25 0 344 9 87 10 32 11 344 13 87 14 344 32 87 33 349 45 153 46 349 62 38 63 349 91 344 65545 87 65546 32 65547 344 65549 87 65550 344 65568 87 65569 49 65581 107 65582 49 65598 3 65599 49 65627 344
+0 0 29 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 95 62 49 63 95 79 108 80 95 91 87 111 93 112 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 106 65598 49 65599 106 65615 110 65616 106 65627 87 65647 93 65648 87
+0 0 29 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 95 62 49 63 95 77 109 78 95 91 87 109 99 110 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 106 65598 49 65599 106 65613 111 65614 106 65627 87 65645 99 65646 87
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 85 112 86 39 91 40 117 114 118 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65621 333 65622 4 65627 5 65653 21 65654 5 65659 2
+1 0 21 0 344 9 87 10 32 11 344 13 87 14 344 32 87 33 349 62 38 63 349 91 344 65545 87 65546 32 65547 344 65549 87 65550 344 65568 87 65569 49 65598 3 65599 49 65627 344
+1 0 19 0 344 9 2 11 344 13 2 14 344 32 2 33 349 62 38 63 349 91 344 65545 2 65547 344 65549 2 65550 344 65568 2 65569 49 65598 3 65599 49 65627 344
+1 0 25 0 344 9 87 10 32 11 344 13 87 14 344 32 87 33 349 45 153 46 349 62 38 63 349 91 344 65545 87 65546 32 65547 344 65549 87 65550 344 65568 87 65569 49 65581 107 65582 49 65598 3 65599 49 65627 344
+1 0 29 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 95 62 49 63 95 77 109 78 95 91 87 109 99 110 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 106 65598 49 65599 106 65613 111 65614 106 65627 87 65645 99 65646 87
+1 0 5 0 53 10 2 11 53 65546 2 65547 53
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 85 114 86 40 117 114 118 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65621 21 65622 5 65653 21 65654 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 84 115 85 39 91 40 116 60 117 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65620 89 65621 4 65627 5 65652 90 65653 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 84 115 85 39 91 40 116 60 117 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65620 89 65621 4 65627 5 65652 90 65653 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 175 70 40 101 175 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 117 65606 5 65637 117 65638 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 76 118 77 39 91 40 108 88 109 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65612 332 65613 4 65627 5 65644 121 65645 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 77 350 78 39 91 40 109 82 110 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65613 353 65614 4 65627 5 65645 354 65646 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 167 70 40 101 167 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 150 65606 5 65637 150 65638 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 87 119 88 40 119 119 120 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65623 135 65624 5 65655 135 65656 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 76 118 77 39 91 40 108 88 109 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65612 332 65613 4 65627 5 65644 121 65645 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 76 122 77 39 91 40 108 126 109 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65612 120 65613 4 65627 5 65644 57 65645 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 76 88 77 40 108 88 109 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65612 121 65613 5 65644 121 65645 5 65659 2
+1 0 21 0 2 43 40 44 2 45 123 46 2 47 40 58 2 61 40 62 2 65 40 123 2 65579 5 65580 2 65581 125 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 76 122 77 39 91 40 108 126 109 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65612 120 65613 4 65627 5 65644 57 65645 5 65659 2
+0 0 21 0 2 43 40 44 2 45 123 46 2 47 40 58 2 61 40 62 2 65 40 123 2 65579 5 65580 2 65581 125 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 76 126 77 40 108 126 109 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65612 57 65613 5 65644 57 65645 5 65659 2
+0 0 25 0 2 33 38 43 39 44 38 45 127 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 128 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+1 0 25 0 2 33 38 43 39 44 38 45 127 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 128 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 83 129 84 39 91 40 115 360 116 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65619 77 65620 4 65627 5 65651 132 65652 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 83 360 84 40 115 360 116 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65619 132 65620 5 65651 132 65652 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 77 133 78 39 91 40 109 136 110 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65613 334 65614 4 65627 5 65645 18 65646 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 83 360 84 40 115 360 116 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65619 132 65620 5 65651 132 65652 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 77 133 78 39 91 40 109 136 110 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65613 334 65614 4 65627 5 65645 18 65646 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 70 131 71 40 102 131 103 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65606 142 65607 5 65638 142 65639 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 83 178 84 39 91 40 115 179 116 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65619 173 65620 4 65627 5 65651 181 65652 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 87 119 88 40 119 119 120 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65623 135 65624 5 65655 135 65656 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 87 137 88 39 91 40 119 119 120 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65623 134 65624 4 65627 5 65655 135 65656 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 77 136 78 40 109 136 110 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65613 18 65614 5 65645 18 65646 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 70 140 71 39 91 40 102 131 103 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65606 138 65607 4 65627 5 65638 142 65639 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 84 141 85 40 116 141 117 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65620 146 65621 5 65652 146 65653 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 87 137 88 39 91 40 119 119 120 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65623 134 65624 4 65627 5 65655 135 65656 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 70 140 71 39 91 40 102 131 103 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65606 138 65607 4 65627 5 65638 142 65639 5 65659 2
+1 0 27 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 252 66 40 97 252 98 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 139 65602 5 65633 139 65634 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 70 131 71 40 102 131 103 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65606 142 65607 5 65638 142 65639 5 65659 2
+0 0 9 0 87 10 32 11 87 62 1 63 87 65546 32 65547 87 65598 1 65599 87
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 73 144 74 40 105 144 106 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65609 170 65610 5 65641 170 65642 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 165 70 39 91 40 101 167 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 163 65606 4 65627 5 65637 150 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 167 70 40 101 167 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 150 65606 5 65637 150 65638 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 73 148 74 40 105 148 106 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65609 305 65610 5 65641 305 65642 5 65659 2
+0 0 35 0 87 9 92 10 94 11 87 13 92 14 87 32 92 33 87 62 327 63 87 70 365 71 87 73 366 74 87 102 365 103 87 105 366 106 87 65545 92 65546 94 65547 87 65549 92 65550 87 65568 92 65569 87 65598 327 65599 87 65606 365 65607 87 65609 366 65610 87 65638 365 65639 87 65641 366 65642 87
+0 0 27 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 87 62 327 63 87 78 147 79 87 110 147 111 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 87 65598 327 65599 87 65614 147 65615 87 65646 147 65647 87
+0 0 43 0 87 9 92 10 27 11 87 13 92 14 87 32 92 33 87 62 327 63 87 65 100 66 87 70 151 71 87 73 346 74 87 97 100 98 87 102 151 103 87 105 346 106 87 65545 92 65546 27 65547 87 65549 92 65550 87 65568 92 65569 87 65598 327 65599 87 65601 100 65602 87 65606 151 65607 87 65609 346 65610 87 65633 100 65634 87 65638 151 65639 87 65641 346 65642 87
+0 0 13 0 87 10 32 11 87 33 95 62 3 63 95 91 87 65546 32 65547 87 65569 106 65598 3 65599 106 65627 87
+0 0 23 0 344 9 87 10 32 11 344 13 87 14 344 32 87 33 344 45 29 46 344 62 2 63 344 65545 87 65546 32 65547 344 65549 87 65550 344 65568 87 65569 344 65581 29 65582 344 65598 2 65599 344
+0 0 13 0 199 10 32 11 199 45 240 46 199 62 98 63 199 65546 32 65547 199 65581 240 65582 199 65598 98 65599 199
+1 0 5 0 204 45 210 46 204 65581 210 65582 204
+0 0 27 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 87 62 327 63 87 71 100 72 87 103 100 104 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 87 65598 327 65599 87 65607 100 65608 87 65639 100 65640 87
+0 0 19 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 87 62 1 63 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 87 65598 1 65599 87
+0 0 9 0 2 69 368 70 2 101 368 102 2 65605 368 65606 2 65637 368 65638 2
+0 0 9 0 2 69 154 70 2 101 154 102 2 65605 154 65606 2 65637 154 65638 2
+0 0 9 0 2 83 155 84 2 115 155 116 2 65619 155 65620 2 65651 155 65652 2
+0 0 9 0 2 80 156 81 2 112 156 113 2 65616 156 65617 2 65648 156 65649 2
+0 0 9 0 2 68 205 69 2 100 205 101 2 65604 205 65605 2 65636 205 65637 2
+1 0 13 0 87 10 32 11 87 33 95 62 3 63 95 91 87 65546 32 65547 87 65569 106 65598 3 65599 106 65627 87
+1 0 25 0 29 9 199 10 202 11 29 13 199 14 29 32 199 33 153 45 208 46 153 62 211 63 153 91 29 65545 199 65546 202 65547 29 65549 199 65550 29 65568 199 65569 107 65581 159 65582 107 65598 213 65599 107 65627 29
+0 0 29 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 95 62 49 63 95 78 158 79 95 91 87 110 147 111 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 106 65598 49 65599 106 65614 113 65615 106 65627 87 65646 147 65647 87
+0 0 29 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 95 62 49 63 95 71 160 72 95 91 87 103 100 104 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 106 65598 49 65599 106 65607 161 65608 106 65627 87 65639 100 65640 87
+1 0 29 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 95 62 49 63 95 78 158 79 95 91 87 110 147 111 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 106 65598 49 65599 106 65614 113 65615 106 65627 87 65646 147 65647 87
+1 0 29 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 95 62 49 63 95 71 160 72 95 91 87 103 100 104 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 106 65598 49 65599 106 65607 161 65608 106 65627 87 65639 100 65640 87
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 78 162 79 39 91 40 110 164 111 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65614 149 65615 4 65627 5 65646 23 65647 5 65659 2
+1 0 27 0 87 9 32 11 87 13 32 14 87 32 32 33 95 62 49 63 95 84 160 85 95 91 87 116 100 117 87 65545 32 65547 87 65549 32 65550 87 65568 32 65569 106 65598 49 65599 106 65620 161 65621 106 65627 87 65652 100 65653 87
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 78 164 79 40 110 164 111 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65614 23 65615 5 65646 23 65647 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 165 70 39 91 40 101 167 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 163 65606 4 65627 5 65637 150 65638 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 78 220 79 39 91 40 110 221 111 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65614 217 65615 4 65627 5 65646 341 65647 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 78 221 79 40 110 221 111 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65614 341 65615 5 65646 341 65647 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 73 168 74 39 91 40 105 144 106 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65609 166 65610 4 65627 5 65641 170 65642 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 83 190 84 40 115 190 116 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65619 185 65620 5 65651 185 65652 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 171 70 39 91 40 101 175 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 116 65606 4 65627 5 65637 117 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 73 144 74 40 105 144 106 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65609 170 65610 5 65641 170 65642 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 171 70 39 91 40 101 175 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 116 65606 4 65627 5 65637 117 65638 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 82 172 83 40 114 172 115 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65618 174 65619 5 65650 174 65651 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 73 302 74 39 91 40 105 148 106 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65609 303 65610 4 65627 5 65641 305 65642 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 82 172 83 40 114 172 115 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65618 174 65619 5 65650 174 65651 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 175 70 40 101 175 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 117 65606 5 65637 117 65638 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 82 176 83 39 91 40 114 172 115 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65618 145 65619 4 65627 5 65650 174 65651 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 82 176 83 39 91 40 114 172 115 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65618 145 65619 4 65627 5 65650 174 65651 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 83 178 84 39 91 40 115 179 116 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65619 173 65620 4 65627 5 65651 181 65652 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 80 194 81 39 91 40 112 198 113 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65616 196 65617 4 65627 5 65648 193 65649 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 383 70 40 101 383 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 384 65606 5 65637 384 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 83 179 84 40 115 179 116 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65619 181 65620 5 65651 181 65652 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 182 70 39 91 40 101 186 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 184 65606 4 65627 5 65637 17 65638 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 83 187 84 39 91 40 115 190 116 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65619 188 65620 4 65627 5 65651 185 65652 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 83 190 84 40 115 190 116 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65619 185 65620 5 65651 185 65652 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 186 70 40 101 186 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 17 65606 5 65637 17 65638 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 83 187 84 39 91 40 115 190 116 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65619 188 65620 4 65627 5 65651 185 65652 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 191 70 39 91 40 101 383 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 192 65606 4 65627 5 65637 384 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 82 268 83 40 114 268 115 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65618 189 65619 5 65650 189 65651 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 191 70 39 91 40 101 383 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 192 65606 4 65627 5 65637 384 65638 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 80 198 81 40 112 198 113 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65616 193 65617 5 65648 193 65649 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 383 70 40 101 383 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 384 65606 5 65637 384 65638 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 80 194 81 39 91 40 112 198 113 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65616 196 65617 4 65627 5 65648 193 65649 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 86 372 87 40 118 372 119 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65622 374 65623 5 65654 374 65655 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 222 70 39 91 40 101 183 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 223 65606 4 65627 5 65637 201 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 80 198 81 40 112 198 113 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65616 193 65617 5 65648 193 65649 5 65659 2
+0 0 25 0 87 9 32 11 87 13 32 14 87 32 32 33 87 62 327 63 87 84 100 85 87 116 100 117 87 65545 32 65547 87 65549 32 65550 87 65568 32 65569 87 65598 327 65599 87 65620 100 65621 87 65652 100 65653 87
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 68 167 69 40 100 167 101 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65604 150 65605 5 65636 150 65637 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 68 212 69 39 91 40 100 215 101 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65604 200 65605 4 65627 5 65636 85 65637 5 65659 2
+1 0 23 0 2 43 40 44 2 45 40 46 2 47 40 58 218 59 2 61 40 62 2 65 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 218 65595 2 65597 5 65598 2 65601 5 65659 2
+0 0 27 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 87 62 327 63 87 79 93 80 87 111 93 112 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 87 65598 327 65599 87 65615 93 65616 87 65647 93 65648 87
+0 0 13 0 202 10 2 11 202 45 242 46 202 62 98 63 202 65546 2 65547 202 65581 242 65582 202 65598 98 65599 202
+0 0 25 0 29 9 199 10 202 11 29 13 199 14 29 32 199 33 153 45 208 46 153 62 211 63 153 91 29 65545 199 65546 202 65547 29 65549 199 65550 29 65568 199 65569 107 65581 159 65582 107 65598 213 65599 107 65627 29
+0 0 5 0 2 61 203 62 2 65597 203 65598 2
+0 0 5 0 2 58 207 59 2 65594 207 65595 2
+0 0 5 0 2 32 209 33 2 65568 209 65569 2
+0 0 23 0 29 9 199 10 32 11 29 13 199 14 29 32 199 33 29 45 238 46 29 62 204 63 29 65545 199 65546 32 65547 29 65549 199 65550 29 65568 199 65569 29 65581 238 65582 29 65598 204 65599 29
+0 0 27 0 87 9 32 11 87 13 32 14 87 32 32 33 95 62 49 63 95 84 160 85 95 91 87 116 100 117 87 65545 32 65547 87 65549 32 65550 87 65568 32 65569 106 65598 49 65599 106 65620 161 65621 106 65627 87 65652 100 65653 87
+1 0 25 0 29 9 199 10 32 11 29 13 199 14 29 32 199 33 153 45 243 46 153 62 211 63 153 91 29 65545 199 65546 32 65547 29 65549 199 65550 29 65568 199 65569 107 65581 235 65582 107 65598 213 65599 107 65627 29
+0 0 21 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 95 62 3 63 95 91 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 106 65598 3 65599 106 65627 87
+1 0 21 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 95 62 3 63 95 91 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 106 65598 3 65599 106 65627 87
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 68 212 69 39 91 40 100 215 101 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65604 200 65605 4 65627 5 65636 85 65637 5 65659 2
+1 0 27 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 216 59 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 169 65595 3 65597 4 65598 3 65601 4 65627 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 68 215 69 40 100 215 101 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65604 85 65605 5 65636 85 65637 5 65659 2
+0 0 27 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 216 59 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 169 65595 3 65597 4 65598 3 65601 4 65627 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 86 371 87 39 91 40 118 372 119 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65622 373 65623 4 65627 5 65654 374 65655 5 65659 2
+0 0 23 0 2 43 40 44 2 45 40 46 2 47 40 58 218 59 2 61 40 62 2 65 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 218 65595 2 65597 5 65598 2 65601 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 86 371 87 39 91 40 118 372 119 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65622 373 65623 4 65627 5 65654 374 65655 5 65659 2
+1 0 9 0 218 10 241 11 218 33 216 91 218 65546 241 65547 218 65569 169 65627 218
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 86 372 87 40 118 372 119 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65622 374 65623 5 65654 374 65655 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 78 220 79 39 91 40 110 221 111 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65614 217 65615 4 65627 5 65646 341 65647 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 183 70 40 101 183 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 201 65606 5 65637 201 65638 5 65659 2
+1 0 31 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 224 66 39 91 40 97 225 98 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 226 65602 4 65627 5 65633 227 65634 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 183 70 40 101 183 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 201 65606 5 65637 201 65638 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 78 221 79 40 110 221 111 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65614 341 65615 5 65646 341 65647 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 222 70 39 91 40 101 183 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 223 65606 4 65627 5 65637 201 65638 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 78 283 79 39 91 40 110 280 111 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65614 281 65615 4 65627 5 65646 282 65647 5 65659 2
+0 0 31 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 224 66 39 91 40 97 225 98 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 226 65602 4 65627 5 65633 227 65634 5 65659 2
+0 0 27 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 225 66 40 97 225 98 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 227 65602 5 65633 227 65634 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 310 70 39 91 40 101 369 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 312 65606 4 65627 5 65637 370 65638 5 65659 2
+1 0 27 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 225 66 40 97 225 98 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 227 65602 5 65633 227 65634 5 65659 2
+0 0 25 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 228 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 219 65598 3 65601 4 65627 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 80 229 81 40 112 229 113 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65616 355 65617 5 65648 355 65649 5 65659 2
+1 0 25 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 228 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 219 65598 3 65601 4 65627 5 65659 2
+1 0 23 0 2 43 40 44 2 45 40 46 2 47 40 58 207 59 2 61 40 62 2 65 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 207 65595 2 65597 5 65598 2 65601 5 65659 2
+0 0 21 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 232 62 2 65 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 233 65598 2 65601 5 65659 2
+0 0 27 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 234 59 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 214 65595 3 65597 4 65598 3 65601 4 65627 5 65659 2
+1 0 27 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 234 59 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 214 65595 3 65597 4 65598 3 65601 4 65627 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 89 290 90 40 121 290 122 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65625 292 65626 5 65657 292 65658 5 65659 2
+0 0 23 0 2 43 40 44 2 45 40 46 2 47 40 58 207 59 2 61 40 62 2 65 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 207 65595 2 65597 5 65598 2 65601 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 82 236 83 39 91 40 114 377 115 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65618 230 65619 4 65627 5 65650 379 65651 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 82 236 83 39 91 40 114 377 115 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65618 230 65619 4 65627 5 65650 379 65651 5 65659 2
+1 0 25 0 2 32 209 33 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 123 2 65568 209 65569 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65659 2
+0 0 27 0 2 32 209 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65568 209 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 82 262 83 40 114 262 115 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65618 263 65619 5 65650 263 65651 5 65659 2
+1 0 27 0 2 32 209 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65568 209 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 82 262 83 40 114 262 115 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65618 263 65619 5 65650 263 65651 5 65659 2
+0 0 25 0 2 32 209 33 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 123 2 65568 209 65569 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65659 2
+0 0 13 0 199 10 202 11 199 45 97 46 199 62 98 63 199 65546 202 65547 199 65581 97 65582 199 65598 98 65599 199
+1 0 31 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 250 66 39 91 40 97 252 98 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 239 65602 4 65627 5 65633 139 65634 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 80 229 81 40 112 229 113 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65616 355 65617 5 65648 355 65649 5 65659 2
+0 0 13 0 202 10 204 11 202 45 152 46 202 62 98 63 202 65546 204 65547 202 65581 152 65582 202 65598 98 65599 202
+0 0 5 0 2 34 1 35 2 65570 1 65571 2
+0 0 5 0 204 45 210 46 204 65581 210 65582 204
+0 0 9 0 2 65 244 66 2 97 244 98 2 65601 244 65602 2 65633 244 65634 2
+0 0 9 0 2 65 347 66 2 97 347 98 2 65601 347 65602 2 65633 347 65634 2
+0 0 5 0 2 60 245 61 2 65596 245 65597 2
+0 0 25 0 29 9 199 10 32 11 29 13 199 14 29 32 199 33 153 45 243 46 153 62 211 63 153 91 29 65545 199 65546 32 65547 29 65549 199 65550 29 65568 199 65569 107 65581 235 65582 107 65598 213 65599 107 65627 29
+0 0 9 0 2 73 246 74 2 105 246 106 2 65609 246 65610 2 65641 246 65642 2
+0 0 9 0 204 10 2 11 204 45 261 46 204 65546 2 65547 204 65581 261 65582 204
+0 0 9 0 204 33 211 45 248 46 211 91 204 65569 213 65581 237 65582 213 65627 204
+0 0 31 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 250 66 39 91 40 97 252 98 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 239 65602 4 65627 5 65633 139 65634 5 65659 2
+1 0 9 0 204 33 211 45 248 46 211 91 204 65569 213 65581 237 65582 213 65627 204
+1 0 9 0 2 33 38 60 257 61 38 91 2 65569 3 65596 251 65597 3 65627 2
+0 0 27 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 252 66 40 97 252 98 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 139 65602 5 65633 139 65634 5 65659 2
+0 0 9 0 218 10 241 11 218 33 216 91 218 65546 241 65547 218 65569 169 65627 218
+1 0 31 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 75 66 39 91 40 97 80 98 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 73 65602 4 65627 5 65633 19 65634 5 65659 2
+0 0 5 0 218 10 241 11 218 65546 241 65547 218
+1 0 27 0 2 33 38 34 3 35 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+0 0 31 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 75 66 39 91 40 97 80 98 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 73 65602 4 65627 5 65633 19 65634 5 65659 2
+0 0 27 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 80 66 40 97 80 98 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 19 65602 5 65633 19 65634 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 80 255 81 39 91 40 112 229 113 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65616 256 65617 4 65627 5 65648 355 65649 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 80 255 81 39 91 40 112 229 113 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65616 256 65617 4 65627 5 65648 355 65649 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 71 376 72 39 91 40 103 380 104 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65607 378 65608 4 65627 5 65639 381 65640 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 71 380 72 40 103 380 104 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65607 381 65608 5 65639 381 65640 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 71 376 72 39 91 40 103 380 104 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65607 378 65608 4 65627 5 65639 381 65640 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 71 380 72 40 103 380 104 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65607 381 65608 5 65639 381 65640 5 65659 2
+0 0 27 0 2 33 38 34 3 35 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 76 272 77 40 108 272 109 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65612 274 65613 5 65644 274 65645 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 260 70 39 91 40 101 258 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 177 65606 4 65627 5 65637 231 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 78 280 79 40 110 280 111 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65614 282 65615 5 65646 282 65647 5 65659 2
+0 0 25 0 2 34 1 35 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 123 2 65570 1 65571 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65659 2
+1 0 25 0 2 34 1 35 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 123 2 65570 1 65571 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65659 2
+0 0 9 0 2 33 38 60 257 61 38 91 2 65569 3 65596 251 65597 3 65627 2
+1 0 21 0 29 9 199 10 32 11 29 13 199 14 29 32 199 33 153 62 3 63 153 91 29 65545 199 65546 32 65547 29 65549 199 65550 29 65568 199 65569 107 65598 3 65599 107 65627 29
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 260 70 39 91 40 101 258 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 177 65606 4 65627 5 65637 231 65638 5 65659 2
+1 0 13 0 204 10 2 11 204 33 211 45 265 46 211 91 204 65546 2 65547 204 65569 213 65581 249 65582 213 65627 204
+0 0 19 0 29 9 199 10 32 11 29 13 199 14 29 32 199 33 29 62 1 63 29 65545 199 65546 32 65547 29 65549 199 65550 29 65568 199 65569 29 65598 1 65599 29
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 82 266 83 39 91 40 114 268 115 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65618 259 65619 4 65627 5 65650 189 65651 5 65659 2
+0 0 9 0 199 10 32 11 199 62 1 63 199 65546 32 65547 199 65598 1 65599 199
+1 0 9 0 2 9 218 10 2 32 218 33 2 65545 218 65546 2 65568 218 65569 2
+0 0 9 0 202 10 2 11 202 62 1 63 202 65546 2 65547 202 65598 1 65599 202
+0 0 21 0 29 9 199 10 32 11 29 13 199 14 29 32 199 33 153 62 3 63 153 91 29 65545 199 65546 32 65547 29 65549 199 65550 29 65568 199 65569 107 65598 3 65599 107 65627 29
+0 0 9 0 2 82 247 83 2 114 247 115 2 65618 247 65619 2 65650 247 65651 2
+0 0 9 0 32 10 2 11 32 62 2 63 32 65546 2 65547 32 65598 2 65599 32
+0 0 9 0 2 68 264 69 2 100 264 101 2 65604 264 65605 2 65636 264 65637 2
+0 0 9 0 2 89 285 90 2 121 285 122 2 65625 285 65626 2 65657 285 65658 2
+0 0 13 0 204 10 2 11 204 33 211 45 265 46 211 91 204 65546 2 65547 204 65569 213 65581 249 65582 213 65627 204
+1 0 13 0 204 10 2 11 204 33 211 62 3 63 211 91 204 65546 2 65547 204 65569 213 65598 3 65599 213 65627 204
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 82 266 83 39 91 40 114 268 115 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65618 259 65619 4 65627 5 65650 189 65651 5 65659 2
+1 0 13 0 32 10 2 11 32 33 279 62 38 63 279 91 32 65546 2 65547 32 65569 267 65598 3 65599 267 65627 32
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 82 268 83 40 114 268 115 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65618 189 65619 5 65650 189 65651 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 82 269 83 39 91 40 114 262 115 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65618 270 65619 4 65627 5 65650 263 65651 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 82 269 83 39 91 40 114 262 115 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65618 270 65619 4 65627 5 65650 263 65651 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 76 271 77 39 91 40 108 272 109 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65612 273 65613 4 65627 5 65644 274 65645 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 76 271 77 39 91 40 108 272 109 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65612 273 65613 4 65627 5 65644 274 65645 5 65659 2
+0 0 13 0 32 10 2 11 32 33 279 62 38 63 279 91 32 65546 2 65547 32 65569 267 65598 3 65599 267 65627 32
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 78 280 79 40 110 280 111 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65614 282 65615 5 65646 282 65647 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 89 289 90 39 91 40 121 290 122 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65625 284 65626 4 65627 5 65657 292 65658 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 78 283 79 39 91 40 110 280 111 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65614 281 65615 4 65627 5 65646 282 65647 5 65659 2
+0 0 9 0 204 10 2 11 204 62 1 63 204 65546 2 65547 204 65598 1 65599 204
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 89 357 90 40 121 357 122 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65625 359 65626 5 65657 359 65658 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 89 357 90 40 121 357 122 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65625 359 65626 5 65657 359 65658 5 65659 2
+0 0 5 0 2 32 53 33 2 65568 53 65569 2
+0 0 13 0 204 10 2 11 204 33 211 62 3 63 211 91 204 65546 2 65547 204 65569 213 65598 3 65599 213 65627 204
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 89 289 90 39 91 40 121 290 122 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65625 284 65626 4 65627 5 65657 292 65658 5 65659 2
+1 0 13 0 32 10 2 11 32 33 279 62 3 63 279 91 32 65546 2 65547 32 65569 267 65598 3 65599 267 65627 32
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 89 290 90 40 121 290 122 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65625 292 65626 5 65657 292 65658 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 89 356 90 39 91 40 121 357 122 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65625 358 65626 4 65627 5 65657 359 65658 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 89 356 90 39 91 40 121 357 122 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65625 358 65626 4 65627 5 65657 359 65658 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 89 291 90 39 91 40 121 286 122 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65625 287 65626 4 65627 5 65657 288 65658 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 89 286 90 40 121 286 122 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65625 288 65626 5 65657 288 65658 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 89 291 90 39 91 40 121 286 122 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65625 287 65626 4 65627 5 65657 288 65658 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 89 286 90 40 121 286 122 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65625 288 65626 5 65657 288 65658 5 65659 2
+0 0 25 0 2 33 38 43 39 44 38 45 293 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 124 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+0 0 21 0 2 43 40 44 2 45 91 46 2 47 40 58 2 61 40 62 2 65 40 123 2 65579 5 65580 2 65581 296 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65659 2
+1 0 25 0 2 33 38 43 39 44 38 45 293 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 124 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+1 0 21 0 2 43 40 44 2 45 91 46 2 47 40 58 2 61 40 62 2 65 40 123 2 65579 5 65580 2 65581 296 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65659 2
+0 0 13 0 32 10 2 11 32 33 279 62 3 63 279 91 32 65546 2 65547 32 65569 267 65598 3 65599 267 65627 32
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 67 298 68 40 99 298 100 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65603 299 65604 5 65635 299 65636 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 67 297 68 39 91 40 99 298 100 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65603 180 65604 4 65627 5 65635 299 65636 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 67 298 68 40 99 298 100 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65603 299 65604 5 65635 299 65636 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 67 297 68 39 91 40 99 298 100 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65603 180 65604 4 65627 5 65635 299 65636 5 65659 2
+1 0 25 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 53 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 53 65598 3 65601 4 65627 5 65659 2
+0 0 5 0 2 61 53 62 2 65597 53 65598 2
+0 0 21 0 2 43 40 44 2 45 362 46 2 47 40 58 2 61 40 62 2 65 40 123 2 65579 5 65580 2 65581 364 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65659 2
+1 0 25 0 2 33 38 43 39 44 38 45 361 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 363 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+1 0 21 0 2 43 40 44 2 45 362 46 2 47 40 58 2 61 40 62 2 65 40 123 2 65579 5 65580 2 65581 364 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65659 2
+0 0 25 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 53 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 53 65598 3 65601 4 65627 5 65659 2
+0 0 21 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 53 62 2 65 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 53 65598 2 65601 5 65659 2
+0 0 25 0 2 33 38 43 39 44 38 45 361 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 363 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+1 0 21 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 53 62 2 65 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 53 65598 2 65601 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 73 302 74 39 91 40 105 148 106 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65609 303 65610 4 65627 5 65641 305 65642 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 68 304 69 40 100 304 101 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65604 313 65605 5 65636 313 65637 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 68 314 69 39 91 40 100 304 101 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65604 315 65605 4 65627 5 65636 313 65637 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 73 148 74 40 105 148 106 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65609 305 65610 5 65641 305 65642 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 310 70 39 91 40 101 369 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 312 65606 4 65627 5 65637 370 65638 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 369 70 40 101 369 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 370 65606 5 65637 370 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 369 70 40 101 369 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 370 65606 5 65637 370 65638 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 68 314 69 39 91 40 100 304 101 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65604 315 65605 4 65627 5 65636 313 65637 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 68 304 69 40 100 304 101 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65604 313 65605 5 65636 313 65637 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 68 165 69 39 91 40 100 167 101 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65604 163 65605 4 65627 5 65636 150 65637 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 68 165 69 39 91 40 100 167 101 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65604 163 65605 4 65627 5 65636 150 65637 5 65659 2
+0 0 27 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 308 66 40 97 308 98 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 309 65602 5 65633 309 65634 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 68 167 69 40 100 167 101 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65604 150 65605 5 65636 150 65637 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 84 115 85 39 91 40 116 60 117 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65620 89 65621 4 65627 5 65652 90 65653 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 84 115 85 39 91 40 116 60 117 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65620 89 65621 4 65627 5 65652 90 65653 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 84 60 85 40 116 60 117 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65620 90 65621 5 65652 90 65653 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 84 60 85 40 116 60 117 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65620 90 65621 5 65652 90 65653 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 83 165 84 39 91 40 115 167 116 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65619 163 65620 4 65627 5 65651 150 65652 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 79 167 80 40 111 167 112 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65615 150 65616 5 65647 150 65648 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 83 165 84 39 91 40 115 167 116 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65619 163 65620 4 65627 5 65651 150 65652 5 65659 2
+1 0 27 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 308 66 40 97 308 98 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 309 65602 5 65633 309 65634 5 65659 2
+0 0 31 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 306 66 39 91 40 97 308 98 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 307 65602 4 65627 5 65633 309 65634 5 65659 2
+1 0 31 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 306 66 39 91 40 97 308 98 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 307 65602 4 65627 5 65633 309 65634 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 79 165 80 39 91 40 111 167 112 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65615 163 65616 4 65627 5 65647 150 65648 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 79 165 80 39 91 40 111 167 112 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65615 163 65616 4 65627 5 65647 150 65648 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 79 167 80 40 111 167 112 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65615 150 65616 5 65647 150 65648 5 65659 2
+0 0 87 0 1 9 326 10 1 33 3 43 4 44 3 45 329 46 3 47 4 58 3 60 328 61 4 62 3 65 4 66 6 67 4 68 8 69 9 70 10 71 4 73 11 74 4 77 12 78 330 79 4 82 13 83 14 84 4 91 5 98 335 99 5 100 336 101 382 102 337 103 5 105 338 106 5 109 339 110 20 111 5 114 340 115 342 116 5 123 1 65545 326 65546 1 65569 3 65579 4 65580 3 65581 329 65582 3 65583 4 65594 3 65596 328 65597 4 65598 3 65601 4 65602 6 65603 4 65604 8 65605 9 65606 10 65607 4 65609 11 65610 4 65613 12 65614 330 65615 4 65618 13 65619 14 65620 4 65627 5 65634 335 65635 5 65636 336 65637 382 65638 337 65639 5 65641 338 65642 5 65645 339 65646 20 65647 5 65650 340 65651 342 65652 5 65659 1
+1 0 41 0 344 9 26 10 27 11 344 13 26 14 344 32 26 33 345 34 344 65 28 66 344 70 25 71 344 73 346 74 344 97 28 98 344 102 25 103 344 105 346 106 344 65545 26 65546 27 65547 344 65549 26 65550 344 65568 26 65569 345 65570 344 65601 28 65602 344 65606 25 65607 344 65609 346 65610 344 65633 28 65634 344 65638 25 65639 344 65641 346 65642 344
+1 0 9 0 2 79 30 80 2 111 30 112 2 65615 30 65616 2 65647 30 65648 2
+1 0 9 0 2 83 33 84 2 115 33 116 2 65619 33 65620 2 65651 33 65652 2
+1 0 9 0 2 73 34 74 2 105 34 106 2 65609 34 65610 2 65641 34 65642 2
+1 0 17 0 2 65 347 66 2 69 35 70 2 97 347 98 2 101 35 102 2 65601 347 65602 2 65605 35 65606 2 65633 347 65634 2 65637 35 65638 2
+1 0 9 0 2 77 36 78 2 109 36 110 2 65613 36 65614 2 65645 36 65646 2
+1 0 9 0 2 73 31 74 2 105 31 106 2 65609 31 65610 2 65641 31 65642 2
+1 0 19 0 344 9 87 10 32 11 344 13 87 14 344 32 87 33 344 62 2 63 344 65545 87 65546 32 65547 344 65549 87 65550 344 65568 87 65569 344 65598 2 65599 344
+1 0 43 0 344 9 26 10 27 11 344 13 26 14 344 32 26 33 42 34 349 65 44 66 349 70 46 71 349 73 47 74 349 91 344 97 28 98 344 102 25 103 344 105 346 106 344 65545 26 65546 27 65547 344 65549 26 65550 344 65568 26 65569 7 65570 49 65601 50 65602 49 65606 43 65607 49 65609 52 65610 49 65627 344 65633 28 65634 344 65638 25 65639 344 65641 346 65642 344
+1 0 25 0 2 33 38 43 39 44 38 45 41 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 16 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+1 0 39 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 75 66 39 69 79 70 39 91 40 97 80 98 40 101 61 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 73 65602 4 65605 83 65606 4 65627 5 65633 19 65634 5 65637 78 65638 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 83 129 84 39 91 40 115 360 116 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65619 77 65620 4 65627 5 65651 132 65652 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 73 168 74 39 91 40 105 144 106 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65609 166 65610 4 65627 5 65641 170 65642 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 78 162 79 39 91 40 110 164 111 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65614 149 65615 4 65627 5 65646 23 65647 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 182 70 39 91 40 101 186 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 184 65606 4 65627 5 65637 17 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 79 54 80 40 111 54 112 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65615 22 65616 5 65647 22 65648 5 65659 2
+1 0 35 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 348 66 40 69 351 70 40 97 348 98 40 101 351 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 343 65602 5 65605 64 65606 5 65633 343 65634 5 65637 64 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 73 68 74 40 105 68 106 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65609 24 65610 5 65641 24 65642 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 78 67 79 40 110 67 111 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65614 65 65615 5 65646 65 65647 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 72 70 40 101 72 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 74 65606 5 65637 74 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 76 70 40 101 76 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 86 65606 5 65637 86 65638 5 65659 2
+1 0 27 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 80 66 40 97 80 98 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 19 65602 5 65633 19 65634 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 77 82 78 40 109 82 110 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65613 354 65614 5 65645 354 65646 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 84 60 85 40 116 60 117 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65620 90 65621 5 65652 90 65653 5 65659 2
+0 0 19 0 344 9 87 10 32 11 344 13 87 14 344 32 87 33 344 62 2 63 344 65545 87 65546 32 65547 344 65549 87 65550 344 65568 87 65569 344 65598 2 65599 344
+0 0 23 0 344 9 87 10 32 11 344 13 87 14 344 32 87 33 344 45 96 46 344 62 2 63 344 65545 87 65546 32 65547 344 65549 87 65550 344 65568 87 65569 344 65581 96 65582 344 65598 2 65599 344
+0 0 27 0 87 9 32 10 2 11 87 13 32 14 87 32 32 33 87 62 327 63 87 77 99 78 87 109 99 110 87 65545 32 65546 2 65547 87 65549 32 65550 87 65568 32 65569 87 65598 327 65599 87 65613 99 65614 87 65645 99 65646 87
+0 0 9 0 2 77 102 78 2 109 102 110 2 65613 102 65614 2 65645 102 65646 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 84 60 85 40 116 60 117 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65620 90 65621 5 65652 90 65653 5 65659 2
+0 0 21 0 344 9 87 10 32 11 344 13 87 14 344 32 87 33 349 62 38 63 349 91 344 65545 87 65546 32 65547 344 65549 87 65550 344 65568 87 65569 49 65598 3 65599 49 65627 344
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 84 143 85 39 91 40 116 141 117 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65620 130 65621 4 65627 5 65652 146 65653 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 76 88 77 40 108 88 109 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65612 121 65613 5 65644 121 65645 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 77 82 78 40 109 82 110 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65613 354 65614 5 65645 354 65646 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 84 143 85 39 91 40 116 141 117 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65620 130 65621 4 65627 5 65652 146 65653 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 84 141 85 40 116 141 117 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65620 146 65621 5 65652 146 65653 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 76 272 77 40 108 272 109 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65612 274 65613 5 65644 274 65645 5 65659 2
+0 0 25 0 2 33 38 43 39 44 38 45 300 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 295 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+0 0 21 0 2 43 40 44 2 45 294 46 2 47 40 58 2 61 40 62 2 65 40 123 2 65579 5 65580 2 65581 301 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65659 2
+1 0 25 0 2 33 38 43 39 44 38 45 300 46 38 47 39 58 38 61 39 62 38 65 39 91 40 123 2 65569 3 65579 4 65580 3 65581 295 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65627 5 65659 2
+1 0 21 0 2 43 40 44 2 45 294 46 2 47 40 58 2 61 40 62 2 65 40 123 2 65579 5 65580 2 65581 301 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 83 179 84 40 115 179 116 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65619 181 65620 5 65651 181 65652 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 84 316 85 39 91 40 116 311 117 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65620 317 65621 4 65627 5 65652 318 65653 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 84 311 85 40 116 311 117 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65620 318 65621 5 65652 318 65653 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 84 316 85 39 91 40 116 311 117 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65620 317 65621 4 65627 5 65652 318 65653 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 84 311 85 40 116 311 117 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65620 318 65621 5 65652 318 65653 5 65659 2
+0 0 17 0 87 10 32 11 87 62 327 63 87 79 367 80 87 111 367 112 87 65546 32 65547 87 65598 327 65599 87 65615 367 65616 87 65647 367 65648 87
+0 0 17 0 87 10 32 11 87 62 327 63 87 77 375 78 87 109 375 110 87 65546 32 65547 87 65598 327 65599 87 65613 375 65614 87 65645 375 65646 87
+0 0 17 0 87 10 32 11 87 62 327 63 87 78 375 79 87 110 375 111 87 65546 32 65547 87 65598 327 65599 87 65614 375 65615 87 65646 375 65647 87
+0 0 9 0 2 78 206 79 2 110 206 111 2 65614 206 65615 2 65646 206 65647 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 83 167 84 40 115 167 116 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65619 150 65620 5 65651 150 65652 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 83 167 84 40 115 167 116 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65619 150 65620 5 65651 150 65652 5 65659 2
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 253 70 39 91 40 101 195 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 254 65606 4 65627 5 65637 197 65638 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 195 70 40 101 195 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 197 65606 5 65637 197 65638 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 253 70 39 91 40 101 195 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 254 65606 4 65627 5 65637 197 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 195 70 40 101 195 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 197 65606 5 65637 197 65638 5 65659 2
+0 0 9 0 87 10 32 11 87 62 327 63 87 65546 32 65547 87 65598 327 65599 87
+0 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 275 70 39 91 40 101 276 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 277 65606 4 65627 5 65637 278 65638 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 258 70 40 101 258 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 231 65606 5 65637 231 65638 5 65659 2
+1 0 33 0 2 33 38 43 39 44 38 45 39 46 38 47 39 58 38 61 39 62 38 65 39 69 275 70 39 91 40 101 276 102 40 123 2 65569 3 65579 4 65580 3 65581 4 65582 3 65583 4 65594 3 65597 4 65598 3 65601 4 65605 277 65606 4 65627 5 65637 278 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 258 70 40 101 258 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 231 65606 5 65637 231 65638 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 276 70 40 101 276 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 278 65606 5 65637 278 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 69 276 70 40 101 276 102 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65605 278 65606 5 65637 278 65638 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 83 352 84 40 115 352 116 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65619 342 65620 5 65651 342 65652 5 65659 2
+0 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 82 377 83 40 114 377 115 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65618 379 65619 5 65650 379 65651 5 65659 2
+1 0 29 0 2 43 40 44 2 45 40 46 2 47 40 58 2 61 40 62 2 65 40 82 377 83 40 114 377 115 40 123 2 65579 5 65580 2 65581 5 65582 2 65583 5 65594 2 65597 5 65598 2 65601 5 65618 379 65619 5 65650 379 65651 5 65659 2
blob - /dev/null
blob + 46695efd8e5193db3a23d16f4a5142e9a0aa5081 (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/dfa.c
@@ -0,0 +1,800 @@
+#include <u.h>
+#include <libc.h>
+#include <bin.h>
+#include <bio.h>
+#include <regexp.h>
+#include "/sys/src/libregexp/regcomp.h"
+#include "dfa.h"
+
+void rdump(Reprog*);
+void dump(Dreprog*);
+
+/*
+ * Standard NFA determinization and DFA minimization.
+ */
+typedef struct Deter Deter;
+typedef struct Reiset Reiset;
+
+void ddump(Deter*);
+
+/* state of determinization */
+struct Deter
+{
+	jmp_buf kaboom;	/* jmp on error */
+
+	Bin *bin;		/* bin for temporary allocations */
+
+	Reprog *p;	/* program being determinized */
+	uint ninst;		/* number of instructions in program */
+
+	Reiset *alloc;	/* chain of all Reisets */
+	Reiset **last;
+
+	Reiset **hash;	/* hash of all Reisets */
+	uint nhash;
+
+	Reiset *tmp;	/* temporaries for walk */
+	uchar *bits;
+
+	Rune *c;		/* ``interesting'' characters */
+	uint nc;
+};
+
+/* set of Reinsts: perhaps we should use a bit list instead of the indices? */
+struct Reiset
+{
+	uint *inst;		/* indices of instructions in set */
+	uint ninst;		/* size of set */
+
+	Reiset *next;	/* d.alloc chain */
+	Reiset *hash;	/* d.hash chain */
+	Reiset **delta;	/* where to go on each interesting char */
+	uint id;		/* assigned id during minimization */
+	uint isfinal;	/* is an accepting (final) state */
+};
+
+static Reiset*
+ralloc(Deter *d, int ninst)
+{
+	Reiset *t;
+
+	t = binalloc(&d->bin, sizeof(Reiset)+2*d->nc*sizeof(Reiset*)+sizeof(uint)*ninst, 0);
+	if(t == nil)
+		longjmp(d->kaboom, 1);
+	t->delta = (Reiset**)&t[1];
+	t->inst = (uint*)&t->delta[2*d->nc];
+	return t;
+}
+
+/* find the canonical form a given Reiset */
+static Reiset*
+findreiset(Deter *d, Reiset *s)
+{
+	int i, szinst;
+	uint h;
+	Reiset *t;
+
+	h = 0;
+	for(i=0; i<s->ninst; i++)
+		h = h*1000003 + s->inst[i];
+	h %= d->nhash;
+
+	szinst = s->ninst*sizeof(s->inst[0]);
+	for(t=d->hash[h]; t; t=t->hash)
+		if(t->ninst==s->ninst && memcmp(t->inst, s->inst, szinst)==0)
+			return t;
+
+	t = ralloc(d, s->ninst);
+	t->hash = d->hash[h];
+	d->hash[h] = t;
+
+	*d->last = t;
+	d->last = &t->next;
+	t->next = 0;
+
+	t->ninst = s->ninst;
+	memmove(t->inst, s->inst, szinst);
+
+	/* delta is filled in later */
+
+	return t;
+}
+
+/* convert bits to a real reiset */
+static Reiset*
+bits2reiset(Deter *d, uchar *bits)
+{
+	int k;
+	Reiset *s;
+
+	s = d->tmp;
+	s->ninst = 0;
+	for(k=0; k<d->ninst; k++)
+		if(bits[k])
+			s->inst[s->ninst++] = k;
+	return findreiset(d, s);
+}
+
+/* add n to state set; if n < k, need to go around again */
+static int
+add(int n, uchar *bits, int k)
+{
+	if(bits[n])
+		return 0;
+	bits[n] = 1;
+	return n < k;
+}
+
+/* update bits to follow all the empty (non-character-related) transitions possible */
+static void
+followempty(Deter *d, uchar *bits, int bol, int eol)
+{
+	int again, k;
+	Reinst *i;
+
+	do{
+		again = 0;
+		for(i=d->p->firstinst, k=0; k < d->ninst; i++, k++){
+			if(!bits[k])
+				continue;
+			switch(i->type){
+			case RBRA:
+			case LBRA:
+				again |= add(i->next - d->p->firstinst, bits, k);
+				break;
+			case OR:
+				again |= add(i->left - d->p->firstinst, bits, k);
+				again |= add(i->right - d->p->firstinst, bits, k);
+				break;
+			case BOL:
+				if(bol)
+					again |= add(i->next - d->p->firstinst, bits, k);
+				break;
+			case EOL:
+				if(eol)
+					again |= add(i->next - d->p->firstinst, bits, k);
+				break;
+			}
+		}
+	}while(again);
+
+	/*
+	 * Clear bits for useless transitions.  We could do this during
+	 * the switch above, but then we have no guarantee of termination
+	 * if we get a loop in the regexp.
+	 */
+	for(i=d->p->firstinst, k=0; k < d->ninst; i++, k++){
+		if(!bits[k])
+			continue;
+		switch(i->type){
+		case RBRA:
+		case LBRA:
+		case OR:
+		case BOL:
+		case EOL:
+			bits[k] = 0;
+			break;
+		}
+	}
+}
+
+/*
+ * Where does s go if it sees rune r?
+ * Eol is true if a $ matches the string at the position just after r.
+ */
+static Reiset*
+transition(Deter *d, Reiset *s, Rune r, uint eol)
+{
+	int k;
+	uchar *bits;
+	Reinst *i, *inst0;
+	Rune *rp, *ep;
+
+	bits = d->bits;
+	memset(bits, 0, d->ninst);
+
+	inst0 = d->p->firstinst;
+	for(k=0; k < s->ninst; k++){
+		i = inst0 + s->inst[k];
+		switch(i->type){
+		default:
+			werrstr("bad reprog: got type %d", i->type);
+			longjmp(d->kaboom, 1);
+		case RBRA:
+		case LBRA:
+		case OR:
+		case BOL:
+		case EOL:
+			werrstr("internal error: got type %d", i->type);
+			longjmp(d->kaboom, 1);
+
+		case RUNE:
+			if(r == i->r)
+				bits[i->next - inst0] = 1;
+			break;
+		case ANY:
+			if(r != L'\n')
+				bits[i->next - inst0] = 1;
+			break;
+		case ANYNL:
+			bits[i->next - inst0] = 1;
+			break;
+		case NCCLASS:
+			if(r == L'\n')
+				break;
+			/* fall through */
+		case CCLASS:
+			ep = i->cp->end;
+			for(rp = i->cp->spans; rp < ep; rp += 2)
+				if(rp[0] <= r && r <= rp[1])
+					break;
+			if((rp < ep) ^! (i->type == CCLASS))
+				bits[i->next - inst0] = 1;
+			break;
+		case END:
+			break;
+		}
+	}
+
+	followempty(d, bits, r=='\n', eol);
+	return bits2reiset(d, bits);
+}
+
+static int
+countinst(Reprog *pp)
+{
+	int n;
+	Reinst *l;
+
+	n = 0;
+	l = pp->firstinst;
+	while(l++->type)
+		n++;
+	return n;
+}
+
+static void
+set(Deter *d, u32int **tab, Rune r)
+{
+	u32int *u;
+
+	if((u = tab[r/4096]) == nil){
+		u = binalloc(&d->bin, 4096/8, 1);
+		if(u == nil)
+			longjmp(d->kaboom, 1);
+		tab[r/4096] = u;
+	}
+	u[(r%4096)/32] |= 1<<(r%32);
+}
+
+/*
+ * Compute the list of important characters. 
+ * Other characters behave like the ones that surround them.
+ */
+static void
+findchars(Deter *d, Reprog *p)
+{
+	u32int *tab[65536/4096], *u, x;
+	Reinst *i;
+	Rune *rp, *ep;
+	int k, m, n, a;
+
+	memset(tab, 0, sizeof tab);
+	set(d, tab, 0);
+	set(d, tab, 0xFFFF);
+	for(i=p->firstinst; i->type; i++){
+		switch(i->type){
+		case ANY:
+			set(d, tab, L'\n'-1);
+			set(d, tab, L'\n');
+			set(d, tab, L'\n'+1);
+			break;
+		case RUNE:
+			set(d, tab, i->r-1);
+			set(d, tab, i->r);
+			set(d, tab, i->r+1);
+			break;
+		case NCCLASS:
+			set(d, tab, L'\n'-1);
+			set(d, tab, L'\n');
+			set(d, tab, L'\n'+1);
+			/* fall through */
+		case CCLASS:
+			ep = i->cp->end;
+			for(rp = i->cp->spans; rp < ep; rp += 2){
+				set(d, tab, rp[0]-1);
+				set(d, tab, rp[0]);
+				set(d, tab, rp[1]);
+				set(d, tab, rp[1]+1);
+			}
+			break;
+		}
+	}
+
+	n = 0;
+	for(k=0; k<nelem(tab); k++){
+		if((u = tab[k]) == nil)
+			continue;
+		for(m=0; m<4096/32; m++){
+			if((x = u[m]) == 0)
+				continue;
+			for(a=0; a<32; a++)
+				if(x&(1<<a))
+					n++;
+		}
+	}
+
+	d->c = binalloc(&d->bin, (n+1)*sizeof(Rune), 0);
+	if(d->c == 0)
+		longjmp(d->kaboom, 1);
+	d->nc = n;
+
+	n = 0;
+	for(k=0; k<nelem(tab); k++){
+		if((u = tab[k]) == nil)
+			continue;
+		for(m=0; m<4096/32; m++){
+			if((x = u[m]) == 0)
+				continue;
+			for(a=0; a<32; a++)
+				if(x&(1<<a))
+					d->c[n++] = k*4096+m*32+a;
+		}
+	}
+
+	d->c[n] = 0;
+	if(n != d->nc)
+		abort();
+}
+
+/*
+ * convert the Deter and Reisets into a Dreprog.
+ * if dp and c are nil, just return the count of Drecases needed.
+ */
+static int
+buildprog(Deter *d, Reiset **id2set, int nid, Dreprog *dp, Drecase *c)
+{
+	int i, j, id, n, nn;
+	Dreinst *di;
+	Reiset *s;
+
+	nn = 0;
+	di = 0;
+	for(i=0; i<nid; i++){
+		s = id2set[i];
+		if(c){
+			di = &dp->inst[i];
+			di->isfinal = s->isfinal;
+		}
+		n = 0;
+		id = -1;
+		for(j=0; j<2*d->nc; j++){
+			if(s->delta[j]->id != id){
+				id = s->delta[j]->id;
+				if(c){
+					c[n].start = ((j/d->nc)<<16) | d->c[j%d->nc];
+					c[n].next = &dp->inst[id];
+				}
+				n++;
+			}
+		}
+		if(c){
+			if(n == 1 && c[0].next == di)
+				di->isloop = 1;
+			di->c = c;
+			di->nc = n;
+			c += n;
+		}
+		nn += n;
+	}
+	return nn;
+}
+
+Dreprog*
+dregcvt(Reprog *p)
+{
+	uchar *bits;
+	uint again, n, nid, id;
+	Deter d;
+	Reiset **id2set, *s, *t, *start[4];
+	Dreprog *dp;
+	Drecase *c;
+
+	memset(&d, 0, sizeof d);
+
+	if(setjmp(d.kaboom)){
+		binfree(&d.bin);
+		return nil;
+	}
+
+	d.p = p;
+	d.ninst = countinst(p);
+
+	d.last = &d.alloc;
+
+	n = d.ninst;
+	/* round up to power of two; this loop is the least of our efficiency problems */
+	while(n&(n-1))
+		n++;
+	d.nhash = n;
+	d.hash = binalloc(&d.bin, d.nhash*sizeof(Reinst*), 1);
+
+	/* get list of important runes */
+	findchars(&d, p);
+
+#ifdef DUMP
+	print("relevant chars are: «%S»\n", d.c+1);
+#endif
+
+	d.bits = bits = binalloc(&d.bin, d.ninst, 0);
+	d.tmp = ralloc(&d, d.ninst);
+
+	/*
+	 * Convert to DFA
+	 */
+
+	/* 4 start states, depending on initial bol, eol */
+	for(n=0; n<4; n++){
+		memset(bits, 0, d.ninst);
+		bits[p->startinst - p->firstinst] = 1;
+		followempty(&d, bits, n&1, n&2);
+		start[n] = bits2reiset(&d, bits);
+	}
+
+	/* explore the reiset space */
+	for(s=d.alloc; s; s=s->next)
+		for(n=0; n<2*d.nc; n++)
+			s->delta[n] = transition(&d, s, d.c[n%d.nc], n/d.nc);
+
+#ifdef DUMP
+	nid = 0;
+	for(s=d.alloc; s; s=s->next)
+		s->id = nid++;
+	ddump(&d);
+#endif
+
+	/*
+	 * Minimize.
+	 */
+
+	/* first class division is final or not */
+	for(s=d.alloc; s; s=s->next){
+		s->isfinal = 0;
+		for(n=0; n<s->ninst; n++)
+			if(p->firstinst[s->inst[n]].type == END)
+				s->isfinal = 1;
+		s->id = s->isfinal;
+	}
+
+	/* divide states with different transition tables in id space */
+	nid = 2;
+	do{
+		again = 0;
+		for(s=d.alloc; s; s=s->next){
+			id = -1;
+			for(t=s->next; t; t=t->next){
+				if(s->id != t->id)
+					continue;
+				for(n=0; n<2*d.nc; n++){
+					/* until we finish the for(t) loop, s->id and id are same */
+					if((s->delta[n]->id == t->delta[n]->id)
+					|| (s->delta[n]->id == s->id && t->delta[n]->id == id)
+					|| (s->delta[n]->id == id && t->delta[n]->id == s->id))
+						continue;
+					break;
+				}
+				if(n == 2*d.nc)
+					continue;
+				if(id == -1)
+					id = nid++;
+				t->id = id;
+				again = 1;
+			}
+		}
+	}while(again);
+
+#ifdef DUMP
+	ddump(&d);
+#endif
+
+	/* build dreprog */
+	id2set = binalloc(&d.bin, nid*sizeof(Reiset*), 1);
+	if(id2set == nil)
+		longjmp(d.kaboom, 1);
+	for(s=d.alloc; s; s=s->next)
+		id2set[s->id] = s;
+
+	n = buildprog(&d, id2set, nid, nil, nil);
+	dp = mallocz(sizeof(Dreprog)+nid*sizeof(Dreinst)+n*sizeof(Drecase), 1);
+	if(dp == nil)
+		longjmp(d.kaboom, 1);
+	c = (Drecase*)&dp->inst[nid];
+	buildprog(&d, id2set, nid, dp, c);
+
+	for(n=0; n<4; n++)
+		dp->start[n] = &dp->inst[start[n]->id];
+	dp->ninst = nid;
+
+	binfree(&d.bin);
+	return dp;
+}
+
+int
+dregexec(Dreprog *p, char *s, int bol)
+{
+	Rune r;
+	ulong rr;
+	Dreinst *i;
+	Drecase *c, *ec;
+	int best, n;
+	char *os;
+
+	i = p->start[(bol ? 1 : 0) | (s[1]=='\n' ? 2 : 0)];
+	best = -1;
+	os = s;
+	for(; *s; s+=n){
+		if(i->isfinal)
+			best = s - os;
+		if(i->isloop){
+			if(i->isfinal)
+				return strlen(os);
+			else
+				return best;
+		}
+		if((*s&0xFF) < Runeself){
+			r = *s;
+			n = 1;
+		}else
+			n = chartorune(&r, s);
+		c = i->c;
+		ec = c+i->nc;
+		rr = r;
+		if(s[n] == '\n' || s[n] == '\0')
+			rr |= 0x10000;
+		for(; c<ec; c++){
+			if(c->start > rr){
+				i = c[-1].next;
+				goto Out;
+			}
+		}
+		i = ec[-1].next;
+	Out:;
+	}
+	if(i->isfinal)
+		best = s - os;
+	return best;
+}
+
+
+#ifdef DUMP
+void
+ddump(Deter *d)
+{
+	int i, id;
+	Reiset *s;
+
+	for(s=d->alloc; s; s=s->next){
+		print("%d ", s->id);
+		id = -1;
+		for(i=0; i<2*d->nc; i++){
+			if(id != s->delta[i]->id){
+				if(i==0)
+					print(" [");
+				else if(i/d->nc)
+					print(" [%C$", d->c[i%d->nc]);
+				else
+					print(" [%C", d->c[i%d->nc]);
+				print(" %d]", s->delta[i]->id);
+				id = s->delta[i]->id;
+			}
+		}
+		print("\n");
+	}
+}
+
+void
+rdump(Reprog *pp)
+{
+	Reinst *l;
+	Rune *p;
+
+	l = pp->firstinst;
+	do{
+		print("%ld:\t0%o\t%ld\t%ld", l-pp->firstinst, l->type,
+			l->left-pp->firstinst, l->right-pp->firstinst);
+		if(l->type == RUNE)
+			print("\t%C\n", l->r);
+		else if(l->type == CCLASS || l->type == NCCLASS){
+			print("\t[");
+			if(l->type == NCCLASS)
+				print("^");
+			for(p = l->cp->spans; p < l->cp->end; p += 2)
+				if(p[0] == p[1])
+					print("%C", p[0]);
+				else
+					print("%C-%C", p[0], p[1]);
+			print("]\n");
+		} else
+			print("\n");
+	}while(l++->type);
+}
+
+void
+dump(Dreprog *pp)
+{
+	int i, j;
+	Dreinst *l;
+
+	print("start %ld %ld %ld %ld\n",
+		pp->start[0]-pp->inst,
+		pp->start[1]-pp->inst,
+		pp->start[2]-pp->inst,
+		pp->start[3]-pp->inst);
+
+	for(i=0; i<pp->ninst; i++){
+		l = &pp->inst[i];
+		print("%d:", i);
+		for(j=0; j<l->nc; j++){
+			print(" [");
+			if(j == 0)
+				if(l->c[j].start != 1)
+					abort();
+			if(j != 0)
+				print("%C%s", l->c[j].start&0xFFFF, (l->c[j].start&0x10000) ? "$" : "");
+			print("-");
+			if(j != l->nc-1)
+				print("%C%s", (l->c[j+1].start&0xFFFF)-1, (l->c[j+1].start&0x10000) ? "$" : "");
+			print("] %ld", l->c[j].next - pp->inst);
+		}
+		if(l->isfinal)
+			print(" final");
+		if(l->isloop)
+			print(" loop");
+		print("\n");
+	}
+}
+
+
+void
+main(int argc, char **argv)
+{
+	int i;
+	Reprog *p;
+	Dreprog *dp;
+
+	i = 1;
+		p = regcomp(argv[i]);
+		if(p == 0){
+			print("=== %s: bad regexp\n", argv[i]);
+		}
+	//	print("=== %s\n", argv[i]);
+	//	rdump(p);
+		dp = dregcvt(p);
+		print("=== dfa\n");
+		dump(dp);
+	
+	for(i=2; i<argc; i++)
+		print("match %d\n", dregexec(dp, argv[i], 0));
+	exits(0);
+}
+#endif
+
+void
+Bprintdfa(Biobuf *b, Dreprog *p)
+{
+	int i, j, nc;
+
+	Bprint(b, "# dreprog\n");
+	nc = 0;
+	for(i=0; i<p->ninst; i++)
+		nc += p->inst[i].nc;
+	Bprint(b, "%d %d %ld %ld %ld %ld\n", p->ninst, nc,
+		p->start[0]-p->inst, p->start[1]-p->inst,
+		p->start[2]-p->inst, p->start[3]-p->inst);
+	for(i=0; i<p->ninst; i++){
+		Bprint(b, "%d %d %d", p->inst[i].isfinal, p->inst[i].isloop, p->inst[i].nc);
+		for(j=0; j<p->inst[i].nc; j++)
+			Bprint(b, " %d %ld", p->inst[i].c[j].start, p->inst[i].c[j].next-p->inst);
+		Bprint(b, "\n");
+	}
+}
+
+static char*
+egetline(Biobuf *b, int c, jmp_buf jb)
+{
+	char *p;
+
+	p = Brdline(b, c);
+	if(p == nil)
+		longjmp(jb, 1);
+	p[Blinelen(b)-1] = '\0';
+	return p;
+}
+
+static void
+egetc(Biobuf *b, int c, jmp_buf jb)
+{
+	if(Bgetc(b) != c)
+		longjmp(jb, 1);
+}
+
+static int
+egetnum(Biobuf *b, int want, jmp_buf jb)
+{
+	int c;
+	int n, first;
+
+	n = 0;
+	first = 1;
+	while((c = Bgetc(b)) != Beof){
+		if(c < '0' || c > '9'){
+			if(want == 0){
+				Bungetc(b);
+				c = 0;
+			}
+			if(first || c != want){
+				werrstr("format error");
+				longjmp(jb, 1);
+			}
+			return n;
+		}
+		n = n*10 + c - '0';
+		first = 0;
+	}
+	werrstr("unexpected eof");
+	longjmp(jb, 1);
+	return -1;
+}
+
+Dreprog*
+Breaddfa(Biobuf *b)
+{
+	char *s;
+	int ninst, nc;
+	jmp_buf jb;
+	Dreprog *p;
+	Drecase *c;
+	Dreinst *l;
+	int j, k;
+
+	p = nil;
+	if(setjmp(jb)){
+		free(p);
+		return nil;
+	}
+
+	s = egetline(b, '\n', jb);
+	if(strcmp(s, "# dreprog") != 0){
+		werrstr("format error");
+		longjmp(jb, 1);
+	}
+
+	ninst = egetnum(b, ' ', jb);
+	nc = egetnum(b, ' ', jb);
+
+	p = mallocz(sizeof(Dreprog)+ninst*sizeof(Dreinst)+nc*sizeof(Drecase), 1);
+	if(p == nil)
+		longjmp(jb, 1);
+	c = (Drecase*)&p->inst[ninst];
+
+	p->start[0] = &p->inst[egetnum(b, ' ', jb)];
+	p->start[1] = &p->inst[egetnum(b, ' ', jb)];
+	p->start[2] = &p->inst[egetnum(b, ' ', jb)];
+	p->start[3] = &p->inst[egetnum(b, '\n', jb)];
+
+	for(j=0; j<ninst; j++){
+		l = &p->inst[j];
+		l->isfinal = egetnum(b, ' ', jb);
+		l->isloop = egetnum(b, ' ', jb);
+		l->nc = egetnum(b, 0, jb);
+		l->c = c;
+		for(k=0; k<l->nc; k++){
+			egetc(b, ' ', jb);
+			c->start = egetnum(b, ' ', jb);
+			c->next = &p->inst[egetnum(b, 0, jb)];
+			c++;
+		}
+		egetc(b, '\n', jb);
+	}
+	return p;
+}
blob - /dev/null
blob + 28c43dbc45aba64f0ec903cc4170e7e93d17c253 (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/dfa.h
@@ -0,0 +1,33 @@
+/*
+ * Deterministic regexp program.
+ */
+typedef struct Dreprog Dreprog;
+typedef struct Dreinst Dreinst;
+typedef struct Drecase Drecase;
+
+struct Dreinst
+{
+	int isfinal;
+	int isloop;
+	Drecase *c;
+	int nc;
+};
+
+struct Dreprog
+{
+	Dreinst *start[4];
+	int ninst;
+	Dreinst inst[1];
+};
+
+struct Drecase
+{
+	uint start;
+	Dreinst *next;
+};
+
+Dreprog* dregcvt(Reprog*);
+int dregexec(Dreprog*, char*, int);
+Dreprog* Breaddfa(Biobuf *b);
+void Bprintdfa(Biobuf*, Dreprog*);
+
blob - /dev/null
blob + 9c7babd35d71917ba6233ea06406a16248c2277f (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/dump.c
@@ -0,0 +1,67 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <regexp.h>
+#include "/sys/src/libregexp/regcomp.h"
+#include "dfa.h"
+
+#define DUMP
+
+void
+dump(Dreprog *pp)
+{
+	int i, j;
+	Dreinst *l;
+
+	print("start %ld %ld %ld %ld\n",
+		pp->start[0]-pp->inst,
+		pp->start[1]-pp->inst,
+		pp->start[2]-pp->inst,
+		pp->start[3]-pp->inst);
+
+	for(i=0; i<pp->ninst; i++){
+		l = &pp->inst[i];
+		print("%d:", i);
+		for(j=0; j<l->nc; j++){
+			print(" [");
+			if(j == 0)
+				if(l->c[j].start > 1)
+					print("<bad start %d>\n", l->c[j].start);
+			if(j != 0)
+				print("%C%s", l->c[j].start&0xFFFF, (l->c[j].start&0x10000) ? "$" : "");
+			print("-");
+			if(j != l->nc-1)
+				print("%C%s", (l->c[j+1].start&0xFFFF)-1, (l->c[j+1].start&0x10000) ? "$" : "");
+			print("] %ld", l->c[j].next - pp->inst);
+		}
+		if(l->isfinal)
+			print(" final");
+		if(l->isloop)
+			print(" loop");
+		print("\n");
+	}
+}
+
+
+void
+main(int argc, char **argv)
+{
+	int i;
+	Reprog *p;
+	Dreprog *dp;
+
+	i = 1;
+		p = regcomp(argv[i]);
+		if(p == 0){
+			print("=== %s: bad regexp\n", argv[i]);
+		}
+	//	print("=== %s\n", argv[i]);
+	//	rdump(p);
+		dp = dregcvt(p);
+		print("=== dfa\n");
+		dump(dp);
+	
+	for(i=2; i<argc; i++)
+		print("match %d\n", dregexec(dp, argv[i], 1));
+	exits(0);
+}
blob - /dev/null
blob + 1d0d0ac0c54ba10311247f23a9fc70d231ac4417 (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/hash.c
@@ -0,0 +1,312 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include "hash.h"
+
+/***
+ * String hash tables.
+ */
+
+Stringtab *tfree;
+
+Stringtab*
+taballoc(void)
+{
+	static Stringtab *t;
+	static uint nt;
+
+	if(tfree){
+		Stringtab *tt = tfree;
+		tfree = tt->link;
+		return tt;
+	}
+
+	if(nt == 0){
+		t = malloc(64000*sizeof(Stringtab));
+		if(t == 0)
+			sysfatal("out of memory");
+		nt = 64000;
+	}
+	nt--;
+	return t++;
+}
+
+void
+tabfree(Stringtab *tt)
+{
+	tt->link = tfree;
+	tfree = tt;
+}
+
+char*
+xstrdup(char *s, int len)
+{
+	char *r;
+	static char *t;
+	static int nt;
+
+	if(nt < len){
+		t = malloc(512*1024+len);
+		if(t == 0)
+			sysfatal("out of memory");
+		nt = 512*1024;
+	}
+	r = t;
+	t += len;
+	nt -= len;
+	memmove(r, s, len);
+	return r;
+}
+
+static uint
+hash(char *s, int n)
+{
+	uint h;
+	uchar *p, *ep;
+	h = 0;
+	for(p=(uchar*)s, ep=p+n; p<ep; p++)
+		h = h*37 + *p;
+	return h;
+}
+
+static void
+rehash(Hash *hh)
+{
+	int h;
+	Stringtab *s;
+
+	if(hh->nstab == 0)
+		hh->nstab = 1024;
+	else
+		hh->nstab = hh->ntab*2;
+
+	free(hh->stab);
+	hh->stab = mallocz(hh->nstab*sizeof(Stringtab*), 1);
+	if(hh->stab == nil)
+		sysfatal("out of memory");
+
+	for(s=hh->all; s; s=s->link){
+		h = hash(s->str, s->n) % hh->nstab;
+		s->hash = hh->stab[h];
+		hh->stab[h] = s;
+	}
+}
+
+Stringtab*
+findstab(Hash *hh, char *str, int n, int create)
+{
+	uint h;
+	Stringtab *tab, **l;
+
+	if(hh->nstab == 0)
+		rehash(hh);
+
+	h = hash(str, n) % hh->nstab;
+	for(tab=hh->stab[h], l=&hh->stab[h]; tab; l=&tab->hash, tab=tab->hash)
+		if(n==tab->n && memcmp(str, tab->str, n) == 0){
+			*l = tab->hash;
+			tab->hash = hh->stab[h];
+			hh->stab[h] = tab;
+			return tab;
+		}
+
+	if(!create)
+		return nil;
+
+	hh->sorted = 0;
+	tab = taballoc();
+	tab->str = xstrdup(str, n);
+	tab->hash = hh->stab[h];
+	tab->link = hh->all;
+	hh->all = tab;
+	tab->n = n;
+	tab->count = 0;
+	tab->date = 0;
+	hh->stab[h] = tab;
+
+	hh->ntab++;
+	if(hh->ntab > 2*hh->nstab && !(hh->ntab&(hh->ntab-1)))
+		rehash(hh);
+	return tab;
+}
+
+int
+scmp(Stringtab *a, Stringtab *b)
+{
+	int n, x;
+
+	if(a == 0)
+		return 1;
+	if(b == 0)
+		return -1;
+	n = a->n;
+	if(n > b->n)
+		n = b->n;
+	x = memcmp(a->str, b->str, n);
+	if(x != 0)
+		return x;
+	if(a->n < b->n)
+		return -1;
+	if(a->n > b->n)
+		return 1;
+	return 0;	/* shouldn't happen */
+}
+
+Stringtab*
+merge(Stringtab *a, Stringtab *b)
+{
+	Stringtab *s, **l;
+
+	l = &s;
+	while(a || b){
+		if(scmp(a, b) < 0){
+			*l = a;
+			l = &a->link;
+			a = a->link;
+		}else{
+			*l = b;
+			l = &b->link;
+			b = b->link;
+		}
+	}
+	*l = 0;
+	return s;
+}
+
+Stringtab*
+mergesort(Stringtab *s)
+{
+	Stringtab *a, *b;
+	int delay;
+
+	if(s == nil)
+		return nil;
+	if(s->link == nil)
+		return s;
+
+	a = b = s;
+	delay = 1;
+	while(a && b){
+		if(delay)	/* easy way to handle 2-element list */
+			delay = 0;
+		else
+			a = a->link;
+		if(b = b->link)
+			b = b->link;
+	}
+
+	b = a->link;
+	a->link = nil;
+
+	a = mergesort(s);
+	b = mergesort(b);
+
+	return merge(a, b);
+}
+
+Stringtab*
+sortstab(Hash *hh)
+{
+	if(!hh->sorted){
+		hh->all = mergesort(hh->all);
+		hh->sorted = 1;
+	}
+	return hh->all;
+}
+
+int
+Bwritehash(Biobuf *b, Hash *hh)
+{
+	Stringtab *s;
+	int now;
+
+	now = time(0);
+	s = sortstab(hh);
+	Bprint(b, "# hash table\n");
+	for(; s; s=s->link){
+		if(s->count <= 0)
+			continue;
+		/*
+		 * Entries that haven't been updated in thirty days get tossed.
+		 */
+		if(s->date+30*86400 < now)
+			continue;
+		Bwrite(b, s->str, s->n);
+		Bprint(b, "\t%d %d\n", s->count, s->date);
+	}
+	if(Bflush(b) == Beof)
+		return -1;
+	return 0;
+}
+
+void
+Breadhash(Biobuf *b, Hash *hh, int scale)
+{
+	char *s;
+	char *t;
+	int n;
+	int date;
+	Stringtab *st;
+
+	s = Brdstr(b, '\n', 1);
+	if(s == nil)
+		return;
+	if(strcmp(s, "# hash table") != 0)
+		sysfatal("bad hash table format");
+
+	while(s = Brdline(b, '\n')){
+		s[Blinelen(b)-1] = 0;
+		t = strrchr(s, '\t');
+		if(t == nil)
+			sysfatal("bad hash table format");
+		*t++ = '\0';
+		if(*t < '0' || *t > '9')
+			sysfatal("bad hash table format");
+		n = strtol(t, &t, 10);
+		date = time(0);
+		if(*t != 0){
+			if(*t == ' '){
+				t++;
+				date = strtol(t, &t, 10);
+			}
+			if(*t != 0)
+				sysfatal("bad hash table format");
+		}
+		st = findstab(hh, s, strlen(s), 1);
+		if(date > st->date)
+			st->date = date;
+		st->count += n*scale;
+	}
+}
+
+void
+freehash(Hash *h)
+{
+	Stringtab *s, *next;
+
+	for(s=h->all; s; s=next){
+		next = s->link;
+		tabfree(s);
+	}
+	free(h->stab);
+	free(h);
+}
+
+Biobuf*
+Bopenlock(char *file, int mode)
+{
+	int i;
+	Biobuf *b;
+	char err[ERRMAX];
+
+	b = nil;
+	for(i=0; i<120; i++){
+		if((b = Bopen(file, mode)) != nil)
+			break;
+		rerrstr(err, sizeof err);
+		if(strstr(err, "file is locked")==nil && strstr(err, "exclusive lock")==nil)
+			break;
+		sleep(1000);
+	}
+	return b;
+}
blob - /dev/null
blob + a1cff392f2f963ba0cd3243165f7cc4fe96b5f3e (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/hash.h
@@ -0,0 +1,27 @@
+typedef struct Stringtab	Stringtab;
+struct Stringtab {
+	Stringtab *link;
+	Stringtab *hash;
+	char *str;
+	int n;
+	int count;
+	int date;
+};
+
+typedef struct Hash Hash;
+struct Hash
+{
+	int sorted;
+	Stringtab **stab;
+	int nstab;
+	int ntab;
+	Stringtab *all;
+};
+
+Stringtab *findstab(Hash*, char*, int, int);
+Stringtab *sortstab(Hash*);
+
+int Bwritehash(Biobuf*, Hash*);	/* destroys hash */
+void Breadhash(Biobuf*, Hash*, int);
+void freehash(Hash*);
+Biobuf *Bopenlock(char*, int);
blob - /dev/null
blob + c0c546e73a8405ffe5fe595818764a55458e655c (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/mkfile
@@ -0,0 +1,33 @@
+</$objtype/mkfile
+
+TARG=addhash bayes msgtok
+HFILES=
+OFILES=
+LIB=
+
+BIN=/$objtype/bin/upas
+</sys/src/cmd/mkmany
+
+# msg tokenizer
+$O.regen: regcomp.$O dfa.$O
+dfa.$O regcomp.$O regen.$O: dfa.h
+
+/mail/lib/classify.re: $O.regen
+	if(~ $cputype $objtype)
+		$O.regen >x && cp x $target
+
+$O.msgtok: dfa.$O
+
+# msg database 
+msgdbx.$O msgdb.$O: msgdb.h
+
+# hash table creator/dumper
+$O.msgdb: msgdbx.$O
+
+$O.msgclass: hash.$O msgdbx.$O
+
+$O.addhash: hash.$O 
+
+$O.bayes: hash.$O
+
+
blob - /dev/null
blob + bd3c571ca06b302526aef8b198e09ce29954386f (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/msgclass.c
@@ -0,0 +1,296 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <ctype.h>
+#include "msgdb.h"
+
+void
+usage(void)
+{
+	fprint(2, "usage: upas/msgclass [-a] [-d name dbfile]... [-l lockfile] [-m mul] [-t thresh] [tokenfile ...]\n");
+	exits("usage");
+}
+
+enum
+{
+	MAXBEST = 32,
+	MAXLEN = 64,
+	MAXTAB = 256,
+};
+
+typedef struct Ndb Ndb;
+struct Ndb
+{
+	char *name;
+	char *file;
+	Msgdb *db;
+	double p;
+	long nmsg;
+};
+
+typedef struct Word Word;
+struct Word
+{
+	char s[MAXLEN];
+	int count[MAXTAB];
+	double p[MAXTAB];
+	double mp;
+	int mi; /* w.p[w.mi] = w.mp */
+	int nmsg;
+};
+
+Ndb db[MAXTAB];
+int ndb;
+
+int add;
+int mul;
+Msgdb *indb;
+
+Word best[MAXBEST];
+int mbest = 15;
+int nbest;
+
+void process(Biobuf*, char*);
+void lockfile(char*);
+
+void
+noteword(Word *w, char *s)
+{
+	int i;
+
+	for(i=nbest-1; i>=0; i--)
+		if(w->mp < best[i].mp)
+			break;
+	i++;
+
+	if(i >= mbest)
+		return;
+	if(nbest == mbest)
+		nbest--;
+	if(i < nbest)
+		memmove(&best[i+1], &best[i], (nbest-i)*sizeof(best[0]));
+	best[i] = *w;
+	strecpy(best[i].s, best[i].s+MAXLEN, s);
+	nbest++;
+}
+
+void
+main(int argc, char **argv)
+{
+	int i, bad, m, tot, nn, j;
+	Biobuf bin, *b, bout;
+	char *s, *lf;
+	double totp, p, thresh;
+	long n;
+	Word w;
+
+	lf = nil;
+	thresh = 0;
+	ARGBEGIN{
+	case 'a':
+		add = 1;
+		break;
+	case 'd':
+		if(ndb >= MAXTAB)
+			sysfatal("too many db classes");
+		db[ndb].name = EARGF(usage());
+		db[ndb].file = EARGF(usage());
+		ndb++;
+		break;
+	case 'l':
+		lf = EARGF(usage());
+		break;
+	case 'm':
+		mul = atoi(EARGF(usage()));
+		break;
+	case 't':
+		thresh = atof(EARGF(usage()));
+		break;
+	default:
+		usage();
+	}ARGEND
+
+	if(ndb == 0){
+		fprint(2, "must have at least one -d option\n");
+		usage();
+	}
+
+	indb = mdopen(nil, 1);
+	if(argc == 0){
+		Binit(&bin, 0, OREAD);
+		process(&bin, "<stdin>");
+		Bterm(&bin);
+	}else{
+		bad = 0;
+		for(i=0; i<argc; i++){
+			if((b = Bopen(argv[i], OREAD)) == nil){
+				fprint(2, "opening %s: %r\n", argv[i]);
+				bad = 1;
+				continue;
+			}
+			process(b, argv[i]);
+			Bterm(b);
+		}
+		if(bad)
+			exits("open inputs");
+	}
+
+	lockfile(lf);
+	bad = 0;
+	for(i=0; i<ndb; i++){
+		if((db[i].db = mdopen(db[i].file, 0)) == nil){
+			fprint(2, "opendb %s: %r\n", db[i].file);
+			bad = 1;
+		}
+		db[i].nmsg = mdget(db[i].db, "*From*");
+	}
+	if(bad)
+		exits("open databases");
+
+	/* run conditional probabilities of input words, getting 15 most specific */
+	mdenum(indb);
+	nbest = 0;
+	while(mdnext(indb, &s, &n) >= 0){
+		tot = 0;
+		totp = 0.0;
+		for(i=0; i<ndb; i++){
+			nn = mdget(db[i].db, s)*(i==0 ? 3 : 1);
+			tot += nn;
+			w.count[i] = nn;
+			p = w.count[i]/(double)db[i].nmsg;
+			if(p >= 1.0)
+				p = 1.0;
+			w.p[i] = p;
+			totp += p;
+		}
+//fprint(2, "%s tot %d totp %g\n", s, tot, totp);
+		if(tot < 2)
+			continue;
+		w.mp = 0.0;
+		for(i=0; i<ndb; i++){
+			p = w.p[i];
+			p /= totp;
+			if(p < 0.001)
+				p = 0.001;
+			else if(p > 0.999)
+				p = 0.999;
+			if(p > w.mp){
+				w.mp = p;
+				w.mi = i;
+			}
+			w.p[i] = p;
+		}
+		noteword(&w, s);
+	}
+
+	/* compute conditional probabilities of message classes using 15 most specific */
+	totp = 0.0;
+	for(i=0; i<ndb; i++){
+		p = 1.0;
+		for(j=0; j<nbest; j++)
+			p *= best[j].p[i];
+		db[i].p = p;
+		totp += p;
+	}
+	for(i=0; i<ndb; i++)
+		db[i].p /= totp;
+	m = 0;
+	for(i=1; i<ndb; i++)
+		if(db[i].p > db[m].p)
+			m = i;
+
+	Binit(&bout, 1, OWRITE);
+	if(db[m].p < thresh)
+		m = -1;
+	if(m >= 0)
+		Bprint(&bout, "%s", db[m].name);
+	else
+		Bprint(&bout, "inconclusive");
+	for(j=0; j<ndb; j++)
+		Bprint(&bout, " %s=%g", db[j].name, db[j].p);
+	Bprint(&bout, "\n");
+	for(i=0; i<nbest; i++){
+		Bprint(&bout, "%s", best[i].s);
+		for(j=0; j<ndb; j++)
+			Bprint(&bout, " %s=%g", db[j].name, best[i].p[j]);
+		Bprint(&bout, "\n");
+	}
+		Bprint(&bout, "%s %g\n", best[i].s, best[i].p[m]);
+	Bterm(&bout);
+
+	if(m >= 0 && add){
+		mdenum(indb);
+		while(mdnext(indb, &s, &n) >= 0)
+			mdput(db[m].db, s, mdget(db[m].db, s)+n*mul);
+		mdclose(db[m].db);
+	}
+	exits(nil);
+}
+
+void
+process(Biobuf *b, char*)
+{
+	char *s;
+	char *p;
+	long n;
+
+	while((s = Brdline(b, '\n')) != nil){
+		s[Blinelen(b)-1] = 0;
+		if((p = strrchr(s, ' ')) != nil){
+			*p++ = 0;
+			n = atoi(p);
+		}else
+			n = 1;
+		mdput(indb, s, mdget(indb, s)+n);
+	}
+}
+
+int tpid;
+void
+killtickle(void)
+{
+	postnote(PNPROC, tpid, "die");
+}
+
+void
+lockfile(char *s)
+{
+	int fd, t, w;
+	char err[ERRMAX];
+
+	if(s == nil)
+		return;
+	w = 50;
+	t = 0;
+	for(;;){
+		fd = open(s, OREAD);
+		if(fd >= 0)
+			break;
+		rerrstr(err, sizeof err);
+		if(strstr(err, "file is locked")==nil && strstr(err, "exclusive lock")==nil))
+			break;
+		sleep(w);
+		t += w;
+		if(w < 1000)
+			w = (w*3)/2;
+		if(t > 120*1000)
+			break;
+	}
+	if(fd < 0)
+		sysfatal("could not lock %s", s);
+	switch(tpid = fork()){
+	case -1:
+		sysfatal("fork: %r");
+	case 0:
+		for(;;){
+			sleep(30*1000);
+			free(dirfstat(fd));
+		}
+		_exits(nil);
+	default:
+		break;
+	}
+	close(fd);
+	atexit(killtickle);
+}
+
blob - /dev/null
blob + 3026a0cc46856dc8ae171851d265fed070542094 (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/msgdb.c
@@ -0,0 +1,63 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include "msgdb.h"
+
+void
+usage(void)
+{
+	fprint(2, "usage: msgdb [-c] file\n");
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	int create = 0;
+	Msgdb *db;
+	char *tok, *p;
+	long val;
+	int input;
+	Biobuf b;
+
+	input = 0;
+	ARGBEGIN{
+	case 'c':
+		create = 1;
+		break;
+	case 'i':
+		input = 1;
+		break;
+	default:
+		usage();
+	}ARGEND
+
+	if(argc != 1)
+		usage();
+
+	if((db = mdopen(argv[0], create)) == nil)
+		sysfatal("open db: %r");
+
+	if(input){
+		Binit(&b, 0, OREAD);
+		while((tok = Brdline(&b, '\n')) != nil){
+			tok[Blinelen(&b)-1] = '\0';
+			p = strrchr(tok, ' ');
+			if(p == nil)
+				val = mdget(db, tok)+1;
+			else{
+				*p++ = 0;
+				val = atoi(p);
+			}
+			mdput(db, tok, val);
+		}
+	}else{
+		mdenum(db);
+		Binit(&b, 1, OWRITE);
+		while(mdnext(db, &tok, &val) >= 0)
+			Bprint(&b, "%s %ld\n", tok, val);
+		Bterm(&b);
+	}
+	mdclose(db);
+	exits(nil);
+}
blob - /dev/null
blob + 54823d728e66a78405ad721f42eebc36a8c6dcc2 (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/msgdb.h
@@ -0,0 +1,10 @@
+typedef struct Msgdb Msgdb;
+
+Msgdb *mdopen(char*, int);
+long mdget(Msgdb*, char*);
+void mdput(Msgdb*, char*, long);
+
+void mdenum(Msgdb*);
+int mdnext(Msgdb*, char**, long*);
+
+void mdclose(Msgdb*);
blob - /dev/null
blob + 60ce70ae575dd0e14a9185fe70611f801b0b7b1c (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/msgdbx.c
@@ -0,0 +1,109 @@
+#include <u.h>
+#include <libc.h>
+#include <db.h>
+#include "msgdb.h"
+
+struct Msgdb
+{
+	DB *db;
+	int reset;
+};
+
+Msgdb*
+mdopen(char *file, int create)
+{
+	Msgdb *mdb;
+	DB *db;
+	HASHINFO h;
+
+	if((mdb = mallocz(sizeof(Msgdb), 1)) == nil)
+		return nil;
+	memset(&h, 0, sizeof h);
+	h.cachesize = 2*1024*1024;
+	if((db = dbopen(file, ORDWR|(create ? OCREATE:0), 0666, DB_HASH, &h)) == nil){
+		free(mdb);
+		return nil;
+	}
+	mdb->db = db;
+	mdb->reset = 1;
+	return mdb;
+}
+
+long
+mdget(Msgdb *mdb, char *tok)
+{
+	DB *db = mdb->db;
+	DBT key, val;
+	uchar *p;
+
+	key.data = tok;
+	key.size = strlen(tok)+1;
+	val.data = 0;
+	val.size = 0;
+
+	if(db->get(db, &key, &val, 0) < 0)
+		return 0;
+	if(val.data == 0)
+		return 0;
+	if(val.size != 4)
+		return 0;
+	p = val.data;
+	return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
+}
+
+void
+mdput(Msgdb *mdb, char *tok, long n)
+{
+	uchar p[4];
+	DB *db = mdb->db;
+	DBT key, val;
+
+	key.data = tok;
+	key.size = strlen(tok)+1;
+	if(n <= 0){
+		db->del(db, &key, 0);
+		return;
+	}
+
+	p[0] = n>>24;
+	p[1] = n>>16;
+	p[2] = n>>8;
+	p[3] = n;
+
+	val.data = p;
+	val.size = 4;
+	db->put(db, &key, &val, 0);
+}
+
+void
+mdenum(Msgdb *mdb)
+{
+	mdb->reset = 1;
+}
+
+int
+mdnext(Msgdb *mdb, char **sp, long *vp)
+{
+	DBT key, val;
+	uchar *p;
+	DB *db = mdb->db;
+	int i;
+
+	i = db->seq(db, &key, &val, mdb->reset ? R_FIRST : R_NEXT);
+	mdb->reset = 0;
+	if(i)
+		return -1;
+	*sp = key.data;
+	p = val.data;
+	*vp = (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
+	return 0;
+}
+
+void
+mdclose(Msgdb *mdb)
+{
+	DB *db = mdb->db;
+
+	db->close(db);
+	mdb->db = nil;
+}
blob - /dev/null
blob + 7c450546983f3c004c43edf9fd7eae6563fa2728 (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/msgtok.c
@@ -0,0 +1,245 @@
+/*
+ * RFC822 message tokenizer (really feature generator) for spam filter.
+ * 
+ * See Paul Graham's musings on spam filtering for theory.
+ */
+
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <regexp.h>
+#include <ctype.h>
+#include "dfa.h"
+
+void buildre(Dreprog*[3]);
+int debug;
+char *refile = "/mail/lib/classify.re";
+int maxtoklen = 20;
+int trim(char*);
+
+void
+usage(void)
+{
+	fprint(2, "usage: msgtok [-D] [-r /mail/lib/classify.re] [file]\n");
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	int i, hdr, n, eof, off;
+	Dreprog *re[3];
+	int m[3];
+	char *p, *ep, *tag;
+	Biobuf bout, bin;
+	char msg[1024+1];
+	char buf[1024];
+
+	buildre(re);
+	ARGBEGIN{
+	case 'D':
+		debug = 1;
+		break;
+	case 'n':
+		maxtoklen = atoi(EARGF(usage()));
+		break;
+	case 'r':
+		refile = EARGF(usage());
+		break;
+	default:
+		usage();
+	}ARGEND;
+
+	if(argc > 1)
+		usage();
+	if(argc == 1){
+		close(0);
+		if(open(argv[0], OREAD) < 0)
+			sysfatal("open %s: %r", argv[0]);
+	}
+
+	tag = nil;
+	Binit(&bin, 0, OREAD);
+	Binit(&bout, 1, OWRITE);
+	ep = msg;
+	p = msg;
+	eof = 0;
+	off = 0;
+	hdr = 1;
+	for(;;){
+		/* replenish buffer */
+		if(ep - p < 512 && !eof){
+			if(p > msg + 1){
+				n = ep - p;
+				memmove(msg, p-1, ep-(p-1));
+				off += (p-1) - msg;
+				p = msg+1;
+				ep = p + n;
+			}
+			n = Bread(&bin, ep, msg+(sizeof msg - 1)- ep);
+			if(n < 0)
+				sysfatal("read error: %r");
+			if(n == 0)
+				eof = 1;
+			ep += n;
+			*ep = 0;
+		}
+		if(p >= ep)
+			break;
+
+		if(*p == 0){
+			p++;
+			continue;
+		}
+
+		if(hdr && p[-1]=='\n'){
+			if(p[0]=='\n')
+				hdr = 0;
+			else if(cistrncmp(p-1, "\nfrom:", 6) == 0)
+				tag = "From*";
+			else if(cistrncmp(p-1, "\nto:", 4) == 0)
+				tag = "To*";
+			else if(cistrncmp(p-1, "\nsubject:", 9) == 0)
+				tag = "Subject*";
+			else if(cistrncmp(p-1, "\nreturn-path:", 13) == 0)
+				tag = "Return-Path*";
+			else
+				tag = nil;
+		}
+		m[0] = dregexec(re[0], p, p==msg || p[-1]=='\n');
+		m[1] = dregexec(re[1], p, p==msg || p[-1]=='\n');
+		m[2] = dregexec(re[2], p, p==msg || p[-1]=='\n');
+
+		n = m[0];
+		if(n < m[1])
+			n = m[1];
+		if(n < m[2])
+			n = m[2];
+		if(n <= 0){
+fprint(2, "«%s» %.2ux", p, p[0]);
+			sysfatal("no regexps matched at %ld", off + (p-msg));
+		}
+
+		if(m[0] >= m[1] && m[0] >= m[2]){
+			/* "From " marks start of new message */
+			Bprint(&bout, "*From*\n");
+			n = m[0];
+			hdr = 1;
+		}else if(m[2] > 1){
+			/* ignore */
+			n = m[2];
+		}else if(m[1] >= m[0] && m[1] >= m[2] && m[1] > 2 && m[1] <= maxtoklen){
+			/* keyword */
+			/* should do UTF-aware lowercasing, too much bother */
+/*
+			for(i=0; i<n; i++)
+				if('A' <= p[i] && p[i] <= 'Z')
+					p[i] += 'a' - 'A';
+*/
+			if(tag){
+				i = strlen(tag);	
+				memmove(buf, tag, i);
+				memmove(buf+i, p, m[1]);
+				buf[i+m[1]] = 0;
+			}else{
+				memmove(buf, p, m[1]);
+				buf[m[1]] = 0;
+			}
+			Bprint(&bout, "%s\n", buf);
+			while(trim(buf) >= 0)
+				Bprint(&bout, "stem*%s\n", buf);
+			n = m[1];
+		}else
+			n = m[2];
+		if(debug)
+			fprint(2, "%.*s¦", utfnlen(p, n), p);
+		p += n;
+	}
+	Bterm(&bout);
+	exits(0);
+}
+
+void
+buildre(Dreprog *re[3])
+{
+	Biobuf *b;
+
+	if((b = Bopen(refile, OREAD)) == nil)
+		sysfatal("open %s: %r", refile);
+
+	re[0] = Breaddfa(b);
+	re[1] = Breaddfa(b);
+	re[2] = Breaddfa(b);
+
+	if(re[0]==nil || re[1]==nil || re[2]==nil)
+		sysfatal("Breaddfa: %r");
+	Bterm(b);
+}
+
+/* perhaps this belongs in the tokenizer */
+int
+trim(char *s)
+{
+	char *p, *op;
+	int mix, mix1;
+
+	if(*s == '*')
+		return -1;
+
+	/* strip leading punctuation */
+	p = strchr(s, '*');
+	if(p == nil)
+		p = s;
+	while(*p && !isalpha(*p))
+		p++;
+	if(strlen(p) < 2)
+{
+		return -1;
+}
+	memmove(s, p, strlen(p)+1);
+
+	/* strip suffix of punctuation */
+	p = s+strlen(s);
+	op = p;
+	while(p > s && (uchar)p[-1]<0x80 && !isalpha(p[-1]))
+		p--;
+
+	/* chop punctuation */
+	if(p > s){
+		/* free!!! -> free! */
+		if(p+1 < op){
+			p[1] = 0;
+			return 0;
+		}
+		/* free! -> free */
+		if(p < op){
+			p[0] = 0;
+			return 0;
+		}
+	}
+
+	mix = mix1 = 0;
+	if(isupper(s[0]))
+		mix = 1;
+	for(p=s+1; *p; p++)
+		if(isupper(*p)){
+			mix1 = 1;
+			break;
+		}
+
+	/* turn FREE into Free */
+	if(mix1){
+		for(p=s+1; *p; p++)
+			if(isupper(*p))
+				*p += 'a'-'A';
+		return 0;
+	}
+
+	/* turn Free into free */
+	if(mix){
+		*s += 'a'-'A';
+		return 0;
+	}
+	return -1;
+}		
+
blob - /dev/null
blob + 8afaf2157fe1ece7320b323f44d100f994879910 (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/regcomp.c
@@ -0,0 +1,563 @@
+/* From libregexp but leaks extra classes when it runs out */
+
+
+#include <u.h>
+#include <libc.h>
+#include "regexp.h"
+#include "/sys/src/libregexp/regcomp.h"
+
+#define	TRUE	1
+#define	FALSE	0
+
+/*
+ * Parser Information
+ */
+typedef
+struct Node
+{
+	Reinst*	first;
+	Reinst*	last;
+}Node;
+
+#define	NSTACK	20
+static	Node	andstack[NSTACK];
+static	Node	*andp;
+static	int	atorstack[NSTACK];
+static	int*	atorp;
+static	int	cursubid;		/* id of current subexpression */
+static	int	subidstack[NSTACK];	/* parallel to atorstack */
+static	int*	subidp;
+static	int	lastwasand;	/* Last token was operand */
+static	int	nbra;
+static	char*	exprp;		/* pointer to next character in source expression */
+static	int	lexdone;
+static	int	nclass;
+static	Reclass*classp;
+static	Reinst*	freep;
+static	int	errors;
+static	Rune	yyrune;		/* last lex'd rune */
+static	Reclass*yyclassp;	/* last lex'd class */
+
+/* predeclared crap */
+static	void	operator(int);
+static	void	pushand(Reinst*, Reinst*);
+static	void	pushator(int);
+static	void	evaluntil(int);
+static	int	bldcclass(void);
+
+static jmp_buf regkaboom;
+
+static	void
+rcerror(char *s)
+{
+	errors++;
+	regerror(s);
+	longjmp(regkaboom, 1);
+}
+
+static	Reinst*
+newinst(int t)
+{
+	freep->type = t;
+	freep->left = 0;
+	freep->right = 0;
+	return freep++;
+}
+
+static	void
+operand(int t)
+{
+	Reinst *i;
+
+	if(lastwasand)
+		operator(CAT);	/* catenate is implicit */
+	i = newinst(t);
+
+	if(t == CCLASS || t == NCCLASS)
+		i->cp = yyclassp;
+	if(t == RUNE)
+		i->r = yyrune;
+
+	pushand(i, i);
+	lastwasand = TRUE;
+}
+
+static	void
+operator(int t)
+{
+	if(t==RBRA && --nbra<0)
+		rcerror("unmatched right paren");
+	if(t==LBRA){
+		if(++cursubid >= NSUBEXP)
+			rcerror ("too many subexpressions");
+		nbra++;
+		if(lastwasand)
+			operator(CAT);
+	} else
+		evaluntil(t);
+	if(t != RBRA)
+		pushator(t);
+	lastwasand = FALSE;
+	if(t==STAR || t==QUEST || t==PLUS || t==RBRA)
+		lastwasand = TRUE;	/* these look like operands */
+}
+
+static	void
+regerr2(char *s, int c)
+{
+	char buf[100];
+	char *cp = buf;
+	while(*s)
+		*cp++ = *s++;
+	*cp++ = c;
+	*cp = '\0'; 
+	rcerror(buf);
+}
+
+static	void
+cant(char *s)
+{
+	char buf[100];
+	strcpy(buf, "can't happen: ");
+	strcat(buf, s);
+	rcerror(buf);
+}
+
+static	void
+pushand(Reinst *f, Reinst *l)
+{
+	if(andp >= &andstack[NSTACK])
+		cant("operand stack overflow");
+	andp->first = f;
+	andp->last = l;
+	andp++;
+}
+
+static	void
+pushator(int t)
+{
+	if(atorp >= &atorstack[NSTACK])
+		cant("operator stack overflow");
+	*atorp++ = t;
+	*subidp++ = cursubid;
+}
+
+static	Node*
+popand(int op)
+{
+	Reinst *inst;
+
+	if(andp <= &andstack[0]){
+		regerr2("missing operand for ", op);
+		inst = newinst(NOP);
+		pushand(inst,inst);
+	}
+	return --andp;
+}
+
+static	int
+popator(void)
+{
+	if(atorp <= &atorstack[0])
+		cant("operator stack underflow");
+	--subidp;
+	return *--atorp;
+}
+
+static	void
+evaluntil(int pri)
+{
+	Node *op1, *op2;
+	Reinst *inst1, *inst2;
+
+	while(pri==RBRA || atorp[-1]>=pri){
+		switch(popator()){
+		default:
+			rcerror("unknown operator in evaluntil");
+			break;
+		case LBRA:		/* must have been RBRA */
+			op1 = popand('(');
+			inst2 = newinst(RBRA);
+			inst2->subid = *subidp;
+			op1->last->next = inst2;
+			inst1 = newinst(LBRA);
+			inst1->subid = *subidp;
+			inst1->next = op1->first;
+			pushand(inst1, inst2);
+			return;
+		case OR:
+			op2 = popand('|');
+			op1 = popand('|');
+			inst2 = newinst(NOP);
+			op2->last->next = inst2;
+			op1->last->next = inst2;
+			inst1 = newinst(OR);
+			inst1->right = op1->first;
+			inst1->left = op2->first;
+			pushand(inst1, inst2);
+			break;
+		case CAT:
+			op2 = popand(0);
+			op1 = popand(0);
+			op1->last->next = op2->first;
+			pushand(op1->first, op2->last);
+			break;
+		case STAR:
+			op2 = popand('*');
+			inst1 = newinst(OR);
+			op2->last->next = inst1;
+			inst1->right = op2->first;
+			pushand(inst1, inst1);
+			break;
+		case PLUS:
+			op2 = popand('+');
+			inst1 = newinst(OR);
+			op2->last->next = inst1;
+			inst1->right = op2->first;
+			pushand(op2->first, inst1);
+			break;
+		case QUEST:
+			op2 = popand('?');
+			inst1 = newinst(OR);
+			inst2 = newinst(NOP);
+			inst1->left = inst2;
+			inst1->right = op2->first;
+			op2->last->next = inst2;
+			pushand(inst1, inst2);
+			break;
+		}
+	}
+}
+
+static	Reprog*
+optimize(Reprog *pp)
+{
+	Reinst *inst, *target;
+	int size;
+	Reprog *npp;
+	Reclass *cl;
+	int diff;
+
+	/*
+	 *  get rid of NOOP chains
+	 */
+	for(inst=pp->firstinst; inst->type!=END; inst++){
+		target = inst->next;
+		while(target->type == NOP)
+			target = target->next;
+		inst->next = target;
+	}
+
+	/*
+	 *  The original allocation is for an area larger than
+	 *  necessary.  Reallocate to the actual space used
+	 *  and then relocate the code.
+	 */
+	size = sizeof(Reprog) + (freep - pp->firstinst)*sizeof(Reinst);
+	npp = realloc(pp, size);
+	if(npp==0 || npp==pp)
+		return pp;
+	diff = (char *)npp - (char *)pp;
+	freep = (Reinst *)((char *)freep + diff);
+	for(inst=npp->firstinst; inst<freep; inst++){
+		switch(inst->type){
+		case OR:
+		case STAR:
+		case PLUS:
+		case QUEST:
+			*(char **)&inst->right += diff;
+			break;
+		case CCLASS:
+		case NCCLASS:
+			*(char **)&inst->right += diff;
+			cl = inst->cp;
+			*(char **)&cl->end += diff;
+			break;
+		}
+		*(char **)&inst->left += diff;
+	}
+	*(char **)&npp->startinst += diff;
+	return npp;
+}
+
+#ifdef	DEBUG
+static	void
+dumpstack(void){
+	Node *stk;
+	int *ip;
+
+	print("operators\n");
+	for(ip=atorstack; ip<atorp; ip++)
+		print("0%o\n", *ip);
+	print("operands\n");
+	for(stk=andstack; stk<andp; stk++)
+		print("0%o\t0%o\n", stk->first->type, stk->last->type);
+}
+
+static	void
+dump(Reprog *pp)
+{
+	Reinst *l;
+	Rune *p;
+
+	l = pp->firstinst;
+	do{
+		print("%d:\t0%o\t%d\t%d", l-pp->firstinst, l->type,
+			l->left-pp->firstinst, l->right-pp->firstinst);
+		if(l->type == RUNE)
+			print("\t%C\n", l->r);
+		else if(l->type == CCLASS || l->type == NCCLASS){
+			print("\t[");
+			if(l->type == NCCLASS)
+				print("^");
+			for(p = l->cp->spans; p < l->cp->end; p += 2)
+				if(p[0] == p[1])
+					print("%C", p[0]);
+				else
+					print("%C-%C", p[0], p[1]);
+			print("]\n");
+		} else
+			print("\n");
+	}while(l++->type);
+}
+#endif
+
+static	Reclass*
+newclass(void)
+{
+	if(nclass <= 0){
+		classp = mallocz(128*sizeof(Reclass), 1);
+		if(classp == nil)
+			regerror("out of memory");
+		nclass = 128;
+	}
+	return &classp[--nclass];
+}
+
+static	int
+nextc(Rune *rp)
+{
+	if(lexdone){
+		*rp = 0;
+		return 1;
+	}
+	exprp += chartorune(rp, exprp);
+	if(*rp == L'\\'){
+		exprp += chartorune(rp, exprp);
+		return 1;
+	}
+	if(*rp == 0)
+		lexdone = 1;
+	return 0;
+}
+
+static	int
+lex(int literal, int dot_type)
+{
+	int quoted;
+
+	quoted = nextc(&yyrune);
+	if(literal || quoted){
+		if(yyrune == 0)
+			return END;
+		return RUNE;
+	}
+
+	switch(yyrune){
+	case 0:
+		return END;
+	case L'*':
+		return STAR;
+	case L'?':
+		return QUEST;
+	case L'+':
+		return PLUS;
+	case L'|':
+		return OR;
+	case L'.':
+		return dot_type;
+	case L'(':
+		return LBRA;
+	case L')':
+		return RBRA;
+	case L'^':
+		return BOL;
+	case L'$':
+		return EOL;
+	case L'[':
+		return bldcclass();
+	}
+	return RUNE;
+}
+
+static int
+bldcclass(void)
+{
+	int type;
+	Rune r[NCCRUNE];
+	Rune *p, *ep, *np;
+	Rune rune;
+	int quoted;
+
+	/* we have already seen the '[' */
+	type = CCLASS;
+	yyclassp = newclass();
+
+	/* look ahead for negation */
+	/* SPECIAL CASE!!! negated classes don't match \n */
+	ep = r;
+	quoted = nextc(&rune);
+	if(!quoted && rune == L'^'){
+		type = NCCLASS;
+		quoted = nextc(&rune);
+		*ep++ = L'\n';
+		*ep++ = L'\n';
+	}
+
+	/* parse class into a set of spans */
+	for(; ep<&r[NCCRUNE];){
+		if(rune == 0){
+			rcerror("malformed '[]'");
+			return 0;
+		}
+		if(!quoted && rune == L']')
+			break;
+		if(!quoted && rune == L'-'){
+			if(ep == r){
+				rcerror("malformed '[]'");
+				return 0;
+			}
+			quoted = nextc(&rune);
+			if((!quoted && rune == L']') || rune == 0){
+				rcerror("malformed '[]'");
+				return 0;
+			}
+			*(ep-1) = rune;
+		} else {
+			*ep++ = rune;
+			*ep++ = rune;
+		}
+		quoted = nextc(&rune);
+	}
+
+	/* sort on span start */
+	for(p = r; p < ep; p += 2){
+		for(np = p; np < ep; np += 2)
+			if(*np < *p){
+				rune = np[0];
+				np[0] = p[0];
+				p[0] = rune;
+				rune = np[1];
+				np[1] = p[1];
+				p[1] = rune;
+			}
+	}
+
+	/* merge spans */
+	np = yyclassp->spans;
+	p = r;
+	if(r == ep)
+		yyclassp->end = np;
+	else {
+		np[0] = *p++;
+		np[1] = *p++;
+		for(; p < ep; p += 2)
+			if(p[0] <= np[1]){
+				if(p[1] > np[1])
+					np[1] = p[1];
+			} else {
+				np += 2;
+				np[0] = p[0];
+				np[1] = p[1];
+			}
+		yyclassp->end = np+2;
+	}
+
+	return type;
+}
+
+static	Reprog*
+regcomp1(char *s, int literal, int dot_type)
+{
+	int token;
+	Reprog *pp;
+
+	/* get memory for the program */
+	pp = malloc(sizeof(Reprog) + 6*sizeof(Reinst)*strlen(s));
+	if(pp == 0){
+		regerror("out of memory");
+		return 0;
+	}
+	freep = pp->firstinst;
+	classp = pp->class;
+	errors = 0;
+
+	if(setjmp(regkaboom))
+		goto out;
+
+	/* go compile the sucker */
+	lexdone = 0;
+	exprp = s;
+	nclass = NCLASS;
+	nbra = 0;
+	atorp = atorstack;
+	andp = andstack;
+	subidp = subidstack;
+	lastwasand = FALSE;
+	cursubid = 0;
+
+	/* Start with a low priority operator to prime parser */
+	pushator(START-1);
+	while((token = lex(literal, dot_type)) != END){
+		if((token&0300) == OPERATOR)
+			operator(token);
+		else
+			operand(token);
+	}
+
+	/* Close with a low priority operator */
+	evaluntil(START);
+
+	/* Force END */
+	operand(END);
+	evaluntil(START);
+#ifdef DEBUG
+	dumpstack();
+#endif
+	if(nbra)
+		rcerror("unmatched left paren");
+	--andp;	/* points to first and only operand */
+	pp->startinst = andp->first;
+#ifdef DEBUG
+	dump(pp);
+#endif
+	pp = optimize(pp);
+#ifdef DEBUG
+	print("start: %d\n", andp->first-pp->firstinst);
+	dump(pp);
+#endif
+out:
+	if(errors){
+		free(pp);
+		pp = 0;
+	}
+	return pp;
+}
+
+extern	Reprog*
+regcomp(char *s)
+{
+	return regcomp1(s, 0, ANY);
+}
+
+extern	Reprog*
+regcomplit(char *s)
+{
+	return regcomp1(s, 1, ANY);
+}
+
+extern	Reprog*
+regcompnl(char *s)
+{
+	return regcomp1(s, 0, ANYNL);
+}
blob - /dev/null
blob + 4f550095c82acf7252d589f075bc9f945b861d30 (mode 644)
--- /dev/null
+++ src/cmd/upas/bayes/regen.c
@@ -0,0 +1,176 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <regexp.h>
+#include "dfa.h"
+
+/***
+ * Regular expression for matching.
+ */
+
+char *ignore[] = 
+{
+	/* HTML that isn't A, IMG, or FONT */
+	/* Must have a space somewhere to avoid catching <email@address> */
+	"<[ 	\n\r]*("
+		"[^aif]|"
+		"a[^> \t\r\n]|"
+		"i[^mM \t\r\n]|"
+		"im[^gG \t\r\n]|"
+		"img[^> \t\r\n]|"
+		"f[^oO \t\r\n]|"
+		"fo[^Nn \t\r\n]|"
+		"fon[^tT \t\r\n]|"
+		"font[^> \r\t\n]"
+	")[^>]*[ \t\n\r][^>]*>",
+	"<[ 	\n\r]*("
+		"i|im|f|fo|fon"
+	")[ \t\r\n][^>]*>",
+
+	/* ignore html comments */
+	"<!--([^\\-]|-[^\\-]|--[^>]|\n)*-->",
+
+	/* random mail strings */
+	"^message-id:.*\n([ 	].*\n)*",
+	"^in-reply-to:.*\n([ 	].*\n)*",
+	"^references:.*\n([ 	].*\n)*",
+	"^date:.*\n([ 	].*\n)*",
+	"^delivery-date:.*\n([ 	].*\n)*",
+	"e?smtp id .*",
+	"^	id.*",
+	"boundary=.*",
+	"name=\"",
+	"filename=\"",
+	"news:<[^>]+>",
+	"^--[^ 	]*$",
+
+	/* base64 encoding */
+	"^[0-9a-zA-Z+\\-=/]+$",
+
+	/* uu encoding */
+	"^[!-Z]+$",
+
+	/* little things */
+	".",
+	"\n",
+};
+
+char *keywords[] =
+{
+	"([a-zA-Z'`$!¡-￿]|[0-9]([.,][0-9])*)+",
+};
+
+int debug;
+
+Dreprog*
+dregcomp(char *buf)
+{
+	Reprog *r;
+	Dreprog *d;
+
+	if(debug)
+		print(">>> '%s'\n", buf);
+
+	r = regcomp(buf);
+	if(r == nil)
+		sysfatal("regcomp");
+	d = dregcvt(r);
+	if(d == nil)
+		sysfatal("dregcomp");
+	free(r);
+	return d;
+}
+
+char*
+strcpycase(char *d, char *s)
+{
+	int cc, esc;
+
+	cc = 0;
+	esc = 0;
+	while(*s){
+		if(*s == '[')
+			cc++;
+		if(*s == ']')
+			cc--;
+		if(!cc && 'a' <= *s && *s <= 'z'){
+			*d++ = '[';
+			*d++ = *s;
+			*d++ = *s+'A'-'a';
+			*d++ = ']';
+		}else
+			*d++ = *s;
+		if(*s == '\\')
+			esc++;
+		else if(esc)
+			esc--;
+		s++;
+	}
+	return d;
+}
+
+void
+regerror(char *msg)
+{
+	sysfatal("regerror: %s", msg);
+}
+
+void
+buildre(Dreprog *re[3])
+{
+	int i;
+	static char buf[16384], *s;
+
+	re[0] = dregcomp("^From ");
+	
+	s = buf;
+	for(i=0; i<nelem(keywords); i++){
+		if(i != 0)
+			*s++ = '|';
+		s = strcpycase(s, keywords[i]);
+	}
+	*s = 0;
+	re[1] = dregcomp(buf);
+
+	s = buf;
+	for(i=0; i<nelem(ignore); i++){
+		if(i != 0)
+			*s++ = '|';
+		s = strcpycase(s, ignore[i]);
+	}
+	*s = 0;
+	re[2] = dregcomp(buf);
+}
+
+void
+usage(void)
+{
+	fprint(2, "usage: regen [-d]\n");
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	Dreprog *re[3];
+	Biobuf b;
+
+	ARGBEGIN{
+	default:
+		usage();
+	case 'd':
+		debug = 1;
+	}ARGEND
+
+	if(argc != 0)
+		usage();
+
+	buildre(re);
+	Binit(&b, 1, OWRITE);
+	Bprintdfa(&b, re[0]);
+	Bprintdfa(&b, re[1]);
+	Bprintdfa(&b, re[2]);
+	exits(0);
+}
+
+	
\ No newline at end of file
blob - /dev/null
blob + 98f515789ea3bb426ea8615993c722c0d5a6e7f1 (mode 644)
--- /dev/null
+++ src/cmd/upas/common/appendfiletombox.c
@@ -0,0 +1,155 @@
+#include "common.h"
+
+enum {
+	Buffersize = 64*1024,
+};
+
+typedef struct Inbuf Inbuf;
+struct Inbuf
+{
+	char buf[Buffersize];
+	char *wp;
+	char *rp;
+	int eof;
+	int in;
+	int out;
+	int last;
+	ulong bytes;
+};
+
+static Inbuf*
+allocinbuf(int in, int out)
+{
+	Inbuf *b;
+
+	b = mallocz(sizeof(Inbuf), 1);
+	if(b == nil)
+		sysfatal("reading mailbox: %r");
+	b->rp = b->wp = b->buf;
+	b->in = in;
+	b->out = out;
+	return b;
+}
+
+static int
+fill(Inbuf *b, int addspace)
+{
+	int i, n;
+
+	if(b->eof && b->wp - b->rp == 0)
+		return 0;
+
+	n = b->rp - b->buf;
+	if(n > 0){
+		i = write(b->out, b->buf, n);
+		if(i != n)
+			return -1;
+		b->last = b->buf[n-1];
+		b->bytes += n;
+	}
+	if(addspace){
+		if(write(b->out, " ", 1) != 1)
+			return -1;
+		b->last = ' ';
+		b->bytes++;
+	}
+
+	n = b->wp - b->rp;
+	memmove(b->buf, b->rp, n);
+	b->rp = b->buf;
+	b->wp = b->rp + n;
+
+	i = read(b->in, b->buf+n, sizeof(b->buf)-n);
+	if(i < 0)
+		return -1;
+	b->wp += i;
+
+	return b->wp - b->rp;
+}
+
+/* code to escape ' '*From' ' at the beginning of a line */
+int
+appendfiletombox(int in, int out)
+{
+	int addspace;
+	int n;
+	char *p;
+	int sol;
+	Inbuf *b;
+
+	seek(out, 0, 2);
+
+	b = allocinbuf(in, out);
+	addspace = 0;
+	sol = 1;
+
+	for(;;){
+		if(b->wp - b->rp < 5){
+			n = fill(b, addspace);
+			addspace = 0;
+			if(n < 0)
+				goto error;
+			if(n == 0)
+				break;
+			if(n < 5){
+				b->rp = b->wp;
+				continue;
+			}
+		}
+
+		/* state machine looking for ' '*From' ' */
+		if(!sol){
+			p = memchr(b->rp, '\n', b->wp - b->rp);
+			if(p == nil)
+				b->rp = b->wp;
+			else{
+				b->rp = p+1;
+				sol = 1;
+			}
+			continue;
+		} else {
+			if(*b->rp == ' ' || strncmp(b->rp, "From ", 5) != 0){
+				b->rp++;
+				continue;
+			}
+			addspace = 1;
+			sol = 0;
+		}
+	}
+
+	/* mailbox entries always terminate with two newlines */
+	n = b->last == '\n' ? 1 : 2;
+	if(write(out, "\n\n", n) != n)
+		goto error;
+	n += b->bytes;
+	free(b);
+	return n;
+error:
+	free(b);
+	return -1;
+}
+
+int
+appendfiletofile(int in, int out)
+{
+	int n;
+	Inbuf *b;
+
+	seek(out, 0, 2);
+
+	b = allocinbuf(in, out);
+	for(;;){
+		n = fill(b, 0);
+		if(n < 0)
+			goto error;
+		if(n == 0)
+			break;
+		b->rp = b->wp;
+	}
+	n = b->bytes;
+	free(b);
+	return n;
+error:
+	free(b);
+	return -1;
+}
blob - /dev/null
blob + 7577acaeaf432ac9bece1835a3af24e6fed1edef (mode 644)
--- /dev/null
+++ src/cmd/upas/common/aux.c
@@ -0,0 +1,148 @@
+#include "common.h"
+
+/* expand a path relative to some `.' */
+extern String *
+abspath(char *path, char *dot, String *to)
+{
+	if (*path == '/') {
+		to = s_append(to, path);
+	} else {
+		to = s_append(to, dot);
+		to = s_append(to, "/");
+		to = s_append(to, path);
+	}
+	return to;
+}
+
+/* return a pointer to the base component of a pathname */
+extern char *
+basename(char *path)
+{
+	char *cp;
+
+	cp = strrchr(path, '/');
+	return cp==0 ? path : cp+1;
+}
+
+/* append a sub-expression match onto a String */
+extern void
+append_match(Resub *subexp, String *sp, int se)
+{
+	char *cp, *ep;
+
+	cp = subexp[se].s.sp;    /* jpc .sp -> .s.sp */
+	ep = subexp[se].e.ep;    /* jpc .ep -> .e.ep */
+	for (; cp < ep; cp++)
+		s_putc(sp, *cp);
+	s_terminate(sp);
+}
+
+/*
+ *  check for shell characters in a String
+ */
+static char *illegalchars = "\r\n";
+
+extern int
+shellchars(char *cp)
+{
+	char *sp;
+
+	for(sp=illegalchars; *sp; sp++)
+		if(strchr(cp, *sp))
+			return 1;
+	return 0;
+}
+
+static char *specialchars = " ()<>{};=\\'\`^&|";
+static char *escape = "%%";
+
+int
+hexchar(int x)
+{
+	x &= 0xf;
+	if(x < 10)
+		return '0' + x;
+	else
+		return 'A' + x - 10;
+}
+
+/*
+ *  rewrite a string to escape shell characters
+ */
+extern String*
+escapespecial(String *s)
+{
+	String *ns;
+	char *sp;
+
+	for(sp = specialchars; *sp; sp++)
+		if(strchr(s_to_c(s), *sp))
+			break;
+	if(*sp == 0)
+		return s;
+
+	ns = s_new();
+	for(sp = s_to_c(s); *sp; sp++){
+		if(strchr(specialchars, *sp)){
+			s_append(ns, escape);
+			s_putc(ns, hexchar(*sp>>4));
+			s_putc(ns, hexchar(*sp));
+		} else
+			s_putc(ns, *sp);
+	}
+	s_terminate(ns);
+	s_free(s);
+	return ns;
+}
+
+uint
+hex2uint(char x)
+{
+	if(x >= '0' && x <= '9')
+		return x - '0';
+	if(x >= 'A' && x <= 'F')
+		return (x - 'A') + 10;
+	if(x >= 'a' && x <= 'f')
+		return (x - 'a') + 10;
+	return -512;
+}
+
+/*
+ *  rewrite a string to remove shell characters escapes
+ */
+extern String*
+unescapespecial(String *s)
+{
+	String *ns;
+	char *sp;
+	uint c, n;
+
+	if(strstr(s_to_c(s), escape) == 0)
+		return s;
+	n = strlen(escape);
+
+	ns = s_new();
+	for(sp = s_to_c(s); *sp; sp++){
+		if(strncmp(sp, escape, n) == 0){
+			c = (hex2uint(sp[n])<<4) + hex2uint(sp[n+1]);
+			if(c < 0)
+				s_putc(ns, *sp);
+			else {
+				s_putc(ns, c);
+				sp += n+2-1;
+			}
+		} else
+			s_putc(ns, *sp);
+	}
+	s_terminate(ns);
+	s_free(s);
+	return ns;
+
+}
+
+int
+returnable(char *path)
+{
+
+	return strcmp(path, "/dev/null") != 0;
+}
blob - /dev/null
blob + 1b5aa4569be8d2af6d9ff8aff90721ea6052fefe (mode 644)
--- /dev/null
+++ src/cmd/upas/common/become.c
@@ -0,0 +1,28 @@
+#include "common.h"
+#include <auth.h>
+#include <ndb.h>
+
+/*
+ *  become powerless user
+ */
+int
+become(char **cmd, char *who)
+{
+	int fd;
+
+	USED(cmd);
+	if(strcmp(who, "none") == 0) {
+		fd = open("#c/user", OWRITE);
+		if(fd < 0 || write(fd, "none", strlen("none")) < 0) {
+			werrstr("can't become none");
+			return -1;
+		}
+		close(fd);
+		// jpc if(newns("none", 0)) {
+		// jpc 	werrstr("can't set new namespace");
+		// jpc	return -1;
+		// jpc }
+	}
+	return 0;
+}
+
blob - /dev/null
blob + d1e93841cd881726f69233b37c0ce04b1b78f8ec (mode 644)
--- /dev/null
+++ src/cmd/upas/common/common.h
@@ -0,0 +1,79 @@
+#include "sys.h"
+
+/* format of REMOTE FROM lines */
+extern char *REMFROMRE;
+extern int REMSENDERMATCH;
+extern int REMDATEMATCH;
+extern int REMSYSMATCH;
+
+/* format of mailbox FROM lines */
+#define IS_HEADER(p) ((p)[0]=='F'&&(p)[1]=='r'&&(p)[2]=='o'&&(p)[3]=='m'&&(p)[4]==' ')
+#define IS_TRAILER(p) ((p)[0]=='m'&&(p)[1]=='o'&&(p)[2]=='r'&&(p)[3]=='F'&&(p)[4]=='\n')
+extern char *FROMRE;
+extern int SENDERMATCH;
+extern int DATEMATCH;
+
+enum
+{
+	Elemlen= 28,
+	Errlen=	128,
+	Pathlen= 256,
+};
+
+/*
+ *  routines in mail.c
+ */
+extern int	print_header(Biobuf*, char*, char*);
+extern int	print_remote_header(Biobuf*, char*, char*, char*);
+extern int	parse_header(char*, String*, String*);
+
+/*
+ *  routines in aux.c
+ */
+extern String	*abspath(char*, char*, String*);
+extern String	*mboxpath(char*, char*, String*, int);
+extern char	*basename(char*);
+extern int	delivery_status(String*);
+extern void	append_match(Resub*, String*, int);
+extern int	shellchars(char*);
+extern String*	escapespecial(String*);
+extern String*	unescapespecial(String*);
+extern int	returnable(char*);
+
+/* in copymessage */
+extern int	appendfiletombox(int, int);
+extern int	appendfiletofile(int, int);
+
+/* mailbox types */
+#define MF_NORMAL 0
+#define MF_PIPE 1
+#define MF_FORWARD 2
+#define MF_NOMBOX 3
+#define MF_NOTMBOX 4
+
+/* a pipe between parent and child*/
+typedef struct {
+	Biobuf	bb;
+	Biobuf	*fp;	/* parent process end*/
+	int	fd;	/* child process end*/
+} stream;
+
+/* a child process*/
+typedef struct process{
+	stream	*std[3];	/* standard fd's*/
+	int	pid;		/* process identifier*/
+	int	status;		/* exit status*/
+	Waitmsg	*waitmsg;
+} process;
+
+extern stream	*instream(void);
+extern stream	*outstream(void);
+extern void	stream_free(stream*);
+extern process	*noshell_proc_start(char**, stream*, stream*, stream*, int, char*);
+extern process	*proc_start(char*, stream*, stream*, stream*, int, char*);
+extern int	proc_wait(process*);
+extern int	proc_free(process*);
+extern int	proc_kill(process*);
+
+/* tell compiler we're using a value so it won't complain */
+#define USE(x)	if(x)
blob - /dev/null
blob + 4bbaff83384400e35fc2159a9961b25ef94348b3 (mode 644)
--- /dev/null
+++ src/cmd/upas/common/config.c
@@ -0,0 +1,11 @@
+#include "common.h"
+
+char *MAILROOT =	"#9/mail";
+char *UPASLOG =		"#9/sys/log";
+char *UPASLIB = 	"#9/mail/lib";
+char *UPASBIN=		"#9/bin/upas";
+char *UPASTMP = 	"#9/mail/tmp";
+char *SHELL = 		"#9/bin/rc";
+char *POST =		"#9/sys/lib/post/dispatch";
+
+int MBOXMODE = 0662;
blob - /dev/null
blob + 7266859d12cd813b7597b64d66f15728e8a7eca9 (mode 644)
Binary files /dev/null and src/cmd/upas/common/libcommon.a differ
blob - /dev/null
blob + fc666a9dbc6dcf79a782b91465956feaa6edb00f (mode 644)
--- /dev/null
+++ src/cmd/upas/mkfile
@@ -0,0 +1,37 @@
+<$PLAN9/src/mkhdr
+
+LIBS=common
+#PROGS=smtp alias fs ned misc q send scanmail pop3 ml marshal vf filterkit unesc
+PROGS=smtp alias fs ned q send marshal vf 
+#libs must be made first
+DIRS=$LIBS $PROGS
+
+<$PLAN9/src/mkdirs
+
+#
+# setup the mail directories.  this should be done by the administrator since
+# he/she will own everything.  the following files must be altered to reflect
+# local preference.
+#
+# /mail/lib/namefiles	- remove alias files you don't use, insert ones you do.
+# /mail/lib/remotemail	- change '-g research.research.bell-labs.com' to your own mail
+#			  gateway.  if you have none, remove it.
+#			- change '-h plan9.bell-labs.com' to a name you would like
+#			  this host to be known as.  if you don't care, take it
+#			  out and it will use the name in /env/site.
+# /mail/lib/rewrite	- change the line that contains 'helix' to include names,
+#			  other than the contents of /env/site, that your system
+#			  answers to.  this is a hack and will be fixed.
+#
+setup:V:
+	mkdir /mail
+	chmod 775 /mail
+	mkdir /mail/lib
+	chmod 775 /mail/lib
+	mkdir /mail/queue
+	mkdir /mail/box
+	mkdir /mail/tmp
+	chmod 777 /mail/queue /mail/box /mail/tmp
+	mkdir /mail/ml
+	chmod 775 /mail/ml
+	cp misc/rewrite misc/qmail misc/remotemail misc/namefiles /mail/lib
blob - /dev/null
blob + 8845999ba51efa7bfdbbbdbf40405e551c32159b (mode 644)
--- /dev/null
+++ src/cmd/upas/mkfile.9
@@ -0,0 +1,99 @@
+<$PLAN9/src/mkhdr
+
+LIBS=common
+#PROGS=smtp alias fs ned misc q send scanmail pop3 ml marshal vf filterkit unesc
+PROGS=smtp alias fs q send marshal vf 
+#libs must be made first
+DIRS=$LIBS $PROGS
+
+UPDATE=\
+	mkfile\
+	/sys/man/1/mail\
+
+all:V:
+	for i in $DIRS
+	do
+		(cd $i; mk $stem)
+	done
+
+clean:V:
+	for (i in $DIRS) @{
+		cd $i
+		mk clean
+	}
+
+nuke:V:
+	for (i in $LIBS) @{
+		cd $i
+		mk nuke
+	}
+	for (i in $PROGS) @{
+		cd $i
+		mk clean
+	}
+
+install:V:
+	for (i in $DIRS) @{
+		cd $i
+		mk install
+	}
+
+installall:V:
+	for (i in $DIRS) @{
+		cd $i
+		mk installall
+	}
+	for (i in $DIRS) @{
+		cd $i
+		mk clean
+	}
+
+safeinstallall:V:
+	for (i in $LIBS) @{
+		cd $i
+		mk installall
+	}
+	for (i in $PROGS) @{
+		cd $i
+		mk safeinstallall
+	}
+	for (i in $DIRS) @{
+		cd $i
+		mk clean
+	}
+
+update:V:
+	update $UPDATEFLAGS $UPDATE
+	for (i in $DIRS) @{
+		cd $i
+		echo '>>>>>>>>>>' `{pwd} '<<<<<<<<<<<'
+		mk $MKFLAGS 'UPDATEFLAGS='$"UPDATEFLAGS update
+	}
+
+#
+# setup the mail directories.  this should be done by the administrator since
+# he/she will own everything.  the following files must be altered to reflect
+# local preference.
+#
+# /mail/lib/namefiles	- remove alias files you don't use, insert ones you do.
+# /mail/lib/remotemail	- change '-g research.research.bell-labs.com' to your own mail
+#			  gateway.  if you have none, remove it.
+#			- change '-h plan9.bell-labs.com' to a name you would like
+#			  this host to be known as.  if you don't care, take it
+#			  out and it will use the name in /env/site.
+# /mail/lib/rewrite	- change the line that contains 'helix' to include names,
+#			  other than the contents of /env/site, that your system
+#			  answers to.  this is a hack and will be fixed.
+#
+setup:V:
+	mkdir /mail
+	chmod 775 /mail
+	mkdir /mail/lib
+	chmod 775 /mail/lib
+	mkdir /mail/queue
+	mkdir /mail/box
+	mkdir /mail/tmp
+	chmod 777 /mail/queue /mail/box /mail/tmp
+	mkdir /mail/ml
+	chmod 775 /mail/ml
+	cp misc/rewrite misc/qmail misc/remotemail misc/namefiles /mail/lib
blob - /dev/null
blob + 11905ac1eba6f6fc3eee5bff40dfbe23ac5ef440 (mode 644)
--- /dev/null
+++ src/cmd/upas/notes
@@ -0,0 +1,50 @@
+upas:
+	from thread(3):
+		It is not safe to call rfork in a  threaded  program,  except  to  call
+		rfork(RFNOTEG) from the main proc before any other procs have been cre-
+		ated.  To create new processes, use proccreate.
+
+
+upas/fs:
+	when serving a file writes tbox.tmp when writing back tbox.
+	make L.mbox in home directory (sometimes)
+
+	=======> auth stuff:
+	Server, Certificate, ...
+	
+	    * POP3/IMAP Server (receiving emails): mail.physik.fu-berlin.de (unchanged)
+	    * SMTP Server (sending emails): mail.physik.fu-berlin.de (unchanged and not relevant for this change [no STARTTLS/SMTP_AUTH])
+	    * Certificate Authority (CA) Certificate: cacert.crt (CN=ZEDV)
+	      SHA1 Fingerprint: 37:19:00:47:BB:91:20:94:3B:AA:A7:75:57:D5:4C:0D:EA:5C:18:D9
+	      MD5 Fingerprint: 56:58:1C:91:DC:08:1B:42:D0:C2:D6:D4:FF:28:AE:C5
+	    * mail.physik.fu-berlin.de Fingerprints (IMAP/POP3):
+	      SHA1 Fingerprint: 75:C6:A5:1E:CB:F4:33:2E:95:85:A0:65:87:71:19:08:3D:19:FE:7D
+	      MD5 Fingerprint: 67:76:23:98:65:0A:39:44:5B:79:BD:91:31:49:59:7A
+	
+	The fingerprints can be displayed in the mail clients and can be optained using:
+	
+	openssl s_client -connect mail.physik.fu-berlin.de:993 -showcerts # IMAP
+	openssl s_client -connect mail.physik.fu-berlin.de:995 -showcerts # POP3
+	
+	Save all between -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----
+	
+	openssl x509       -noout -fingerprint -in mail.physik.fu-berlin.de.pem # MD5
+	openssl x509 -sha1 -noout -fingerprint -in mail.physik.fu-berlin.de.pem # SHA1
+	
+	<======= auth stuff
+
+upas/ned:
+	need to understand singleton stuff.
+	
+	need to understand wait (cf lpdaemon.c ~315)  is it safe to fork in a threaded prog? shoud i use proccreate?
+	
+	routines to check/fix:
+		appendtofile()
+		switchmb()
+		rooted()
+		plumb() <= understand how this works, it may help in deciding how to present attachments in acme/Mail
+	
+
+upas/marshal:
+	some attachments work, some don't. looks like pdf files work while ps don't!? problem in body64()
+	actually, it seems like the size of attachment is the problem: large attacments don't seem to work, somewhere between 19967 and 161065 is the failure point.
\ No newline at end of file