diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:20:00 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:20:00 +0000 |
commit | 8daa83a594a2e98f39d764422bfbdbc62c9efd44 (patch) | |
tree | 4099e8021376c7d8c05bdf8503093d80e9c7bad0 /lib/ldb/ldb_sqlite3 | |
parent | Initial commit. (diff) | |
download | samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.tar.xz samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.zip |
Adding upstream version 2:4.20.0+dfsg.upstream/2%4.20.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/ldb/ldb_sqlite3')
-rw-r--r-- | lib/ldb/ldb_sqlite3/README | 7 | ||||
-rw-r--r-- | lib/ldb/ldb_sqlite3/base160.c | 154 | ||||
-rw-r--r-- | lib/ldb/ldb_sqlite3/ldb_sqlite3.c | 1958 | ||||
-rw-r--r-- | lib/ldb/ldb_sqlite3/schema | 328 | ||||
-rw-r--r-- | lib/ldb/ldb_sqlite3/trees.ps | 1760 |
5 files changed, 4207 insertions, 0 deletions
diff --git a/lib/ldb/ldb_sqlite3/README b/lib/ldb/ldb_sqlite3/README new file mode 100644 index 0000000..6cda0a7 --- /dev/null +++ b/lib/ldb/ldb_sqlite3/README @@ -0,0 +1,7 @@ +trees.ps contains an explanation of the Genealogical Representation of Trees +in Databases which is being used in ldb_sqlite3. Note that we use fgID +representation with 4 bytes per level, so we can represent 6.5E+08 subclasses +of any object class. This should be adequate for our purposes. :-) + +The following document is the primary basis for the schema currently being +used here: http://www.research.ibm.com/journal/sj/392/shi.html diff --git a/lib/ldb/ldb_sqlite3/base160.c b/lib/ldb/ldb_sqlite3/base160.c new file mode 100644 index 0000000..7ad39f7 --- /dev/null +++ b/lib/ldb/ldb_sqlite3/base160.c @@ -0,0 +1,154 @@ +/* + base160 code used by ldb_sqlite3 + + Copyright (C) 2004 Derrell Lipman + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ + + +/* + * ldb_sqlite3_base160() + * + * Convert an integer value to a string containing the base 160 representation + * of the integer. We always convert to a string representation that is 4 + * bytes in length, and we always null terminate. + * + * Parameters: + * val -- + * The value to be converted + * + * result -- + * Buffer in which the result is to be placed + * + * Returns: + * nothing + */ +static unsigned char base160tab[161] = +{ + 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , /* 0-9 */ + 58 , 59 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , /* : ; A-H */ + 73 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 81 , 82 , /* I-R */ + 83 , 84 , 85 , 86 , 87 , 88 , 89 , 90 , 97 , 98 , /* S-Z , a-b */ + 99 , 100, 101, 102, 103, 104, 105, 106, 107, 108, /* c-l */ + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, /* m-v */ + 119, 120, 121, 122, 160, 161, 162, 163, 164, 165, /* w-z, latin1 */ + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, /* latin1 */ + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, /* latin1 */ + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, /* latin1 */ + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, /* latin1 */ + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, /* latin1 */ + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, /* latin1 */ + 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, /* latin1 */ + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, /* latin1 */ + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, /* latin1 */ + '\0' +}; + + +/* + * lsqlite3_base160() + * + * Convert an unsigned long integer into a base160 representation of the + * number. + * + * Parameters: + * val -- + * value to be converted + * + * result -- + * character array, 5 bytes long, into which the base160 representation + * will be placed. The result will be a four-digit representation of the + * number (with leading zeros prepended as necessary), and null + * terminated. + * + * Returns: + * Nothing + */ +void +lsqlite3_base160(unsigned long val, + unsigned char result[5]) +{ + int i; + + for (i = 3; i >= 0; i--) { + + result[i] = base160tab[val % 160]; + val /= 160; + } + + result[4] = '\0'; +} + + +/* + * lsqlite3_base160Next() + * + * Retrieve the next-greater number in the base160 sequence for the terminal + * tree node (the last four digits). Only one tree level (four digits) are + * operated on. + * + * Parameters: + * base160 -- a character array containing either an empty string (in which + * case no operation is performed), or a string of base160 digits + * with a length of a multiple of four digits. + * + * Upon return, the trailing four digits (one tree level) will + * have been incremented by 1. + * + * Returns: + * base160 -- the modified array + */ +char * +lsqlite3_base160Next(char base160[]) +{ + int i; + int len; + unsigned char * pTab; + char * pBase160 = base160; + + /* + * We need a minimum of four digits, and we will always get a multiple of + * four digits. + */ + if ((len = strlen(pBase160)) >= 4) + { + pBase160 += strlen(pBase160) - 1; + + /* We only carry through four digits: one level in the tree */ + for (i = 0; i < 4; i++) { + + /* What base160 value does this digit have? */ + pTab = strchr(base160tab, *pBase160); + + /* Is there a carry? */ + if (pTab < base160tab + sizeof(base160tab) - 1) { + + /* Nope. Just increment this value and we're done. */ + *pBase160 = *++pTab; + break; + } else { + + /* + * There's a carry. This value gets base160tab[0], we + * decrement the buffer pointer to get the next higher-order + * digit, and continue in the loop. + */ + *pBase160-- = base160tab[0]; + } + } + } + + return base160; +} diff --git a/lib/ldb/ldb_sqlite3/ldb_sqlite3.c b/lib/ldb/ldb_sqlite3/ldb_sqlite3.c new file mode 100644 index 0000000..26c7023 --- /dev/null +++ b/lib/ldb/ldb_sqlite3/ldb_sqlite3.c @@ -0,0 +1,1958 @@ +/* + ldb database library + + Copyright (C) Derrell Lipman 2005 + Copyright (C) Simo Sorce 2005-2009 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ + +/* + * Name: ldb + * + * Component: ldb sqlite3 backend + * + * Description: core files for SQLITE3 backend + * + * Author: Derrell Lipman (based on Andrew Tridgell's LDAP backend) + */ + +#include "ldb_module.h" + +#include <sqlite3.h> + +struct lsqlite3_private { + int trans_count; + char **options; + sqlite3 *sqlite; +}; + +struct lsql_context { + struct ldb_module *module; + struct ldb_request *req; + + /* search stuff */ + long long current_eid; + const char * const * attrs; + struct ldb_reply *ares; + + bool callback_failed; + struct tevent_timer *timeout_event; +}; + +/* + * Macros used throughout + */ + +#ifndef FALSE +# define FALSE (0) +# define TRUE (! FALSE) +#endif + +#define RESULT_ATTR_TABLE "temp_result_attrs" + + +/* for testing, define to nothing, (create non-temporary table) */ +#define TEMPTAB "TEMPORARY" + +/* + * Static variables + */ +sqlite3_stmt * stmtGetEID = NULL; + +static char *lsqlite3_tprintf(TALLOC_CTX *mem_ctx, const char *fmt, ...) +{ + char *str, *ret; + va_list ap; + + va_start(ap, fmt); + str = sqlite3_vmprintf(fmt, ap); + va_end(ap); + + if (str == NULL) return NULL; + + ret = talloc_strdup(mem_ctx, str); + if (ret == NULL) { + sqlite3_free(str); + return NULL; + } + + sqlite3_free(str); + return ret; +} + +static char base160tab[161] = { + 48 ,49 ,50 ,51 ,52 ,53 ,54 ,55 ,56 ,57 , /* 0-9 */ + 58 ,59 ,65 ,66 ,67 ,68 ,69 ,70 ,71 ,72 , /* : ; A-H */ + 73 ,74 ,75 ,76 ,77 ,78 ,79 ,80 ,81 ,82 , /* I-R */ + 83 ,84 ,85 ,86 ,87 ,88 ,89 ,90 ,97 ,98 , /* S-Z , a-b */ + 99 ,100,101,102,103,104,105,106,107,108, /* c-l */ + 109,110,111,112,113,114,115,116,117,118, /* m-v */ + 119,120,121,122,160,161,162,163,164,165, /* w-z, latin1 */ + 166,167,168,169,170,171,172,173,174,175, /* latin1 */ + 176,177,178,179,180,181,182,183,184,185, /* latin1 */ + 186,187,188,189,190,191,192,193,194,195, /* latin1 */ + 196,197,198,199,200,201,202,203,204,205, /* latin1 */ + 206,207,208,209,210,211,212,213,214,215, /* latin1 */ + 216,217,218,219,220,221,222,223,224,225, /* latin1 */ + 226,227,228,229,230,231,232,233,234,235, /* latin1 */ + 236,237,238,239,240,241,242,243,244,245, /* latin1 */ + 246,247,248,249,250,251,252,253,254,255, /* latin1 */ + '\0' +}; + + +/* + * base160() + * + * Convert an unsigned long integer into a base160 representation of the + * number. + * + * Parameters: + * val -- + * value to be converted + * + * result -- + * character array, 5 bytes long, into which the base160 representation + * will be placed. The result will be a four-digit representation of the + * number (with leading zeros prepended as necessary), and null + * terminated. + * + * Returns: + * Nothing + */ +static void +base160_sql(sqlite3_context * hContext, + int argc, + sqlite3_value ** argv) +{ + int i; + long long val; + char result[5]; + + val = sqlite3_value_int64(argv[0]); + + for (i = 3; i >= 0; i--) { + + result[i] = base160tab[val % 160]; + val /= 160; + } + + result[4] = '\0'; + + sqlite3_result_text(hContext, result, -1, SQLITE_TRANSIENT); +} + + +/* + * base160next_sql() + * + * This function enhances sqlite by adding a "base160_next()" function which is + * accessible via queries. + * + * Retrieve the next-greater number in the base160 sequence for the terminal + * tree node (the last four digits). Only one tree level (four digits) is + * operated on. + * + * Input: + * A character string: either an empty string (in which case no operation is + * performed), or a string of base160 digits with a length of a multiple of + * four digits. + * + * Output: + * Upon return, the trailing four digits (one tree level) will have been + * incremented by 1. + */ +static void +base160next_sql(sqlite3_context * hContext, + int argc, + sqlite3_value ** argv) +{ + int i; + int len; + char * pTab; + char * pBase160 = strdup((const char *)sqlite3_value_text(argv[0])); + char * pStart = pBase160; + + /* + * We need a minimum of four digits, and we will always get a multiple + * of four digits. + */ + if (pBase160 != NULL && + (len = strlen(pBase160)) >= 4 && + len % 4 == 0) { + + if (pBase160 == NULL) { + + sqlite3_result_null(hContext); + return; + } + + pBase160 += strlen(pBase160) - 1; + + /* We only carry through four digits: one level in the tree */ + for (i = 0; i < 4; i++) { + + /* What base160 value does this digit have? */ + pTab = strchr(base160tab, *pBase160); + + /* Is there a carry? */ + if (pTab < base160tab + sizeof(base160tab) - 1) { + + /* + * Nope. Just increment this value and we're + * done. + */ + *pBase160 = *++pTab; + break; + } else { + + /* + * There's a carry. This value gets + * base160tab[0], we decrement the buffer + * pointer to get the next higher-order digit, + * and continue in the loop. + */ + *pBase160-- = base160tab[0]; + } + } + + sqlite3_result_text(hContext, + pStart, + strlen(pStart), + free); + } else { + sqlite3_result_value(hContext, argv[0]); + if (pBase160 != NULL) { + free(pBase160); + } + } +} + +static char *parsetree_to_sql(struct ldb_module *module, + void *mem_ctx, + const struct ldb_parse_tree *t) +{ + struct ldb_context *ldb; + const struct ldb_schema_attribute *a; + struct ldb_val value, subval; + char *wild_card_string; + char *child, *tmp; + char *ret = NULL; + char *attr; + unsigned int i; + + ldb = ldb_module_get_ctx(module); + + switch(t->operation) { + case LDB_OP_AND: + + tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]); + if (tmp == NULL) return NULL; + + for (i = 1; i < t->u.list.num_elements; i++) { + + child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]); + if (child == NULL) return NULL; + + tmp = talloc_asprintf_append(tmp, " INTERSECT %s ", child); + if (tmp == NULL) return NULL; + } + + ret = talloc_asprintf(mem_ctx, "SELECT * FROM ( %s )\n", tmp); + + return ret; + + case LDB_OP_OR: + + tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]); + if (tmp == NULL) return NULL; + + for (i = 1; i < t->u.list.num_elements; i++) { + + child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]); + if (child == NULL) return NULL; + + tmp = talloc_asprintf_append(tmp, " UNION %s ", child); + if (tmp == NULL) return NULL; + } + + return talloc_asprintf(mem_ctx, "SELECT * FROM ( %s ) ", tmp); + + case LDB_OP_NOT: + + child = parsetree_to_sql(module, mem_ctx, t->u.isnot.child); + if (child == NULL) return NULL; + + return talloc_asprintf(mem_ctx, + "SELECT eid FROM ldb_entry " + "WHERE eid NOT IN ( %s ) ", child); + + case LDB_OP_EQUALITY: + /* + * For simple searches, we want to retrieve the list of EIDs that + * match the criteria. + */ + attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); + if (value.data == NULL) { + return NULL; + } + + if (strcasecmp(t->u.equality.attr, "dn") == 0) { + /* DN query is a special ldb case */ + const char *cdn = ldb_dn_get_casefold( + ldb_dn_new(mem_ctx, ldb, + (const char *)value.data)); + if (cdn == NULL) { + return NULL; + } + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_entry " + "WHERE norm_dn = '%q'", cdn); + + } else { + /* A normal query. */ + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND norm_attr_value = '%q'", + attr, + value.data); + + } + + case LDB_OP_SUBSTRING: + + wild_card_string = talloc_strdup(mem_ctx, + (t->u.substring.start_with_wildcard)?"*":""); + if (wild_card_string == NULL) return NULL; + + for (i = 0; t->u.substring.chunks[i]; i++) { + wild_card_string = talloc_asprintf_append(wild_card_string, "%s*", + t->u.substring.chunks[i]->data); + if (wild_card_string == NULL) return NULL; + } + + if ( ! t->u.substring.end_with_wildcard ) { + /* remove last wildcard */ + wild_card_string[strlen(wild_card_string) - 1] = '\0'; + } + + attr = ldb_attr_casefold(mem_ctx, t->u.substring.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + subval.data = (void *)wild_card_string; + subval.length = strlen(wild_card_string) + 1; + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(subval), &value); + if (value.data == NULL) { + return NULL; + } + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND norm_attr_value GLOB '%q'", + attr, + value.data); + + case LDB_OP_GREATER: + attr = ldb_attr_casefold(mem_ctx, t->u.comparison.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.comparison.value), &value); + if (value.data == NULL) { + return NULL; + } + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND ldap_compare(norm_attr_value, '>=', '%q', '%q') ", + attr, + value.data, + attr); + + case LDB_OP_LESS: + attr = ldb_attr_casefold(mem_ctx, t->u.comparison.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.comparison.value), &value); + if (value.data == NULL) { + return NULL; + } + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND ldap_compare(norm_attr_value, '<=', '%q', '%q') ", + attr, + value.data, + attr); + + case LDB_OP_PRESENT: + if (strcasecmp(t->u.present.attr, "dn") == 0) { + return talloc_strdup(mem_ctx, "SELECT eid FROM ldb_entry"); + } + + attr = ldb_attr_casefold(mem_ctx, t->u.present.attr); + if (attr == NULL) return NULL; + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' ", + attr); + + case LDB_OP_APPROX: + attr = ldb_attr_casefold(mem_ctx, t->u.comparison.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.comparison.value), &value); + if (value.data == NULL) { + return NULL; + } + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND ldap_compare(norm_attr_value, '~%', 'q', '%q') ", + attr, + value.data, + attr); + + case LDB_OP_EXTENDED: +#warning "work out how to handle bitops" + return NULL; + + default: + break; + }; + + /* should never occur */ + abort(); + return NULL; +} + +/* + * query_int() + * + * This function is used for the common case of queries that return a single + * integer value. + * + * NOTE: If more than one value is returned by the query, all but the first + * one will be ignored. + */ +static int +query_int(const struct lsqlite3_private * lsqlite3, + long long * pRet, + const char * pSql, + ...) +{ + int ret; + int bLoop; + char * p; + sqlite3_stmt * pStmt; + va_list args; + + /* Begin access to variable argument list */ + va_start(args, pSql); + + /* Format the query */ + if ((p = sqlite3_vmprintf(pSql, args)) == NULL) { + va_end(args); + return SQLITE_NOMEM; + } + + /* + * Prepare and execute the SQL statement. Loop allows retrying on + * certain errors, e.g. SQLITE_SCHEMA occurs if the schema changes, + * requiring retrying the operation. + */ + for (bLoop = TRUE; bLoop; ) { + + /* Compile the SQL statement into sqlite virtual machine */ + if ((ret = sqlite3_prepare(lsqlite3->sqlite, + p, + -1, + &pStmt, + NULL)) == SQLITE_SCHEMA) { + if (stmtGetEID != NULL) { + sqlite3_finalize(stmtGetEID); + stmtGetEID = NULL; + } + continue; + } else if (ret != SQLITE_OK) { + break; + } + + /* One row expected */ + if ((ret = sqlite3_step(pStmt)) == SQLITE_SCHEMA) { + if (stmtGetEID != NULL) { + sqlite3_finalize(stmtGetEID); + stmtGetEID = NULL; + } + (void) sqlite3_finalize(pStmt); + continue; + } else if (ret != SQLITE_ROW) { + (void) sqlite3_finalize(pStmt); + break; + } + + /* Get the value to be returned */ + *pRet = sqlite3_column_int64(pStmt, 0); + + /* Free the virtual machine */ + if ((ret = sqlite3_finalize(pStmt)) == SQLITE_SCHEMA) { + if (stmtGetEID != NULL) { + sqlite3_finalize(stmtGetEID); + stmtGetEID = NULL; + } + continue; + } else if (ret != SQLITE_OK) { + (void) sqlite3_finalize(pStmt); + break; + } + + /* + * Normal condition is only one time through loop. Loop is + * rerun in error conditions, via "continue", above. + */ + bLoop = FALSE; + } + + /* All done with variable argument list */ + va_end(args); + + + /* Free the memory we allocated for our query string */ + sqlite3_free(p); + + return ret; +} + +/* + * This is a bad hack to support ldap style comparisons within sqlite. + * val is the attribute in the row currently under test + * func is the desired test "<=" ">=" "~" ":" + * cmp is the value to compare against (eg: "test") + * attr is the attribute name the value of which we want to test + */ + +static void lsqlite3_compare(sqlite3_context *ctx, int argc, + sqlite3_value **argv) +{ + struct ldb_context *ldb = (struct ldb_context *)sqlite3_user_data(ctx); + const char *val = (const char *)sqlite3_value_text(argv[0]); + const char *func = (const char *)sqlite3_value_text(argv[1]); + const char *cmp = (const char *)sqlite3_value_text(argv[2]); + const char *attr = (const char *)sqlite3_value_text(argv[3]); + const struct ldb_schema_attribute *a; + struct ldb_val valX; + struct ldb_val valY; + int ret; + + switch (func[0]) { + /* greater */ + case '>': /* >= */ + a = ldb_schema_attribute_by_name(ldb, attr); + valX.data = (uint8_t *)cmp; + valX.length = strlen(cmp); + valY.data = (uint8_t *)val; + valY.length = strlen(val); + ret = a->syntax->comparison_fn(ldb, ldb, &valY, &valX); + if (ret >= 0) + sqlite3_result_int(ctx, 1); + else + sqlite3_result_int(ctx, 0); + return; + + /* lesser */ + case '<': /* <= */ + a = ldb_schema_attribute_by_name(ldb, attr); + valX.data = (uint8_t *)cmp; + valX.length = strlen(cmp); + valY.data = (uint8_t *)val; + valY.length = strlen(val); + ret = a->syntax->comparison_fn(ldb, ldb, &valY, &valX); + if (ret <= 0) + sqlite3_result_int(ctx, 1); + else + sqlite3_result_int(ctx, 0); + return; + + /* approx */ + case '~': + /* TODO */ + sqlite3_result_int(ctx, 0); + return; + + /* bitops */ + case ':': + /* TODO */ + sqlite3_result_int(ctx, 0); + return; + + default: + break; + } + + sqlite3_result_error(ctx, "Value must start with a special operation char (<>~:)!", -1); + return; +} + + +/* rename a record */ +static int lsqlite3_safe_rollback(sqlite3 *sqlite) +{ + char *errmsg; + int ret; + + /* execute */ + ret = sqlite3_exec(sqlite, "ROLLBACK;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3_safe_rollback: Error: %s\n", errmsg); + free(errmsg); + } + return -1; + } + + return 0; +} + +/* return an eid as result */ +static int lsqlite3_eid_callback(void *result, int col_num, char **cols, char **names) +{ + long long *eid = (long long *)result; + + if (col_num != 1) return SQLITE_ABORT; + if (strcasecmp(names[0], "eid") != 0) return SQLITE_ABORT; + + *eid = atoll(cols[0]); + return SQLITE_OK; +} + +/* + * add a single set of ldap message values to a ldb_message + */ +static int lsqlite3_search_callback(void *result, int col_num, char **cols, char **names) +{ + struct ldb_context *ldb; + struct lsql_context *ac; + struct ldb_message *msg; + long long eid; + unsigned int i; + int ret; + + ac = talloc_get_type(result, struct lsql_context); + ldb = ldb_module_get_ctx(ac->module); + + /* eid, dn, attr_name, attr_value */ + if (col_num != 4) return SQLITE_ABORT; + + eid = atoll(cols[0]); + + if (ac->ares) { + msg = ac->ares->message; + } + + if (eid != ac->current_eid) { /* here begin a new entry */ + + /* call the async callback for the last entry + * except the first time */ + if (ac->current_eid != 0) { + ret = ldb_msg_normalize(ldb, ac->req, msg, &msg); + if (ret != LDB_SUCCESS) { + return SQLITE_ABORT; + } + + ret = ldb_module_send_entry(ac->req, msg, NULL); + if (ret != LDB_SUCCESS) { + ac->callback_failed = true; + /* free msg object */ + TALLOC_FREE(msg); + return SQLITE_ABORT; + } + + /* free msg object */ + TALLOC_FREE(msg); + } + + /* start over */ + ac->ares = talloc_zero(ac, struct ldb_reply); + if (!ac->ares) return SQLITE_ABORT; + + msg = ldb_msg_new(ac->ares); + if (!msg) return SQLITE_ABORT; + + ac->ares->type = LDB_REPLY_ENTRY; + ac->current_eid = eid; + } + + if (msg->dn == NULL) { + msg->dn = ldb_dn_new(msg, ldb, cols[1]); + if (msg->dn == NULL) + return SQLITE_ABORT; + } + + if (ac->attrs) { + int found = 0; + for (i = 0; ac->attrs[i]; i++) { + if (strcasecmp(cols[2], ac->attrs[i]) == 0) { + found = 1; + break; + } + } + if (!found) goto done; + } + + if (ldb_msg_add_string(msg, cols[2], cols[3]) != 0) { + return SQLITE_ABORT; + } + +done: + ac->ares->message = msg; + return SQLITE_OK; +} + + +/* + * lsqlite3_get_eid() + * lsqlite3_get_eid_ndn() + * + * These functions are used for the very common case of retrieving an EID value + * given a (normalized) DN. + */ + +static long long lsqlite3_get_eid_ndn(sqlite3 *sqlite, void *mem_ctx, const char *norm_dn) +{ + char *errmsg; + char *query; + long long eid = -1; + long long ret; + + /* get object eid */ + query = lsqlite3_tprintf(mem_ctx, "SELECT eid " + "FROM ldb_entry " + "WHERE norm_dn = '%q';", norm_dn); + if (query == NULL) return -1; + + ret = sqlite3_exec(sqlite, query, lsqlite3_eid_callback, &eid, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3_get_eid: Fatal Error: %s\n", errmsg); + free(errmsg); + } + return -1; + } + + return eid; +} + +static long long lsqlite3_get_eid(struct lsqlite3_private *lsqlite3, + struct ldb_dn *dn) +{ + TALLOC_CTX *local_ctx; + long long eid = -1; + char *cdn; + + /* ignore ltdb specials */ + if (ldb_dn_is_special(dn)) { + return -1; + } + + /* create a local ctx */ + local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_get_eid local context"); + if (local_ctx == NULL) { + return -1; + } + + cdn = ldb_dn_alloc_casefold(local_ctx, dn); + if (!cdn) goto done; + + eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, local_ctx, cdn); + +done: + talloc_free(local_ctx); + return eid; +} + +/* + * Interface functions referenced by lsqlite3_ops + */ + +/* search for matching records, by tree */ +int lsql_search(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + char *norm_basedn; + char *sqlfilter; + char *errmsg; + char *query = NULL; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + if ((( ! ldb_dn_is_valid(req->op.search.base)) || + ldb_dn_is_null(req->op.search.base)) && + (req->op.search.scope == LDB_SCOPE_BASE || + req->op.search.scope == LDB_SCOPE_ONELEVEL)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->op.search.base) { + norm_basedn = ldb_dn_alloc_casefold(ctx, req->op.search.base); + if (norm_basedn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + } else norm_basedn = talloc_strdup(ctx, ""); + + /* Convert filter into a series of SQL conditions (constraints) */ + sqlfilter = parsetree_to_sql(module, ctx, req->op.search.tree); + + switch(req->op.search.scope) { + case LDB_SCOPE_DEFAULT: + case LDB_SCOPE_SUBTREE: + if (*norm_basedn != '\0') { + query = lsqlite3_tprintf(ctx, + "SELECT entry.eid,\n" + " entry.dn,\n" + " av.attr_name,\n" + " av.attr_value\n" + " FROM ldb_entry AS entry\n" + + " LEFT OUTER JOIN ldb_attribute_values AS av\n" + " ON av.eid = entry.eid\n" + + " WHERE entry.eid IN\n" + " (SELECT DISTINCT ldb_entry.eid\n" + " FROM ldb_entry\n" + " WHERE (ldb_entry.norm_dn GLOB('*,%q')\n" + " OR ldb_entry.norm_dn = '%q')\n" + " AND ldb_entry.eid IN\n" + " (%s)\n" + " )\n" + + " ORDER BY entry.eid ASC;", + norm_basedn, + norm_basedn, + sqlfilter); + } else { + query = lsqlite3_tprintf(ctx, + "SELECT entry.eid,\n" + " entry.dn,\n" + " av.attr_name,\n" + " av.attr_value\n" + " FROM ldb_entry AS entry\n" + + " LEFT OUTER JOIN ldb_attribute_values AS av\n" + " ON av.eid = entry.eid\n" + + " WHERE entry.eid IN\n" + " (SELECT DISTINCT ldb_entry.eid\n" + " FROM ldb_entry\n" + " WHERE ldb_entry.eid IN\n" + " (%s)\n" + " )\n" + + " ORDER BY entry.eid ASC;", + sqlfilter); + } + + break; + + case LDB_SCOPE_BASE: + query = lsqlite3_tprintf(ctx, + "SELECT entry.eid,\n" + " entry.dn,\n" + " av.attr_name,\n" + " av.attr_value\n" + " FROM ldb_entry AS entry\n" + + " LEFT OUTER JOIN ldb_attribute_values AS av\n" + " ON av.eid = entry.eid\n" + + " WHERE entry.eid IN\n" + " (SELECT DISTINCT ldb_entry.eid\n" + " FROM ldb_entry\n" + " WHERE ldb_entry.norm_dn = '%q'\n" + " AND ldb_entry.eid IN\n" + " (%s)\n" + " )\n" + + " ORDER BY entry.eid ASC;", + norm_basedn, + sqlfilter); + break; + + case LDB_SCOPE_ONELEVEL: + query = lsqlite3_tprintf(ctx, + "SELECT entry.eid,\n" + " entry.dn,\n" + " av.attr_name,\n" + " av.attr_value\n" + " FROM ldb_entry AS entry\n" + + " LEFT OUTER JOIN ldb_attribute_values AS av\n" + " ON av.eid = entry.eid\n" + + " WHERE entry.eid IN\n" + " (SELECT DISTINCT ldb_entry.eid\n" + " FROM ldb_entry\n" + " WHERE norm_dn GLOB('*,%q')\n" + " AND NOT norm_dn GLOB('*,*,%q')\n" + " AND ldb_entry.eid IN\n(%s)\n" + " )\n" + + " ORDER BY entry.eid ASC;", + norm_basedn, + norm_basedn, + sqlfilter); + break; + } + + if (query == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* * / + printf ("%s\n", query); + / * */ + + ctx->current_eid = 0; + ctx->attrs = req->op.search.attrs; + ctx->ares = NULL; + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + ret = sqlite3_exec(lsqlite3->sqlite, query, lsqlite3_search_callback, ctx, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + /* complete the last message if any */ + if (ctx->ares) { + ret = ldb_msg_normalize(ldb, ctx->ares, + ctx->ares->message, + &ctx->ares->message); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_module_send_entry(req, ctx->ares->message, NULL); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + + return LDB_SUCCESS; +} + +/* add a record */ +static int lsql_add(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + struct ldb_message *msg = req->op.add.message; + long long eid; + char *dn, *ndn; + char *errmsg; + char *query; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + /* See if this is an ltdb special */ + if (ldb_dn_is_special(msg->dn)) { +/* + struct ldb_dn *c; + c = ldb_dn_new(local_ctx, ldb, "@INDEXLIST"); + if (ldb_dn_compare(ldb, msg->dn, c) == 0) { +#warning "should we handle indexes somehow ?" + ret = LDB_ERR_UNWILLING_TO_PERFORM; + goto done; + } +*/ + /* Others return an error */ + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + /* create linearized and normalized dns */ + dn = ldb_dn_alloc_linearized(ctx, msg->dn); + ndn = ldb_dn_alloc_casefold(ctx, msg->dn); + if (dn == NULL || ndn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + query = lsqlite3_tprintf(ctx, + /* Add new entry */ + "INSERT OR ABORT INTO ldb_entry " + "('dn', 'norm_dn') " + "VALUES ('%q', '%q');", + dn, ndn); + if (query == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, ctx, ndn); + if (eid == -1) { + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i = 0; i < msg->num_elements; i++) { + const struct ldb_message_element *el = &msg->elements[i]; + const struct ldb_schema_attribute *a; + char *attr; + unsigned int j; + + /* Get a case-folded copy of the attribute name */ + attr = ldb_attr_casefold(ctx, el->name); + if (attr == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + a = ldb_schema_attribute_by_name(ldb, el->name); + + if (el->num_value == 0) { + ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)", + el->name, ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + /* For each value of the specified attribute name... */ + for (j = 0; j < el->num_values; j++) { + struct ldb_val value; + char *insert; + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); + if (value.data == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + insert = lsqlite3_tprintf(ctx, + "INSERT OR ROLLBACK INTO ldb_attribute_values " + "('eid', 'attr_name', 'norm_attr_name'," + " 'attr_value', 'norm_attr_value') " + "VALUES ('%lld', '%q', '%q', '%q', '%q');", + eid, el->name, attr, + el->values[j].data, value.data); + if (insert == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, insert, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + } + } + + return LDB_SUCCESS; +} + +/* modify a record */ +static int lsql_modify(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + struct ldb_message *msg = req->op.mod.message; + long long eid; + char *errmsg; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + /* See if this is an ltdb special */ + if (ldb_dn_is_special(msg->dn)) { + /* Others return an error */ + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + eid = lsqlite3_get_eid(lsqlite3, msg->dn); + if (eid == -1) { + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i = 0; i < msg->num_elements; i++) { + const struct ldb_message_element *el = &msg->elements[i]; + const struct ldb_schema_attribute *a; + unsigned int flags = el->flags & LDB_FLAG_MOD_MASK; + char *attr; + char *mod; + unsigned int j; + + /* Get a case-folded copy of the attribute name */ + attr = ldb_attr_casefold(ctx, el->name); + if (attr == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + a = ldb_schema_attribute_by_name(ldb, el->name); + + switch (flags) { + + case LDB_FLAG_MOD_REPLACE: + struct ldb_val *duplicate = NULL; + + ret = ldb_msg_find_duplicate_val(ldb, el, el, + &duplicate, 0); + if (ret != LDB_SUCCESS) { + return ret; + } + if (duplicate != NULL) { + ldb_asprintf_errstring( + ldb, + "attribute '%s': value '%.*s' " + "on '%s' provided more than " + "once in REPLACE", + el->name, + (int)duplicate->length, + duplicate->data, + ldb_dn_get_linearized(msg2->dn)); + return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + } + + /* remove all attributes before adding the replacements */ + mod = lsqlite3_tprintf(ctx, + "DELETE FROM ldb_attribute_values " + "WHERE eid = '%lld' " + "AND norm_attr_name = '%q';", + eid, attr); + if (mod == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + /* MISSING break is INTENTIONAL */ + + case LDB_FLAG_MOD_ADD: + + if (el->num_values == 0) { + ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)", + el->name, ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + /* For each value of the specified attribute name... */ + for (j = 0; j < el->num_values; j++) { + struct ldb_val value; + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); + if (value.data == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + mod = lsqlite3_tprintf(ctx, + "INSERT OR ROLLBACK INTO ldb_attribute_values " + "('eid', 'attr_name', 'norm_attr_name'," + " 'attr_value', 'norm_attr_value') " + "VALUES ('%lld', '%q', '%q', '%q', '%q');", + eid, el->name, attr, + el->values[j].data, value.data); + + if (mod == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + } + + break; + + case LDB_FLAG_MOD_DELETE: +#warning "We should throw an error if the attribute we are trying to delete does not exist!" + if (el->num_values == 0) { + mod = lsqlite3_tprintf(ctx, + "DELETE FROM ldb_attribute_values " + "WHERE eid = '%lld' " + "AND norm_attr_name = '%q';", + eid, attr); + if (mod == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + } + + /* For each value of the specified attribute name... */ + for (j = 0; j < el->num_values; j++) { + struct ldb_val value; + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); + if (value.data == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + mod = lsqlite3_tprintf(ctx, + "DELETE FROM ldb_attribute_values " + "WHERE eid = '%lld' " + "AND norm_attr_name = '%q' " + "AND norm_attr_value = '%q';", + eid, attr, value.data); + + if (mod == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + } + + break; + } + } + + return LDB_SUCCESS; +} + +/* delete a record */ +static int lsql_delete(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + long long eid; + char *errmsg; + char *query; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + eid = lsqlite3_get_eid(lsqlite3, req->op.del.dn); + if (eid == -1) { + return LDB_ERR_OPERATIONS_ERROR; + } + + query = lsqlite3_tprintf(ctx, + /* Delete entry */ + "DELETE FROM ldb_entry WHERE eid = %lld; " + /* Delete attributes */ + "DELETE FROM ldb_attribute_values WHERE eid = %lld; ", + eid, eid); + if (query == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +/* rename a record */ +static int lsql_rename(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + char *new_dn, *new_cdn, *old_cdn; + char *errmsg; + char *query; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + /* create linearized and normalized dns */ + old_cdn = ldb_dn_alloc_casefold(ctx, req->op.rename.olddn); + new_cdn = ldb_dn_alloc_casefold(ctx, req->op.rename.newdn); + new_dn = ldb_dn_alloc_linearized(ctx, req->op.rename.newdn); + if (old_cdn == NULL || new_cdn == NULL || new_dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* build the SQL query */ + query = lsqlite3_tprintf(ctx, + "UPDATE ldb_entry SET dn = '%q', norm_dn = '%q' " + "WHERE norm_dn = '%q';", + new_dn, new_cdn, old_cdn); + if (query == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* execute */ + ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +static int lsql_start_trans(struct ldb_module * module) +{ + int ret; + char *errmsg; + struct lsqlite3_private *lsqlite3; + + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + if (lsqlite3->trans_count == 0) { + ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN IMMEDIATE;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3_start_trans: error: %s\n", errmsg); + free(errmsg); + } + return -1; + } + }; + + lsqlite3->trans_count++; + + return 0; +} + +static int lsql_end_trans(struct ldb_module *module) +{ + int ret; + char *errmsg; + struct lsqlite3_private *lsqlite3; + + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + if (lsqlite3->trans_count > 0) { + lsqlite3->trans_count--; + } else return -1; + + if (lsqlite3->trans_count == 0) { + ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3_end_trans: error: %s\n", errmsg); + free(errmsg); + } + return -1; + } + } + + return 0; +} + +static int lsql_del_trans(struct ldb_module *module) +{ + struct lsqlite3_private *lsqlite3; + + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + if (lsqlite3->trans_count > 0) { + lsqlite3->trans_count--; + } else return -1; + + if (lsqlite3->trans_count == 0) { + return lsqlite3_safe_rollback(lsqlite3->sqlite); + } + + return -1; +} + +static int destructor(struct lsqlite3_private *lsqlite3) +{ + if (lsqlite3->sqlite) { + sqlite3_close(lsqlite3->sqlite); + } + return 0; +} + +static void lsql_request_done(struct lsql_context *ctx, int error) +{ + struct ldb_context *ldb; + struct ldb_request *req; + struct ldb_reply *ares; + + ldb = ldb_module_get_ctx(ctx->module); + req = ctx->req; + + /* if we already returned an error just return */ + if (ldb_request_get_status(req) != LDB_SUCCESS) { + return; + } + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(ldb); + req->callback(req, NULL); + return; + } + ares->type = LDB_REPLY_DONE; + ares->error = error; + + req->callback(req, ares); +} + +static void lsql_timeout(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct lsql_context *ctx; + ctx = talloc_get_type(private_data, struct lsql_context); + + lsql_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED); +} + +static void lsql_callback(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct lsql_context *ctx; + int ret; + + ctx = talloc_get_type(private_data, struct lsql_context); + + switch (ctx->req->operation) { + case LDB_SEARCH: + ret = lsql_search(ctx); + break; + case LDB_ADD: + ret = lsql_add(ctx); + break; + case LDB_MODIFY: + ret = lsql_modify(ctx); + break; + case LDB_DELETE: + ret = lsql_delete(ctx); + break; + case LDB_RENAME: + ret = lsql_rename(ctx); + break; +/* TODO: + case LDB_EXTENDED: + ret = lsql_extended(ctx); + break; + */ + default: + /* no other op supported */ + ret = LDB_ERR_PROTOCOL_ERROR; + } + + if (!ctx->callback_failed) { + /* Once we are done, we do not need timeout events */ + talloc_free(ctx->timeout_event); + lsql_request_done(ctx, ret); + } +} + +static int lsql_handle_request(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct tevent_context *ev; + struct lsql_context *ac; + struct tevent_timer *te; + struct timeval tv; + + if (ldb_check_critical_controls(req->controls)) { + return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + + if (req->starttime == 0 || req->timeout == 0) { + ldb_set_errstring(ldb, "Invalid timeout settings"); + return LDB_ERR_TIME_LIMIT_EXCEEDED; + } + + ldb = ldb_module_get_ctx(module); + ev = ldb_get_event_context(ldb); + + ac = talloc_zero(req, struct lsql_context); + if (ac == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + + tv.tv_sec = 0; + tv.tv_usec = 0; + te = tevent_add_timer(ev, ac, tv, lsql_callback, ac); + if (NULL == te) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->timeout > 0) { + tv.tv_sec = req->starttime + req->timeout; + tv.tv_usec = 0; + ac->timeout_event = tevent_add_timer(ev, ac, tv, lsql_timeout, ac); + if (NULL == ac->timeout_event) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + return LDB_SUCCESS; +} + +/* + * Table of operations for the sqlite3 backend + */ +static const struct ldb_module_ops lsqlite3_ops = { + .name = "sqlite", + .search = lsql_handle_request, + .add = lsql_handle_request, + .modify = lsql_handle_request, + .del = lsql_handle_request, + .rename = lsql_handle_request, + .extended = lsql_handle_request, + .start_transaction = lsql_start_trans, + .end_transaction = lsql_end_trans, + .del_transaction = lsql_del_trans, +}; + +/* + * Static functions + */ + +static int initialize(struct lsqlite3_private *lsqlite3, + struct ldb_context *ldb, const char *url, + unsigned int flags) +{ + TALLOC_CTX *local_ctx; + long long queryInt; + int rollback = 0; + char *errmsg; + char *schema; + int ret; + + /* create a local ctx */ + local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_rename local context"); + if (local_ctx == NULL) { + return -1; + } + + schema = lsqlite3_tprintf(local_ctx, + + + "CREATE TABLE ldb_info AS " + " SELECT 'LDB' AS database_type," + " '1.0' AS version;" + + /* + * The entry table holds the information about an entry. + * This table is used to obtain the EID of the entry and to + * support scope=one and scope=base. The parent and child + * table is included in the entry table since all the other + * attributes are dependent on EID. + */ + "CREATE TABLE ldb_entry " + "(" + " eid INTEGER PRIMARY KEY AUTOINCREMENT," + " dn TEXT UNIQUE NOT NULL," + " norm_dn TEXT UNIQUE NOT NULL" + ");" + + + "CREATE TABLE ldb_object_classes" + "(" + " class_name TEXT PRIMARY KEY," + " parent_class_name TEXT," + " tree_key TEXT UNIQUE," + " max_child_num INTEGER DEFAULT 0" + ");" + + /* + * We keep a full listing of attribute/value pairs here + */ + "CREATE TABLE ldb_attribute_values" + "(" + " eid INTEGER REFERENCES ldb_entry," + " attr_name TEXT," + " norm_attr_name TEXT," + " attr_value TEXT," + " norm_attr_value TEXT " + ");" + + + /* + * Indexes + */ + "CREATE INDEX ldb_attribute_values_eid_idx " + " ON ldb_attribute_values (eid);" + + "CREATE INDEX ldb_attribute_values_name_value_idx " + " ON ldb_attribute_values (attr_name, norm_attr_value);" + + + + /* + * Triggers + */ + + "CREATE TRIGGER ldb_object_classes_insert_tr" + " AFTER INSERT" + " ON ldb_object_classes" + " FOR EACH ROW" + " BEGIN" + " UPDATE ldb_object_classes" + " SET tree_key = COALESCE(tree_key, " + " (" + " SELECT tree_key || " + " (SELECT base160(max_child_num + 1)" + " FROM ldb_object_classes" + " WHERE class_name = " + " new.parent_class_name)" + " FROM ldb_object_classes " + " WHERE class_name = new.parent_class_name " + " ));" + " UPDATE ldb_object_classes " + " SET max_child_num = max_child_num + 1" + " WHERE class_name = new.parent_class_name;" + " END;" + + /* + * Table initialization + */ + + "INSERT INTO ldb_object_classes " + " (class_name, tree_key) " + " VALUES " + " ('TOP', '0001');"); + + /* Skip protocol indicator of url */ + if (strncmp(url, "sqlite3://", 10) != 0) { + return SQLITE_MISUSE; + } + + /* Update pointer to just after the protocol indicator */ + url += 10; + + /* Try to open the (possibly empty/non-existent) database */ + if ((ret = sqlite3_open(url, &lsqlite3->sqlite)) != SQLITE_OK) { + return ret; + } + + /* In case this is a new database, enable auto_vacuum */ + ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA auto_vacuum = 1;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3 initializaion error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + + if (flags & LDB_FLG_NOSYNC) { + /* DANGEROUS */ + ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA synchronous = OFF;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3 initializaion error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + } + + /* */ + + /* Establish a busy timeout of 30 seconds */ + if ((ret = sqlite3_busy_timeout(lsqlite3->sqlite, + 30000)) != SQLITE_OK) { + return ret; + } + + /* Create a function, callable from sql, to increment a tree_key */ + if ((ret = + sqlite3_create_function(lsqlite3->sqlite,/* handle */ + "base160_next", /* function name */ + 1, /* number of args */ + SQLITE_ANY, /* preferred text type */ + NULL, /* user data */ + base160next_sql, /* called func */ + NULL, /* step func */ + NULL /* final func */ + )) != SQLITE_OK) { + return ret; + } + + /* Create a function, callable from sql, to convert int to base160 */ + if ((ret = + sqlite3_create_function(lsqlite3->sqlite,/* handle */ + "base160", /* function name */ + 1, /* number of args */ + SQLITE_ANY, /* preferred text type */ + NULL, /* user data */ + base160_sql, /* called func */ + NULL, /* step func */ + NULL /* final func */ + )) != SQLITE_OK) { + return ret; + } + + /* Create a function, callable from sql, to perform various comparisons */ + if ((ret = + sqlite3_create_function(lsqlite3->sqlite, /* handle */ + "ldap_compare", /* function name */ + 4, /* number of args */ + SQLITE_ANY, /* preferred text type */ + ldb , /* user data */ + lsqlite3_compare, /* called func */ + NULL, /* step func */ + NULL /* final func */ + )) != SQLITE_OK) { + return ret; + } + + /* Begin a transaction */ + ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN EXCLUSIVE;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3: initialization error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + rollback = 1; + + /* Determine if this is a new database. No tables means it is. */ + if (query_int(lsqlite3, + &queryInt, + "SELECT COUNT(*)\n" + " FROM sqlite_master\n" + " WHERE type = 'table';") != 0) { + goto failed; + } + + if (queryInt == 0) { + /* + * Create the database schema + */ + ret = sqlite3_exec(lsqlite3->sqlite, schema, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3 initializaion error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + } else { + /* + * Ensure that the database we opened is one of ours + */ + if (query_int(lsqlite3, + &queryInt, + "SELECT " + " (SELECT COUNT(*) = 2" + " FROM sqlite_master " + " WHERE type = 'table' " + " AND name IN " + " (" + " 'ldb_entry', " + " 'ldb_object_classes' " + " ) " + " ) " + " AND " + " (SELECT 1 " + " FROM ldb_info " + " WHERE database_type = 'LDB' " + " AND version = '1.0'" + " );") != 0 || + queryInt != 1) { + + /* It's not one that we created. See ya! */ + goto failed; + } + } + + /* Commit the transaction */ + ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3: iniialization error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + + return SQLITE_OK; + +failed: + if (rollback) lsqlite3_safe_rollback(lsqlite3->sqlite); + sqlite3_close(lsqlite3->sqlite); + return -1; +} + +/* + * connect to the database + */ +static int lsqlite3_connect(struct ldb_context *ldb, + const char *url, + unsigned int flags, + const char *options[], + struct ldb_module **_module) +{ + struct ldb_module *module; + struct lsqlite3_private *lsqlite3; + unsigned int i; + int ret; + + module = ldb_module_new(ldb, ldb, "ldb_sqlite3 backend", &lsqlite3_ops); + if (!module) return LDB_ERR_OPERATIONS_ERROR; + + lsqlite3 = talloc(module, struct lsqlite3_private); + if (!lsqlite3) { + goto failed; + } + + lsqlite3->sqlite = NULL; + lsqlite3->options = NULL; + lsqlite3->trans_count = 0; + + ret = initialize(lsqlite3, ldb, url, flags); + if (ret != SQLITE_OK) { + goto failed; + } + + talloc_set_destructor(lsqlite3, destructor); + + ldb_module_set_private(module, lsqlite3); + + if (options) { + /* + * take a copy of the options array, so we don't have to rely + * on the caller keeping it around (it might be dynamic) + */ + for (i=0;options[i];i++) ; + + lsqlite3->options = talloc_array(lsqlite3, char *, i+1); + if (!lsqlite3->options) { + goto failed; + } + + for (i=0;options[i];i++) { + + lsqlite3->options[i+1] = NULL; + lsqlite3->options[i] = + talloc_strdup(lsqlite3->options, options[i]); + if (!lsqlite3->options[i]) { + goto failed; + } + } + } + + *_module = module; + return LDB_SUCCESS; + +failed: + if (lsqlite3 && lsqlite3->sqlite != NULL) { + (void) sqlite3_close(lsqlite3->sqlite); + } + talloc_free(lsqlite3); + return LDB_ERR_OPERATIONS_ERROR; +} + +int ldb_sqlite3_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_backend("sqlite3", lsqlite3_connect, false); +} diff --git a/lib/ldb/ldb_sqlite3/schema b/lib/ldb/ldb_sqlite3/schema new file mode 100644 index 0000000..ab7c5cc --- /dev/null +++ b/lib/ldb/ldb_sqlite3/schema @@ -0,0 +1,328 @@ + -- ------------------------------------------------------ + + PRAGMA auto_vacuum=1; + + -- ------------------------------------------------------ + + BEGIN EXCLUSIVE; + + -- ------------------------------------------------------ + + CREATE TABLE ldb_info AS + SELECT 'LDB' AS database_type, + '1.0' AS version; + + /* + * Get the next USN value with: + * BEGIN EXCLUSIVE; + * UPDATE usn SET value = value + 1; + * SELECT value FROM usn; + * COMMIT; + */ + CREATE TABLE usn + ( + value INTEGER + ); + + CREATE TABLE ldb_object + ( + /* tree_key is auto-generated by the insert trigger */ + tree_key TEXT PRIMARY KEY, + + parent_tree_key TEXT, + dn TEXT, + + attr_name TEXT REFERENCES ldb_attributes, + attr_value TEXT, + + /* + * object_type can take on these values (to date): + * 1: object is a node of a DN + * 2: object is an attribute/value pair of its parent DN + */ + object_type INTEGER, + + /* + * if object_type is 1, the node can have children. + * this tracks the maximum previously assigned child + * number so we can generate a new unique tree key for + * a new child object. note that this is always incremented, + * so if children are deleted, this will not represent + * the _number_ of children. + */ + max_child_num INTEGER, + + /* + * Automatically maintained meta-data (a gift for metze) + */ + object_guid TEXT UNIQUE, + timestamp INTEGER, -- originating_time + invoke_id TEXT, -- GUID: originating_invocation_id + usn INTEGER, -- hyper: originating_usn + + /* do not allow duplicate name/value pairs */ + UNIQUE (parent_tree_key, attr_name, attr_value, object_type) + ); + + CREATE TABLE ldb_attributes + ( + attr_name TEXT PRIMARY KEY, + parent_tree_key TEXT, + + objectclass_p BOOLEAN DEFAULT 0, + + case_insensitive_p BOOLEAN DEFAULT 0, + wildcard_p BOOLEAN DEFAULT 0, + hidden_p BOOLEAN DEFAULT 0, + integer_p BOOLEAN DEFAULT 0, + + /* tree_key is auto-generated by the insert trigger */ + tree_key TEXT, -- null if not a object/sub class + -- level 1 if an objectclass + -- level 1-n if a subclass + max_child_num INTEGER + ); + + -- ------------------------------------------------------ + + CREATE INDEX ldb_object_dn_idx + ON ldb_object (dn); + + CREATE INDEX ldb_attributes_tree_key_ids + ON ldb_attributes (tree_key); + + -- ------------------------------------------------------ + + /* Gifts for metze. Automatically updated meta-data */ + CREATE TRIGGER ldb_object_insert_tr + AFTER INSERT + ON ldb_object + FOR EACH ROW + BEGIN + UPDATE ldb_object + SET max_child_num = max_child_num + 1 + WHERE tree_key = new.parent_tree_key; + UPDATE usn SET value = value + 1; + UPDATE ldb_object + SET tree_key = + (SELECT + new.tree_key || + base160(SELECT max_child_num + FROM ldb_object + WHERE tree_key = + new.parent_tree_key)); + max_child_num = 0, + object_guid = random_guid(), + timestamp = strftime('%s', 'now'), + usn = (SELECT value FROM usn); + WHERE tree_key = new.tree_key; + END; + + CREATE TRIGGER ldb_object_update_tr + AFTER UPDATE + ON ldb_object + FOR EACH ROW + BEGIN + UPDATE usn SET value = value + 1; + UPDATE ldb_object + SET timestamp = strftime('%s', 'now'), + usn = (SELECT value FROM usn); + WHERE tree_key = new.tree_key; + END; + + CREATE TRIGGER ldb_attributes_insert_tr + AFTER INSERT + ON ldb_attributes + FOR EACH ROW + BEGIN + UPDATE ldb_attributes + SET max_child_num = max_child_num + 1 + WHERE tree_key = new.parent_tree_key; + UPDATE ldb_attributes + SET tree_key = + (SELECT + new.tree_key || + base160(SELECT max_child_num + FROM ldb_attributes + WHERE tree_key = + new.parent_tree_key)); + max_child_num = 0 + WHERE tree_key = new.tree_key; + END; + + + -- ------------------------------------------------------ + + /* Initialize usn */ + INSERT INTO usn (value) VALUES (0); + + /* Create root object */ + INSERT INTO ldb_object + (tree_key, parent_tree_key, + dn, + object_type, max_child_num) + VALUES ('', NULL, + '', + 1, 0); + + /* We need an implicit "top" level object class */ + INSERT INTO ldb_attributes (attr_name, + parent_tree_key) + SELECT 'top', ''; + + -- ------------------------------------------------------ + + COMMIT; + + -- ------------------------------------------------------ + +/* + * dn: o=University of Michigan,c=US + * objectclass: organization + * objectclass: domainRelatedObject + */ +-- newDN +BEGIN; + +INSERT OR IGNORE INTO ldb_object + (parent_tree_key + dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('', + 'c=US', + 'c', 'US', 1, 0); + +INSERT INTO ldb_object + (parent_tree_key, + dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('0001', + 'o=University of Michigan,c=US', + 'o', 'University of Michigan', 1, 0); + +-- newObjectClass +INSERT OR IGNORE INTO ldb_attributes + (attr_name, parent_tree_key, objectclass_p) + VALUES + ('objectclass', '', 1); + +INSERT INTO ldb_object + (parent_tree_key, + dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', + NULL, + 'objectclass', 'organization', 2, 0); + +INSERT OR IGNORE INTO ldb_attributes + (attr_name, parent_tree_key, objectclass_p) + VALUES + ('objectclass', '', 1); + +INSERT INTO ldb_object + (parent_tree_key, + dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', + NULL, + 'objectclass', 'domainRelatedObject', 2, 0); + +COMMIT; + + +/* + * dn: o=University of Michigan,c=US + * l: Ann Arbor, Michigan + * st: Michigan + * o: University of Michigan + * o: UMICH + * seeAlso: + * telephonenumber: +1 313 764-1817 + */ +-- addAttrValuePair +BEGIN; + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'l', 'Ann Arbor, Michigan', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'st', 'Michigan', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'o', 'University of Michigan', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'o', 'UMICH', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'seeAlso', '', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'telephonenumber', '+1 313 764-1817', 2, 0); + +COMMIT; + +-- ---------------------------------------------------------------------- + +/* + * dn: @ATTRIBUTES + * uid: CASE_INSENSITIVE WILDCARD + * cn: CASE_INSENSITIVE + * ou: CASE_INSENSITIVE + * dn: CASE_INSENSITIVE + */ +-- newAttribute + +BEGIN; + +INSERT OR IGNORE INTO ldb_attributes + (attr_name, parent_tree_key, objectclass_p) + VALUES + ('uid', '', 0); + +UPDATE ldb_attributes + SET case_insensitive_p = 1, + wildcard_p = 1, + hidden_p = 0, + integer_p = 0 + WHERE attr_name = 'uid' + +UPDATE ldb_attributes + SET case_insensitive_p = 1, + wildcard_p = 0, + hidden_p = 0, + integer_p = 0 + WHERE attr_name = 'cn' + +UPDATE ldb_attributes + SET case_insensitive_p = 1, + wildcard_p = 0, + hidden_p = 0, + integer_p = 0 + WHERE attr_name = 'ou' + +UPDATE ldb_attributes + SET case_insensitive_p = 1, + wildcard_p = 0, + hidden_p = 0, + integer_p = 0 + WHERE attr_name = 'dn' + diff --git a/lib/ldb/ldb_sqlite3/trees.ps b/lib/ldb/ldb_sqlite3/trees.ps new file mode 100644 index 0000000..433a064 --- /dev/null +++ b/lib/ldb/ldb_sqlite3/trees.ps @@ -0,0 +1,1760 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software +%%Title: trees.dvi +%%Pages: 7 +%%PageOrder: Ascend +%%BoundingBox: 0 0 596 842 +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -f trees.dvi +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 2000.05.06:2055 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +TeXDict begin 39158280 55380996 1000 600 600 (trees.dvi) +@start +%DVIPSBitmapFont: Fa cmr10 10 6 +/Fa 6 55 df<146014E0EB01C0EB0380EB0700130E131E5B5BA25B485AA2485AA212075B +120F90C7FCA25A121EA2123EA35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203A2 +6C7EA26C7E1378A27F7F130E7FEB0380EB01C0EB00E01460135278BD20>40 +D<12C07E12707E7E7E120F6C7E6C7EA26C7E6C7EA21378A2137C133C133E131EA2131F7F +A21480A3EB07C0A6EB03E0B2EB07C0A6EB0F80A31400A25B131EA2133E133C137C1378A2 +5BA2485A485AA2485A48C7FC120E5A5A5A5A5A13527CBD20>I<15301578B3A6007FB812 +F8B912FCA26C17F8C80078C8FCB3A6153036367BAF41>43 D<EB03F8EB1FFF90387E0FC0 +9038F803E03901E000F0484813780007147C48487FA248C77EA2481580A3007EEC0FC0A6 +00FE15E0B3007E15C0A4007F141F6C1580A36C15006D5B000F143EA26C6C5B6C6C5B6C6C +485A6C6C485A90387E0FC0D91FFFC7FCEB03F8233A7DB72A>48 D<EB01C013031307131F +13FFB5FCA2131F1200B3B3A8497E007FB512F0A31C3879B72A>I<EC3FC0903801FFF001 +0713FC90380FE03E90383F800790387E001F49EB3F804848137F485AA2485A000FEC3F00 +49131E001F91C7FCA2485AA3127F90C9FCEB01FC903807FF8039FF1E07E090383801F049 +6C7E01607F01E0137E497FA249148016C0151FA290C713E0A57EA56C7E16C0A2121FED3F +807F000F15006C6C5B15FE6C6C5B6C6C485A3900FE07F090383FFFC06D90C7FCEB03FC23 +3A7DB72A>54 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fb cmr7 7 3 +/Fb 3 55 df<EB3F803801FFF03803E0F83807803C48487E001E7F003E1480A2003C1307 +007C14C0A400FC14E0AE007C14C0A36CEB0F80A36CEB1F006C131E6C6C5A3803E0F86CB4 +5A38003F801B277EA521>48 D<13381378EA01F8121F12FE12E01200B3AB487EB512F8A2 +15267BA521>I<EB0FE0EB3FF8EBF81C3801E0063803C01F48485AEA0F005A121E003E13 +1E91C7FC5AA21304EB3FC038FCFFF038FDC078EB003CB4133E48131E141FA2481480A412 +7CA4003C1400123E001E131E143E6C133C6C6C5A3803C1F03801FFC06C6CC7FC19277DA5 +21>54 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fc cmmi10 10 1 +/Fc 1 69 df<0103B7FC4916E018F8903B0007F80007FE4BEB00FFF03F80020FED1FC018 +0F4B15E0F007F0021F1503A24B15F81801143F19FC5DA2147FA292C8FCA25C18035CA213 +0119F84A1507A2130319F04A150FA2010717E0181F4A16C0A2010FEE3F80A24AED7F0018 +7E011F16FE4D5A4A5D4D5A013F4B5A4D5A4A4A5A057FC7FC017F15FEEE03FC91C7EA0FF0 +49EC7FC0B8C8FC16FC16C03E397DB845>68 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fd ectt1000 10 73 +/Fd 73 126 df<D807801307D81FE0EB0F80151F487E486C133F1600007C5CD8FCFC137E +EAF87C15FE5D14015DA21403D8FCFC5BEA7CF8007F13075D383FF00FD81FE05BA2380780 +1FC75B143F92C7FCA25C147E14FE5CA213015CA213035C13075CA2130F5C131FEC800FED +3FC0013FEB7FE0140049EBFFF0017E13F9A2D9FE0113F801FC13F0A2120113F8120313F0 +15F90007010013F05B000F14FF49EB7FE0A20007EC3FC06C48EB0F0025417DB92C>37 +D<EA0F80EA1FE0EA3FF0127F13F8A213FCA2123F121F120FEA007CA313FC13F8A2120113 +F01203EA07E0A2EA0FC0EA3F80127FEAFF005A12F812700E1D71B22C>39 +D<143814FC13011303EB07F8EB0FF0EB1FC0EB3F80EB7F0013FE485A485A5B12075B120F +5B485AA2123F90C7FCA25A127EA312FE5AAC7E127EA3127F7EA27F121FA26C7E7F12077F +12037F6C7E6C7E137FEB3F80EB1FC0EB0FF0EB07F8EB03FC130113001438164272B92C> +I<127012FC7E7E6C7E6C7EEA0FE06C7E6C7E6C7E6C7E137F7F1480131F14C0130FEB07E0 +A214F01303A214F81301A314FC1300AC130114F8A3130314F0A2130714E0A2EB0FC0131F +1480133F14005B13FE485A485A485A485AEA3FC0485A48C7FC5A5A1270164279B92C>I< +EB0380497EA60020140800F8143E00FE14FE00FF13C1EBC7C7EBE7CF003FB512F8000F14 +E0000314806C140038007FFCA248B5FC481480000F14E0003F14F839FFE7CFFEEBC7C7EB +07C100FE13C000F8143E0020140800001400A66D5A1F247AAA2C>I<147014F8AF003FB6 +12E0B712F8A4C700F8C7FCB0147025267DAB2C>I<EA0F80EA1FE0EA3FF0EA7FF8A213FC +A3123F121F120F120013F8A21201EA03F01207EA1FE0EA7FC0EAFF80130012FC12700E17 +718A2C>I<121FEA3F80EA7FC0EAFFE0A5EA7FC0EA3F80EA1F000B0B708A2C>46 +D<1507ED0F80A2151F16005D153E157E157CA215FC5D14015D14035D14075D140F5D141F +92C7FC5C143EA2147E147C14FC5C13015C13035C13075C130F5C131F91C8FC5B133EA213 +7E137C13FC5B12015B12035B12075B120F5B121F90C9FCA25A123E127E127C12FC5AA212 +7021417BB92C>I<EB03F8EB0FFE90383FFF80497F90B57E3901FE0FF03903F803F84848 +6C7EEBE0004848137EA248487FA248C7EA1F80A2003E140F007E15C0A3007C140700FC15 +E0AC6C140F007E15C0A46CEC1F80A36C6CEB3F00A26C6C137E6D13FE00075CEBF0016C6C +485A3901FE0FF06CB55A6D5B6D5BD90FFEC7FCEB03F823357CB32C>I<1307497EA2131F +A2133F137F13FF5A1207127FB5FC13DF139FEA7C1F1200B3AE007FB512E0B612F0A36C14 +E01C3477B32C>I<EB0FF890387FFF8048B512E00007804814FC391FF80FFE393FE001FF +903880007F48C7EA3F80007E141F00FE15C0150F6C15E01507A3127E123CC8FCA2150F16 +C0151F1680153F16005D15FE4A5A14034A5A4A5A4A5A4A5AECFF804948C7FC495A495A49 +5AEB3FE0EB7F8049C8FC485A4848EB03C04848EB07E0EA1FE0485A48B6FCB7FCA36C15C0 +23347CB32C>I<000FB512FE4880A35D0180C8FCADEB83FE90389FFF8090B512E015F881 +9038FE03FE9038F000FF01C07F49EB3F8090C7121F6C15C0C8120FA2ED07E0A4123C127E +B4FC150F16C0A248141F007EEC3F80007FEC7F006C6C5B6D485A391FF80FFC6CB55A6C5C +000114C06C6C90C7FCEB0FF823347CB22C>53 D<EC3FC0903801FFF801077F011F7F497F +90387FE07F9039FF003F804848137FEA03F8485A5B000FEC3F004848131E4990C7FC123F +90C9FCA25A127EEB03FE90381FFF80D8FC7F13E000FDB57EB67E9038FE07FC9038F001FE +9038C0007F49EB3F8090C7121F16C048140F16E01507A3127EA47E150F6D14C0001F141F +6D1480000F143F6DEB7F003907F801FE3903FE07FC6CB55A6C5C6D5B011F1380D907FCC7 +FC23357CB32C>I<1278B712C016E0A316C000FCC7EA3F80ED7F0015FE00785CC712014A +5A4A5A5D140F5D4A5A143F92C7FC5C147E14FE5C13015CA2495AA213075CA3495AA4495A +A5133F91C8FCAA131E23357CB32C>I<EA0F80EA1FC0EA3FE0EA7FF0A5EA3FE0EA1FC0EA +0F80C7FCAEEA0F80EA1FE0EA3FF0EA7FF8A213FCA3123F121F120F120013F8A21201EA03 +F01207EA1FE0EA7FC0EAFF80130012FC12700E3071A32C>59 D<1502ED0F80151F157F15 +FF913803FE00EC0FFCEC1FF0EC7FE0ECFF80D903FEC7FC495AEB1FF0495AEBFF80000390 +C8FCEA07FCEA1FF8EA3FE0EAFF8090C9FCA27FEA3FE0EA1FF8EA07FC6CB4FCC67FEB3FE0 +6D7EEB07FC6D7E903800FF80EC7FE0EC1FF0EC0FFCEC03FE913800FF80157F151F150FED +0200212A7BAD2C>I<007FB612F0B712F8A36C15F0CAFCA8007FB612F0B712F8A36C15F0 +25127DA12C>I<122012F87EB4FC7FEA3FE0EA1FF8EA07FC6CB4FCC67FEB3FE06D7EEB07 +FC6D7E903800FF80EC7FE0EC1FF0EC0FFCEC03FE913800FF80157FA215FF913803FE00EC +0FFCEC1FF0EC7FE0ECFF80D903FEC7FC495AEB1FF0495AEBFF80000390C8FCEA07FCEA1F +F8EA3FE0EAFF8090C9FC12FC5A1220212A7BAD2C>I<14FE497EA4497FA214EFA2130781 +A214C7A2010F7FA314C390381F83F0A590383F01F8A490387E00FCA549137E90B512FEA3 +4880A29038F8003FA34848EB1F80A4000715C049130FD87FFEEBFFFC6D5AB514FE6C15FC +497E27347EB32C>65 D<007FB512E015F8B612FE6C8016C03903F0003FED0FE0ED07F015 +03A2ED01F8A6ED03F0A21507ED0FE0ED1FC0EDFF8090B612005D5D15FF16C09039F0001F +E0ED07F0ED03F81501ED00FCA216FE167EA616FE16FC1501ED03F8150FED3FF0007FB612 +E016C0B712806CECFE0015F027337FB22C>I<02FF13700107EBE0F84913F9013F13FD49 +13FFEBFF813901FE007F4848131FD807F0130F1507485A491303485A150148C7FCA25A00 +7EEC00F01600A212FE5AAB7E127EA3007F15F06CEC01F8A26C7EA26C6C13036D14F06C6C +130716E0D803FC131F6C6CEB3FC03A00FF81FF806DB512006D5B010F5B6D13F001001380 +25357DB32C>I<007FB5FCB612C015F0816C803907E003FEEC00FFED7F80153FED1FC0ED +0FE0A2150716F0150316F81501A4ED00FCACED01F8A3150316F0A2150716E0150FED1FC0 +153FED7F80EDFF00EC03FE007FB55AB65A5D15C06C91C7FC26337EB22C>I<007FB612F0 +B712F8A37E3903F00001A7ED00F01600A4EC01E04A7EA490B5FCA5EBF003A46E5A91C8FC +A5163C167EA8007FB612FEB7FCA36C15FC27337EB22C>I<007FB612F8B712FCA37ED803 +F0C7FCA716781600A515F04A7EA490B5FCA5EBF001A46E5A92C7FCAD387FFFE0B5FC805C +7E26337EB22C>I<903901FC038090390FFF87C04913EF017F13FF90B6FC4813073803FC +01497E4848137F4848133F49131F121F5B003F140F90C7FCA2127EED078092C7FCA212FE +5AA8913803FFF84A13FCA27E007E6D13F89138000FC0A36C141FA27F121F6D133F120F6D +137F6C7E6C6C13FF6D5A3801FF076C90B5FC6D13EF011F13CF6DEB0780D901FCC7FC2635 +7DB32C>I<D87FFEEBFFFCB54813FEA36C486C13FCD807E0EB0FC0B190B6FCA59038E000 +0FB3D87FFEEBFFFCB54813FEA36C486C13FC27337EB22C>I<007FB512F8B612FCA36C14 +F839000FC000B3B3A5007FB512F8B612FCA36C14F81E3379B22C>I<D87FFCEB7FF8486C +EBFFFCA36C48EB7FF8D807C0EB1F80153FED7F00157E5D4A5A14034A5A5D4A5A4A5A143F +4AC7FC147E5CEBC1F813C3EBC7FCA2EBCFFEEBDFBEEBFFBF141F01FE7F496C7E13F86E7E +EBF00301E07FEBC001816E7EA2157E153E153F811680ED0FC0A2ED07E0D87FFCEB1FFC48 +6CEB3FFEA36C48EB1FFC27337EB22C>75 D<387FFFE0B57EA36C5BD803F0C8FCB3AE16F0 +ED01F8A8007FB6FCB7FCA36C15F025337DB22C>I<D87FE0EB0FFC486CEB1FFEA26D133F +007F15FC000F15E001BC137BA4019E13F3A3EB9F01A2018F13E3A21483A2018713C314C7 +A201831383A214EFA201811303A214FFEB80FEA3147C14381400ACD87FF0EB1FFC486CEB +3FFEA36C48EB1FFC27337EB22C>I<D87FF0EB7FFC486CEBFFFEA27F007FEC7FFCD807FE +EB07C013DEA213DF13CFA2148013C714C0A213C314E0A213C114F0A213C014F8A2147CA3 +143EA2141E141FA2140F1587A2140715C7A2140315E71401A215F71400A215FFD87FFC13 +7F487E153FA26C48EB1F8027337EB22C>I<EB7FFF0003B512E0000F14F848804880EBE0 +03EB800048C7127FA2007E80A300FE158048141FB3A86C143FA2007E1500A3007F5CA26C +6C13FEEBF00790B5FC6C5C6C5C000314E0C66C90C7FC21357BB32C>I<007FB512C0B612 +F88115FF6C15802603F00013C0153FED0FE0ED07F0A2150316F81501A6150316F01507A2 +ED0FE0ED3FC015FF90B61280160015FC5D15C001F0C8FCB0387FFF80B57EA36C5B25337E +B22C>I<EB7FFF0003B512E0000F14F848804880EBF007EB800048C7127FA2007E80A300 +FE158048141FB3A7EB01F0EB03F800FE143F267E01FC1300A2EB00FE007F5C147FD83F80 +13FEEBF03F90B5FC6C5C6C5C000314E0C67E90380007F0A26E7EA26E7EA26E7EA2157FA2 +153E21407BB32C>I<387FFFFCB67E15E015F86C803907E007FE1401EC007F6F7E151FA2 +6F7EA64B5AA2153F4BC7FCEC01FE140790B55A5D15E081819038E007FCEC01FE1400157F +81A8160FEE1F80A5D87FFEEB1FBFB5ECFF00815E6C486D5AC8EA01F029347EB22C>I<90 +381FF80790B5EA0F804814CF000714FF5A381FF01F383FC003497E48C7FC007E147F00FE +143F5A151FA46CEC0F00007E91C7FC127F7FEA3FE0EA1FFCEBFFC06C13FC0003EBFFC06C +14F06C6C7F01077F9038007FFEEC07FF02001380153FED1FC0A2ED0FE0A20078140712FC +A56CEC0FC0A26CEC1F806D133F01E0EB7F009038FE01FF90B55A5D00F914F0D8F83F13C0 +D8700790C7FC23357CB32C>I<007FB612FCB712FEA43AFC007E007EA70078153CC71400 +B3AF90383FFFFCA2497F6D5BA227337EB22C>I<3B7FFF803FFFC0B56C4813E0A36C496C +13C03B03F00001F800B3AF6D130300015DA26D130700005D6D130F017F495A6D6C485AEC +E0FF6DB5C7FC6D5B010313F86D5B9038003F802B3480B22C>I<D87FFCEB7FFC486CEBFF +FEA36C48EB7FFCD80FC0EB07E06D130F000715C0A36D131F00031580A36D133F00011500 +A36D5B0000147EA4017E5BA46D485AA490381F83F0A4010F5B14C7A301075BA214EFA201 +035BA214FFA26D90C7FCA46D5A27347EB22C>I<D87FF0EB07FF486C491380A36C486D13 +00001FC8127CA46C6C5CA76C6C495AA4143E147FA33A03E0FF83E0A214F7A201E113C3A3 +000101E35BA201F113C701F313E7A314C1A200005DA201F713F71480A301FF13FF017F91 +C7FC4A7EA4013E133E29347FB22C>I<3A3FFF03FFE0484913F0148714076C6D13E03A01 +F800FE007F0000495A13FE017E5BEB7F03013F5B1487011F5B14CF010F5B14FF6D5BA26D +90C7FCA26D5AA26D5AA2497EA2497EA2497F81EB0FCF81EB1FC7EC87F0EB3F83EC03F8EB +7F01017E7FEBFE00497F0001147E49137F000380491480151FD87FFEEBFFFC6D5AB514FE +6C15FC497E27337EB22C>I<D87FFCEB7FFC486CEBFFFEA36C48EB7FFCD807F0EB0FC015 +1F000315806D133F12016DEB7F0012006D137E017E13FE017F5BEB3F01EC81F8131FEC83 +F0EB0FC314C7903807E7E0A201035B14EF6DB45AA292C7FC7F5C147EB0903807FFE0497F +A36D5B27337EB22C>I<387FFFFCB512FEA314FC00FCC7FCB3B3B3B512FC14FEA36C13FC +17416FB92C>91 D<127012F8A27E127C127E123E123F7EA27F120F7F12077F12037F1201 +7F12007F137C137E133EA2133F7F80130F80130780130380130180130080147C147E143E +A2143F8081140F81140781140381140181140081157CA2157E153E153F811680150FA2ED +070021417BB92C>I<387FFFFCB512FEA37EC7127EB3B3B3387FFFFEB5FCA36C13FC1741 +7DB92C>I<EB07C0EB1FF0EB7FFC48B5FC000714C0001F14F0397FFC7FFC39FFF01FFEEB +C007EB0001007CEB007C003014181F0C7AAE2C>I<007FB6FCB71280A46C150021067B7D +2C>I<1338137CEA01FC1203EA07F813F0EA0FC0EA1F80A2EA3F00123E127E127CA212FC +5AA3EAFFC013E013F013F8A2127FA2123F13F0EA1FE0EA07C00E1D72B82C>I<3801FFF0 +000713FE001F6D7E15E048809038C01FF81407EC01FC381F80000006C77EC8127EA3ECFF +FE131F90B5FC1203120F48EB807E383FF800EA7FC090C7FC12FE5AA47E007F14FEEB8003 +383FE01F6CB612FC6C15FE6C14BF0001EBFE1F3A003FF007FC27247CA32C>I<EA7FF048 +7EA3127F1201AAEC1FE0ECFFF801FB13FE90B6FC16809138F07FC09138801FE091380007 +F049EB03F85BED01FC491300A216FE167EA816FE6D14FCA2ED01F86D13036DEB07F0150F +9138801FE09138E07FC091B51280160001FB5B01F813F83900F03FC027337FB22C>I<90 +3803FFE0011F13F8017F13FE48B5FC48804848C6FCEA0FF0485A49137E4848131890C9FC +5A127EA25AA8127EA2127F6C140F6DEB1F806C7E6D133F6C6CEB7F003907FE03FF6CB55A +6C5C6C6C5B011F13E0010390C7FC21247AA32C>I<EC0FFE4A7EA380EC003FAAEB07F8EB +3FFE90B512BF4814FF5A3807FC0F380FF00348487E497E48487F90C7FC007E80A212FE5A +A87E007E5CA2007F5C6C7E5C6C6C5A380FF0073807FC1F6CB612FC6CECBFFE6C143FEB3F +FC90390FF01FFC27337DB22C>I<EB03FE90381FFFC0017F13F048B57E48803907FE03FE +390FF800FFD81FE0EB3F805B4848EB1FC090C7120F5A007E15E015075AB7FCA416C000FC +C9FC7E127EA2127F6CEC03C06DEB07E06C7ED80FF0130F6C6CEB3FC001FF13FF000190B5 +12806C1500013F13FC010F13F00101138023247CA32C>I<ED03F8903907F80FFC90391F +FE3FFE017FB6FC48B7FC48ECFE7F9038FC0FF82607F003133E3A0FE001FC1CD9C0001300 +001F8049137EA66D13FE000F5CEBE0016C6C485A3903FC0FF048B5FC5D481480D99FFEC7 +FCEB87F80180C8FCA37F6C7E90B512F06C14FE48ECFF804815E04815F03A3FC0001FF848 +C7EA03FC007E1400007C157C00FC157E48153EA46C157E007E15FCD87F801303D83FE0EB +0FF8D81FFCEB7FF06CB612E0000315806C1500D8003F13F8010713C028387EA42C>103 +D<EA7FF0487EA3127F1201AAEC1FE0EC7FFC9038F9FFFE01FB7F90B6FC9138F03F80ECC0 +1F02807FEC000F5B5BA25BB3267FFFE0B5FCB500F11480A36C01E0140029337FB22C>I< +1307EB1FC0A2497EA36D5AA20107C7FC90C8FCA7387FFFC080B5FC7EA2EA0007B3A8007F +B512FCB612FEA36C14FC1F3479B32C>I<EA7FE0487EA3127F1201AA91381FFFF04A13F8 +A36E13F0913800FE004A5A4A5A4A5A4A5A4A5A4A5A4AC7FC14FEEBF1FC13F3EBF7FE90B5 +FCA2EC9F80EC0FC001FE7FEBFC07496C7E496C7E811400157E811680151F3A7FFFC0FFFC +B500E113FEA36C01C013FC27337EB22C>107 D<387FFFE0B57EA37EEA0003B3B3A5007F +B61280B712C0A36C158022337BB22C>I<3A7F83F007E09039CFFC1FF83AFFDFFE3FFCD8 +7FFF13FF91B57E3A07FE1FFC3E01FCEBF83F496C487E01F013E001E013C0A301C01380B3 +3B7FFC3FF87FF0027F13FFD8FFFE6D13F8D87FFC4913F0023F137F2D2481A32C>I<397F +F01FE039FFF87FFC9038F9FFFE01FB7F6CB6FC00019038F03F80ECC01F02807FEC000F5B +5BA25BB3267FFFE0B5FCB500F11480A36C01E0140029247FA32C>I<EB07FCEB1FFF017F +13C048B512F048803907FC07FC390FF001FE48486C7E0180133F003F158090C7121F007E +EC0FC0A348EC07E0A76C140F007E15C0A2007F141F6C15806D133F6C6CEB7F006D5B6C6C +485A3907FC07FC6CB55A6C5C6C6C13C0011F90C7FCEB07FC23247CA32C>I<397FF01FE0 +39FFF8FFF801FB13FE90B6FC6C158000019038F07FC09138801FE091380007F049EB03F8 +5BED01FC491300A216FE167EA816FE6D14FCA2ED01F86D13036DEB07F0150F9138801FE0 +9138E07FC091B51280160001FB5B01F813F8EC3FC091C8FCAD387FFFE0B57EA36C5B2736 +7FA32C>I<903903FC078090391FFF0FC0017F13CF48B512EF4814FF3807FE07380FF001 +48487E49137F4848133F90C7FC48141F127E150F5AA87E007E141FA26C143F7F6C6C137F +6D13FF380FF0033807FC0F6CB6FC6C14EF6C6C138F6D130FEB07F890C7FCAD0203B5FC4A +1480A36E140029367DA32C>I<D87FFEEB3FC0B53801FFF0020713F8021F13FC6C5B3900 +3F7FE1ECFF019138FC00F84A13704A13005CA25C5CA391C8FCAF007FB512E0B67EA36C5C +26247EA32C>I<90387FF8700003B512F8120F5A5A387FC00F387E00034813015AA36CEB +00F0007F140013F0383FFFC06C13FE6CEBFF80000314E0C66C13F8010113FCEB0007EC00 +FE0078147F00FC143F151F7EA26C143F6D133E6D13FE9038F007FC90B5FC15F815E000F8 +148039701FFC0020247AA32C>I<131E133FA9007FB6FCB71280A36C1500D8003FC8FCB1 +ED03C0ED07E0A5EC800F011FEB1FC0ECE07F6DB51280160001035B6D13F89038003FE023 +2E7EAD2C>I<3A7FF003FF80486C487FA3007F7F0001EB000FB3A3151FA2153F6D137F39 +00FE03FF90B7FC6D15807F6D13CF902603FE07130029247FA32C>I<3A3FFF03FFF04801 +8713F8A36C010313F03A00FC007E005D90387E01F8013F5BEB1F83EC87E090380FCFC090 +3807EF80EB03FF6D90C7FC5C6D5A147C14FE130180903803EF80903807CFC0EB0FC7EC83 +E090381F01F0013F7FEB7E00017C137C49137E0001803A7FFF01FFFC1483B514FE6C15FC +140127247EA32C>120 D<3A7FFF01FFFCB5008113FE148314816C010113FC3A03E0000F +806C7E151F6D140012005D6D133E137C017E137E013E137CA2013F13FC6D5BA2EB0F815D +A2EB07C1ECC3E0A2EB03E3ECE7C0130114F75DEB00FFA292C7FC80A2143EA2147E147CA2 +14FC5CA2EA0C01003F5BEA7F83EB87E0EA7E0F495A387FFF806C90C8FC6C5A6C5AEA07E0 +27367EA32C>I<15FF02071380141F147F91B512004913C04AC7FCEB03F85CB31307EB1F +E013FF007F5BB55A49C8FC6D7E6C7FC67F131FEB07F01303B380EB01FEECFFC06D13FF6E +1380141F14070200130021417BB92C>123 D<127812FCB3B3B3A9127806416DB92C>I<EA +7FC0EAFFF813FE6D7E6C7FC67F131FEB07F01303B380EB01FEECFFC06D13FF6E1380141F +147F91B512004913C04AC7FCEB03F85CB31307EB1FE013FF007F5BB55A49C8FC13F8EA7F +C021417BB92C>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fe ecti1000 10 33 +/Fe 33 122 df<EE3FFC4BB51280923907E007C092391F8001E0DB3F0013F0037E13034B +1307A24A5A18E04A48EB038094C7FCA314075DA4140F5DA3010FB7FCA25F903A001F8000 +7EA217FE023F5C92C7FCA216015F5C147E16035FA214FE4A13075FA30101140F5F4AECC1 +C0A2161F1783010316805CA2EF870013074A5CEE0F8EEE079EEE03FC010FEC00F04A91C7 +FCA35C131FA2001C90CAFC127E5BEAFE3E133C137CEAF878EA78F0EA3FE0EA0F80344C82 +BA2F>28 D<150C151C153815F0EC01E0EC03C0EC0780EC0F00141E5C147C5C5C495A1303 +495A5C130F49C7FCA2133EA25BA25BA2485AA212035B12075BA2120F5BA2121FA290C8FC +A25AA2123EA2127EA2127CA412FC5AAD1278A57EA3121C121EA2120E7EA26C7E6C7EA212 +001E5274BD22>40 D<140C140E80EC0380A2EC01C015E0A2140015F0A21578A4157C153C +AB157CA715FCA215F8A21401A215F0A21403A215E0A21407A215C0140F1580A2141F1500 +A2143EA25CA25CA2495AA2495A5C1307495A91C7FC5B133E133C5B5B485A12035B48C8FC +120E5A12785A12C01E527FBD22>I<4B7EA3150393C8FCA35D1506A3150E150CA3151C15 +18A315381530A31570B912E0A2C80060C8FC15E05DA314015DA3140392C9FCA35C1406A3 +140E140CA3141C1418A2333275AD40>43 D<EA03C0EA07F0120F121F13F8A313F0EA07B0 +EA003013701360A213E013C01201EA038013005A120E5A5A5A5A5A0D197A8819>I<120E +EA3F80127F12FFA31300127E123C0909778819>46 D<0103B612FEEFFFC018F0903B0007 +F8000FF84BEB03FCEF00FE020F157FF03F804B141F19C0021F150F19E05D1807143F19F0 +5DA2147FA292C8FCA25C180F5CA2130119E04A151FA2130319C04A153FA201071780187F +4A1600A2010F16FEA24A4A5A60011F15034D5A4A5D4D5A013F4B5A173F4A4AC7FC17FC01 +7FEC03F84C5A91C7EA1FC04949B45A007F90B548C8FCB712F016803C397CB83F>68 +D<0103B512F8A390390007F8005DA2140FA25DA2141FA25DA2143FA25DA2147FA292C7FC +A25CA25CA21301A25CA21303A25CA21307A25CA2130FA25CA2131FA25CA2133FA25CA213 +7FA291C8FC497EB6FCA25C25397CB820>73 D<0107B512FCA25E9026000FF8C7FC5D5D14 +1FA25DA2143FA25DA2147FA292C8FCA25CA25CA21301A25CA21303A25CA21307A25CA213 +0F170C4A141CA2011F153C17384A1478A2013F157017F04A14E01601017F140317C091C7 +1207160F49EC1F80163F4914FF000102071300B8FCA25E2E397BB834>76 +D<ED03FE92383FFFC09238FC07F0913903E001F891390F80007C023FC77E027E8002F815 +804948EC0FC0EB07E04948EC07E0131F4A15F049C81203137E01FE16F8485AA2485AA248 +5AA2120F5B001F16075B123FA34848ED0FF0A448C9EA1FE0A3EF3FC0A21880177F18005F +5F16015F6C4B5A4C5AA24C5A6C4B5A6D4A5A001F93C7FC6D147E000F5D6C6CEB03F06C6C +495A6C6CEB0F806C6C013FC8FC90383F01FC90381FFFE0010190C9FC353D74BA40>79 +D<ED03FE92383FFFC09238FC07F0913903E001F891390FC0007C023FC77E027E804A1580 +D901F0EC0FC013074948EC07E0495A4A15F049C8FC49150301FE16F8485AA2485AA2485A +A2120F491507121FA2485AA34848ED0FF0A448C9EA1FE0A3EF3FC0A21880177F4817005F +5F16015F007F4B5A5F91380F800791393FE00FE06C903970601FC0902680E0305B261F81 +C049C7FC913880187ED80FC35C3A07E30019F00003EC1FE0D801FB14806CB46C48C8FC90 +263F81FC13186DB45A01010138133890C7003C1330177017F05FED3E03ED3F07EEFFC05F +A294C7FC5E6F5A6F5AED07E0354B74BA40>81 D<92383FC00E913901FFF01C020713FC91 +391FC07E3C91393F001F7C027CEB0FF84A130749481303495A4948EB01F0A2495AA2011F +15E091C7FCA34915C0A36E90C7FCA2806D7E14FCECFF806D13F015FE6D6D7E6D14E00100 +80023F7F14079138007FFC150F15031501A21500A2167C120EA3001E15FC5EA3003E4A5A +A24B5AA2007F4A5A4B5A6D49C7FC6D133ED8F9F013FC39F8FC03F839F07FFFE0D8E01F13 +8026C003FCC8FC2F3D7ABA2F>83 D<0007B812E0A25AD9F800EB001F01C049EB07C0485A +D900011403121E001C5C003C17801403123800785C00701607140700F01700485CA2140F +C792C7FC5DA2141FA25DA2143FA25DA2147FA292C9FCA25CA25CA21301A25CA21303A25C +A21307A25CA2130FA25CEB3FF0007FB512F8B6FCA2333971B83B>I<14F8EB07FE90381F +871C90383E03FE137CEBF801120148486C5A485A120FEBC001001F5CA2EA3F801403007F +5C1300A21407485C5AA2140F5D48ECC1C0A2141F15831680143F1587007C017F1300ECFF +076C485B9038038F8E391F0F079E3907FE03FC3901F000F0222677A42A>97 +D<133FEA1FFFA3C67E137EA313FE5BA312015BA312035BA31207EBE0F8EBE7FE9038EF0F +80390FFC07C013F89038F003E013E0D81FC013F0A21380A2123F1300A214075A127EA214 +0F12FE4814E0A2141F15C05AEC3F80A215005C147E5C387801F8007C5B383C03E0383E07 +C0381E1F80D80FFEC7FCEA01F01C3B77B926>I<147F903803FFC090380FC1E090381F00 +70017E13784913383901F801F83803F003120713E0120FD81FC013F091C7FC485AA2127F +90C8FCA35A5AA45AA3153015381578007C14F0007EEB01E0003EEB03C0EC0F806CEB3E00 +380F81F83803FFE0C690C7FC1D2677A426>I<ED01F815FFA3150316F0A21507A216E0A2 +150FA216C0A2151FA21680A2153FA202F81300EB07FE90381F877F90383E03FF017C5BEB +F80112013803F00048485B120FEBC001121F5DEA3F801403127F01005BA214075A485CA2 +140FA248ECC1C0A2141F15C3ED8380143F1587007C017F1300ECFF076C485B9038038F8E +391F0F079E3907FE03FC3901F000F0253B77B92A>I<147F903803FFC090380FC1E09038 +3F00F0017E13785B485A485A485A120F4913F8001F14F0383F8001EC07E0EC1F80397F81 +FF00EBFFF8148090C8FC5A5AA55AA21530007C14381578007E14F0003EEB01E0EC03C06C +EB0F806CEB3E00380781F83803FFE0C690C7FC1D2677A426>I<ED07C0ED1FF0ED3E38ED +7C3CEDF8FC15F9140115F1020313F8EDF0F0160014075DA4140F5DA4141F5D010FB512C0 +5B16809039003F800092C7FCA45C147EA414FE5CA413015CA413035CA413075CA4130F5C +A3131F5CA391C8FC5B121CEA7E3EA2EAFE3C137C1378EAF8F01278EA3FC0EA0F80264C82 +BA19>I<EC07C0EC3FF09138FC38E0903901F01FF0EB03E0903807C00FEB0F80011F1307 +D93F0013E05B017E130F13FE4914C01201151F1203491480A2153F1207491400A25DA249 +137EA215FEA25D00031301140314076C6C485A0000131FEB787BEB3FF390380FC3F0EB00 +031407A25DA2140F5D121C007E131F5D00FE49C7FC147E5C387801F8387C07E0381FFF80 +D803FEC8FC24367CA426>I<EB03F0EA01FFA3EA00075CA3130F5CA3131F5CA3133F91C8 +FCA35B90387E07F0EC1FFCEC783E9038FFE01F02C01380EC800F1400485A16C05B49EB1F +8012035BA2153F000715005BA25D000F147E5B15FE5D121FD98001131C15F8163C003F01 +031338010013F0A216704814E0007E15F016E0EDE1C000FE903801E38048903800FF0000 +38143C263B7BB92A>I<EB01C0EB07E014F0130F14E01307EB038090C7FCAB13F0EA03FC +EA071EEA0E1F121CA212385B1270A25BEAF07E12E013FEC65AA212015B1203A25B12075B +A2000F13E013C013C1001F13C01381A2EB83801303EB0700A2130E6C5AEA07F8EA01E014 +3879B619>I<EB0FC0EA07FFA3EA001F1480A2133FA21400A25BA2137EA213FEA25BA212 +01A25BA21203A25BA21207A25BA2120FA25BA2121FA25BA2123FA290C7FCA25AA2EA7E0E +A212FE131EEAFC1CA2133C133812F81378EA7870EA7CE0121FEA0F80123B79B915>108 +D<D801E001FEEB07F03C07F803FF801FFC3C0E3C0F07C0783E3C1E3E3C03E1E01F261C1F +78D9F3C013803C383FF001F7800F02E01400007801C013FE007018C002805B4A4848EB1F +80EAF07FD8E07E5CA200000207143F01FE1700495CA2030F5C0001177E495C18FE031F5C +120349DA8001131C18F8033F153C00070403133849020013F0A24B1570000F17E049017E +15F019E003FEECE1C0001FEE01E34949903800FF000007C70038143C3E2679A444>I<D8 +01E013FE3A07F803FF803A0E3C0F07C03A1E3E3C03E0261C1F787F39383FF00114E00078 +13C000708114804A485AEAF07FEAE07EA20000140701FE5C5BA2150F00015D5B151F5E12 +034990383F8380160316070007027F130049137EA2160E000F147C49141E161C5E001FEC +3C7849EB1FE00007C7EA0780292679A42F>I<147F903803FFC090380FC1F090381F00F8 +017E137C5B4848137E4848133E0007143F5B120F485AA2485A157F127F90C7FCA215FF5A +4814FEA2140115FC5AEC03F8A2EC07F015E0140F007C14C0007EEB1F80003EEB3F00147E +6C13F8380F83F03803FFC0C648C7FC202677A42A>I<9039078007C090391FE03FF09039 +3CF0787C903938F8E03E9038787FC00170497EECFF00D9F0FE148013E05CEA01E113C15C +A2D80003143FA25CA20107147FA24A1400A2010F5C5E5C4B5A131F5EEC80035E013F495A +6E485A5E6E48C7FC017F133EEC70FC90387E3FF0EC0F8001FEC9FCA25BA21201A25BA212 +03A25B1207B512C0A3293580A42A>I<3903C003F0390FF01FFC391E783C0F381C7C703A +3C3EE03F8038383FC0EB7F800078150000701300151CD8F07E90C7FCEAE0FE5BA2120012 +015BA312035BA312075BA3120F5BA3121F5BA3123F90C9FC120E212679A423>114 +D<14FE903807FF8090380F83C090383E00E04913F00178137001F813F00001130313F0A2 +15E00003EB01C06DC7FC7FEBFFC06C13F814FE6C7F6D13807F010F13C01300143F141F14 +0F123E127E00FE1480A348EB1F0012E06C133E00705B6C5B381E03E06CB45AD801FEC7FC +1C267AA422>I<EB0380EB07C0130FA4131F1480A3133F1400A35B137E007FB5FCA2B6FC +3800FC00A312015BA312035BA312075BA3120F5BA3121FEB801CA2143C003F1338EB0078 +147014F014E0EB01C0EA3E03381F0780380F0F00EA07FCEA01F0183579B31C>I<01F013 +0ED803FC133FD8071EEB7F80EA0E1F121C123C0038143F49131F0070140FA25BD8F07E14 +0000E08013FEC6485B150E12015B151E0003141C5BA2153C000714385B5DA35DA24A5A14 +0300035C6D48C7FC0001130E3800F83CEB7FF8EB0FC0212679A426>118 +D<903907E007C090391FF81FF89039787C383C9038F03E703A01E01EE0FE3803C01F0180 +13C0D8070014FC481480000E1570023F1300001E91C7FC121CA2C75AA2147EA214FEA25C +A21301A24A1370A2010314F016E0001C5B007E1401010714C000FEEC0380010F1307010E +EB0F0039781CF81E9038387C3C393FF03FF03907C00FC027267CA427>120 +D<13F0D803FCEB01C0D8071EEB03E0D80E1F1307121C123C0038140F4914C01270A24913 +1FD8F07E148012E013FEC648133F160012015B5D0003147E5BA215FE00075C5BA214015D +A314035D14070003130FEBF01F3901F87FE038007FF7EB1FC7EB000F5DA2141F003F5C48 +133F92C7FC147E147C007E13FC387001F8EB03E06C485A383C1F80D80FFEC8FCEA03F023 +3679A428>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Ff cmsy10 10 1 +/Ff 1 16 df<EB1FF0EBFFFE487F000714C04814E04814F04814F8A24814FCA3B612FEA9 +6C14FCA36C14F8A26C14F06C14E06C14C0000114006C5BEB1FF01F1F7BA42A>15 +D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fg ecbx1000 10 36 +/Fg 36 119 df<913803FFC0027F13F00103B512FC010FEB00FED93FF8133FD97FE0EBFF +8049485A5A1480484A13C04A6C1380A36F1300167E93C7FCA592383FFFC0B8FCA4000390 +C7FCB3ABB5D8FC3F13FFA4303A7EB935>28 D<B61280A819087F9620>45 +D<EA0F80EA3FE0EA7FF0A2EAFFF8A5EA7FF0A2EA3FE0EA0F800D0D798C1B>I<141E143E +14FE1307137FB5FCA3138FEA000FB3B3A5007FB61280A4213679B530>49 +D<EB0FFE90387FFFC048B512F0000714FC390FE03FFF261F800F1380263F000313C0D87F +8014E0EBE00100FF6D13F07FA2ED7FF8A46C5A6C5A0006C7FCC8FCEDFFF0A216E05C16C0 +4A138016004A5A4A5AEC1FF05D4A5A4AC7FC14FE495AD903F01378495A495A495A49C712 +F8017C14F05B49130148B6FC5A5A5A5A5A4815E0B7FCA425367BB530>I<EC0FF8ECFFFE +0103EBFF8090390FF80FC090393FE003E090397F8001F09038FF000F48EC1FF84848133F +485A120F5B121FA2003FEC1FF0ED0FE0484890C7FCA31408EC7FF039FFF1FFFC01F313FF +D9F78013809039FF007FC049EB3FE04914F0ED1FF85B16FCA34914FEA4127FA5123F16FC +A26C7E16F8000F143F6D14F0000715E06C6CEB7FC03A01FF81FF806C90B51200013F13FC +010F13F00101138027377CB530>54 D<EA0F80EA3FE0EA7FF0A2EAFFF8A5EA7FF0A2EA3F +E0EA0F80C7FCABEA0F80EA3FE0EA7FF0A2EAFFF8A5EA7FF0A2EA3FE0EA0F800D2579A41B +>58 D<B812C017FC17FF18C028007FF000037F04007F717E717E171F84A2717EA74D5AA2 +60173F4D5A4D5A4C13C0040F5B91B600FCC7FCA2EFFF8002F0C713F0EF3FF8717E717E71 +7E19807113C0A319E0A719C0A25F4D138019005FEF7FFE4C485AB912F018C095C7FC17F0 +3B397DB844>66 D<DB3FFCEB01C00203B5EAC003021FECF00791B6EAFC0F01039039FC00 +FF3F4901C0EB1FFFD91FFEC77E49481403D97FF080494880485B48177F4849153F4890C9 +FC181F485A180F123F5B1807127FA24993C7FC12FFAD127F7FF003C0123FA27F001F1707 +A26C6C1780180F6C6D16006C6D5D6C173E6C6D157ED97FF85D6D6C4A5A6DB44A5A010701 +C0EB0FE06D01FCEBFF80010090B548C7FC021F14F8020314E09126003FFEC8FC3A3B7BB9 +45>I<B87E17F817FF18C028007FF8000713F09338007FF8EF1FFE717E050313807113C0 +A27113E0F07FF0A2F03FF8A219FC181FA219FEA419FFAC19FEA419FC183FA219F8187F19 +F0F0FFE0A24D13C04D13804D1300EF1FFEEF7FFC933807FFF0B912C095C7FC17FC178040 +397DB849>I<B612FCA439007FF800B3B3ADB612FCA41E397DB824>73 +D<B7FCA426007FF8C9FCB3ACEF0780A5170F1800A35FA25FA25F5F5E5EEE0FFE167FB8FC +A431397DB839>76 D<B500F80403B512F06E5EA26E5ED8007FF1E000A2D97BFF161EA201 +796D5DA201786D5DA26E6C5DA36E6C4A5AA26E6C4A5AA26E6C4A5AA26E6C4A5AA26E6C14 +1EA36E6D5BA26E6D5BA26F6C5BA26F6C485AA36F6C485AA26F6C485AA26F6C48C7FCA292 +3803FF1EA36F13BCA26F13F8A2705AA2705AA213FCB500FC6D4848B612F0A2EE0F80EE07 +0054397DB85B>I<B500FC0203B512F0A28080C66C6D90390003F0006F6E5A81017B7F13 +798101787F6E7E6E7E6E7F6E7FA26E7F6E7F6E7F6E7F6F7E153F826F13806F13C06F13E0 +6F13F06F13F88117FCEE7FFEEE3FFF7013817013C17013E18218F17013F97013FDEF7FFF +8383A28383838383187FA2183F181F01FC160FB500FC150718031801A244397DB84B>I< +EDFFF8020FEBFF80027F14F0903A01FFC01FFC010790380007FFD91FFC010113C0D93FF0 +6D6C7E49486E7E49486E7E48496E7E48834890C86C7EA248486F1380A248486F13C0A200 +3F18E0A348486F13F0A400FF18F8AC007F18F06D5DA3003F18E0A26D5D001F18C0A26C6C +4B13806C18006E5C6C6D4A5A6C5F6C6D4A5A6D6C4A5AD93FFC49485A6DB401075B0107D9 +C01F90C7FC010190B512FC6D6C14F0020F1480020001F8C8FC3D3B7BB948>I<B8FC17F0 +17FEEFFF8028007FF8000F13C0040113E07013F0EF7FF8EF3FFCA2EF1FFEA218FFA818FE +A2EF3FFCA2EF7FF8EFFFF04C13E0040F13C091B7120017FC17E002F8C9FCB3A4B612FCA4 +38397DB841>I<EDFFF8020FEBFF80027F14F0903A01FFE03FFC010790380007FFD91FFC +010113C049486D7FD97FE0EC3FF049486E7E488348496E7E4890C86C7EA248486F1380A2 +001F18C04981003F18E0A3007F18F04981A300FF18F8AC007F18F0A36D5D003F18E0A36C +6C4B13C0A2000FDA1FC014806C6C90267FF0071300EDFFF86C903A81F07C0FFE6C903AC3 +C01E1FFC6CDA800F5BD97FE3ECBFF0D93FF36DB45AD91FFF5D010701C091C7FC01019038 +F01FFC6D6CB500F01308020F6E131C0200EBF9FC92260001FE133C9438FF80FC18FF8219 +F8A28319F0A27113E0A27113C0711380711300EF01FC3E4A7BB948>I<D907FF130E013F +EBE01E90B5EAF83E0003ECFE7E3A07FC01FFFE390FF0001F4848130F4848130349130100 +7F140090C8FC167E5A163EA27F161E7F7F6D91C7FC13FC387FFFE014FEECFFF06C14FE6F +7E6C816C15F06C816C81C681133F010F801301D9000F1480EC007F030F13C01503818100 +F0157FA3163FA27E17807E167F6C16007E6D14FE01E0495A01F813039039FF801FF800FC +90B512E0D8F83F5CD8F00749C7FC39E0007FF02A3B7BB935>83 D<B600FC011FB512C0A4 +26007FF8C8381FC000725AB3B3181F013F94C7FC8060011F163E6D6C157E187C6D6C15FC +6D6D495A6D6DEB07F06D01F0EB1FE0DA7FFEEBFFC0021FB6C8FC02075C020014F0030F13 +80423A7DB849>85 D<B600F00103B512E0A4C601F0C83807F0006E5E017F5F6E150FA201 +3F5F6E151F011F94C7FC6E5D6D163E6F147E6D167CA26F14FC6D5E6F13016D5E6F13036D +5E811707027F5D6F130F023F5D6F131F021F92C8FC815F6E143EEE807E6E147CEEC0FC6E +5C16E016E16E5C16F36E5C16FF6F5BA36F5BA26F90C9FCA26F5AA36F5AA26F5AA26F5A43 +3A7EB848>I<B6D8E01FB500FC90383FFFFCA4000101F0C7D83FFCC8EA7E006C71153C17 +1F6E197C017F701578836E7014F8013F6F5E6E1801011F4B6D5CA26E18036D4B6D5CA26D +6D496D495A173C6F170F6D037C6D91C7FCEF787F6F5F6D4B6C6C131E816D02016E5BEFE0 +1F03F8177C027F01036E13784D7E03FCEE80F8023F49486C5C15FE021F010FEDC1E04D7E +03FF16C36E49EDE3C0041E7F049E15F76E01BC6D5C04FC15FF6E95C8FC4C80A26E5F4C14 +3F6E5F4C141FA2037F5E4C140FA26F486E5AA2031F5E93C812036F5E5E3A7EB863>I<13 +FFB5FCA412077EAF4AB47E020F13F0023F13FC9138FE03FFDAF00013804AEB7FC00280EB +3FE091C713F0EE1FF8A217FC160FA217FEAA17FCA3EE1FF8A217F06E133F6EEB7FE06E14 +C0903AFDF001FF80903AF8FC07FE009039F03FFFF8D9E00F13E0D9C00390C7FC2F3A7EB9 +35>98 D<EE7F80ED7FFFA4150381AF903801FF81010F13F1013F13FD9038FFC07F0003EB +001FD807FC1307000F8048487F5B123FA2485AA312FFAA127FA27F123FA26C6C5B000F5C +6C6C5B6C6C4913C02701FF80FD13FE39007FFFF9011F13E1010113012F3A7DB935>100 +D<903803FF80011F13F0017F13FC3901FF83FE3A03FE007F804848133F484814C0001FEC +1FE05B003FEC0FF0A2485A16F8150712FFA290B6FCA301E0C8FCA4127FA36C7E1678121F +6C6C14F86D14F000071403D801FFEB0FE06C9038C07FC06DB51200010F13FC010113E025 +257DA42C>I<EC1FF0903801FFFC010713FF90391FF87F8090383FE0FFD9FFC113C0A248 +1381A24813016E1380A2ED3E0092C7FCA8B6FCA4000390C8FCB3ABB512FEA4223A7DB91D +>I<161FD907FEEBFFC090387FFFE348B6EAEFE02607FE07138F260FF801131F48486C13 +8F003F15CF4990387FC7C0EEC000007F81A6003F5DA26D13FF001F5D6C6C4890C7FC3907 +FE07FE48B512F86D13E0261E07FEC8FC90CAFCA2123E123F7F6C7E90B512F8EDFF8016E0 +6C15F86C816C815A001F81393FC0000F48C8138048157F5A163FA36C157F6C16006D5C6C +6C495AD81FF0EB07FCD807FEEB3FF00001B612C06C6C91C7FC010713F02B377DA530>I< +EA01F0EA07FC487EA2487EA56C5AA26C5AEA01F0C8FCA913FF127FA412077EB3A9B512F8 +A4153B7DBA1B>105 D<13FFB5FCA412077EAF92380FFFE0A4923803FC0016F0ED0FE0ED +1F804BC7FC157E5DEC03F8EC07E04A5A141FEC7FE04A7E8181A2ECCFFEEC0FFF496C7F80 +6E7F6E7F82157F6F7E6F7E82150F82B5D8F83F13F8A42D3A7EB932>107 +D<13FFB5FCA412077EB3B3ACB512FCA4163A7DB91B>I<01FED97FE0EB0FFC00FF902601 +FFFC90383FFF80020701FF90B512E0DA1F81903983F03FF0DA3C00903887801F000749DA +CF007F00034914DE6D48D97FFC6D7E4A5CA24A5CA291C75BB3A3B5D8FC1FB50083B512F0 +A44C257DA451>I<01FEEB7FC000FF903803FFF8020F13FE91381F03FFDA3C0113800007 +13780003497E6D4814C05CA25CA291C7FCB3A3B5D8FC3F13FFA430257DA435>I<903801 +FFC0010F13F8017F13FFD9FF807F3A03FE003FE048486D7E48486D7E48486D7EA2003F81 +491303007F81A300FF1680A9007F1600A3003F5D6D1307001F5DA26C6C495A6C6C495A6C +6C495A6C6C6CB45A6C6CB5C7FC011F13FC010113C029257DA430>I<9038FE03F000FFEB +0FFEEC3FFF91387C7F809138F8FFC000075B6C6C5A5CA29138807F80ED3F00150C92C7FC +91C8FCB3A2B512FEA422257EA427>114 D<90383FF0383903FFFEF8000F13FF381FC00F +383F0003007E1301007C130012FC15787E7E6D130013FCEBFFE06C13FCECFF806C14C06C +14F06C14F81203C614FC131F9038007FFE140700F0130114007E157E7E157C6C14FC6C14 +F8EB80019038F007F090B512C000F8140038E01FF81F257DA426>I<130FA55BA45BA25B +5BA25A1207001FEBFFE0B6FCA3000390C7FCB21578A815F86CEB80F014816CEBC3E09038 +3FFFC06D1380903803FE001D357EB425>I<B539F001FFF8A4000390C7EA1F00161E6E13 +3E6C153C6E137C6C15786E13F8017F5CECF001013F5C14F8011F495AA2ECFC07010F5CEC +FE0F010791C7FC6E5A6D131E15BE6D13BC15FC6D5BA36E5AA26E5AA26E5AA26E5AA22D25 +7EA432>118 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fh ecrm1000 10 89 +/Fh 89 126 df<486C1360000314E039070001C0000EEB038048EB070000181306003813 +0E0030130C0070131C00601318A200E01338481330A400CEEB338039FF803FE001C013F0 +A3007F131FA2393F800FE0390E0003801C1981B91C>16 D<001C1307007FEB1FC039FF80 +3FE0A201C013F0A3007F131F001CEB073000001300A400011470491360A2000314E090C7 +12C048130100061480000E130348EB070048130E485B006013181C1980B91C>I<B81280 +A2290280962A>21 D<DA0FF813FC91397FFF07FF903B01F807DF83C0903A07E001FF0F90 +3B1F8007FE1FE090393F000FFC137E16F85B9338F007804848010790C7FC1503ACB812F8 +A32801F80003F0C7FCB3AB486C497E267FFFE0B512F0A3333B7FBA30>27 +D<EC0FF8EC7FFE903901F80780903907E001C090391F8000E090383F0007017E497EA25B +A2485A6F5AED018092C8FCA9ED03F0B7FCA33901F8000F1503B3AA486C497E267FFFE0B5 +12C0A32A3B7FBA2E>I<DA0FF0EB1FF0DA7FFEEBFFFC903B01F80F83F00F903C07E001CF +C00380903C1F8000FF0001C090273F0007FE130F017E4948497EA2495CA248485C03076E +5A03030203C7FC95C8FCA9F007E0BAFCA33C01F80003F0001F1807B3AA486C496C497E26 +7FFFE0B500C1B51280A3413B7FBA45>30 D<EB0380A3EB0FF0EB7FFE48B512803903F38F +C03907C381E0390F8380F0D81F031338123E003C141C007C140C150E0078143E00F814FE +1481A400FCEB80FC157800FE140012FF127F13C313E3EA3FFF6C7F14F86C13FE6CEBFF80 +000114C06C14E0013F13F01303ECBFF8148FEC83FC1481A2EC80FE157E123C12FF153EA4 +12FE00F8143C00E0147C12600070147815F8003814F0003C1381001EEB83E0000FEB87C0 +3907E39F803901FFFE006C5BEB1FE0EB0380A41F437BBD2A>36 D<141FEC7FC0903801F0 +E0903803C0600107137090380F803090381F00381518A25BA2133E133F15381530A21570 +5D5D140190381F838092CAFC1487148E02DC49B51280EB0FF85C4A9039003FF8000107ED +0FC06E5D71C7FC6E140E010F150CD91DFC141C01391518D970FE143801E015302601C07F +1470D803805D00076D6C5BD80F00EBC00148011F5C4890380FE003003E6E48C8FC007E90 +3807F8060203130E00FE6E5A6E6C5A1400ED7F706C4B13036F5A6F7E6C6C6D6C5B701306 +6C6C496C130E6DD979FE5B281FF001F07F133C3C07F80FE03FC0F86CB539800FFFF0C690 +26FE000313C0D91FF0D9007FC7FC393E7DBB41>38 D<121C127FEAFF80A213C0A3127F12 +1C1200A412011380A2120313005A1206120E5A5A5A12600A1979B917>I<146014E0EB01 +C0EB0380EB0700130E131E5B5BA25B485AA2485AA212075B120F90C7FCA25A121EA2123E +A35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203A26C7EA26C7E1378A27F7F130E +7FEB0380EB01C0EB00E01460135278BD20>I<12C07E12707E7E7E120F6C7E6C7EA26C7E +6C7EA21378A2137C133C133E131EA2131F7FA21480A3EB07C0A6EB03E0B2EB07C0A6EB0F +80A31400A25B131EA2133E133C137C1378A25BA2485A485AA2485A48C7FC120E5A5A5A5A +5A13527CBD20>I<1530B3A8B912FCA2C80030C8FCB3A836367BAF41>43 +D<121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A1206120E5A5A5A +12600A19798817>I<B512FCA516057F941C>I<121C127FEAFF80A5EA7F00121C09097988 +17>I<1506A2150E150CA2151C151815381530A215701560A215E015C0A214011580A214 +0315005C1406A2140E140CA2141C1418A214381430A21470146014E05CA213015CA21303 +91C7FCA25B1306A2130E130C131C1318A213381330A213701360A213E05BA212015B1203 +90C8FCA25A1206A2120E120CA2121C1218A21238123012701260A212E05AA21F537BBD2A +>I<EB03F8EB1FFF90387E0FC09038F803E03901E000F0484813780007147C48487FA248 +C77EA2481580A3007EEC0FC0A500FE15E0B3007E15C0A4007F141F6C1580A36C1500A26C +6C133EA26C6C5B6C6C5BEBF0013900F803E090387E0FC0D91FFFC7FCEB03F823397DB62A +>I<EB01C013031307131F13FFB5FCA2131F1200B3B3A7497E007FB512F0A31C3779B62A> +I<EB0FF0EB7FFE48B57E3903E03FE0390F000FF0001E6D7E001C6D7E486D7E5A6E7E1260 +12FE6CEC7F807FA56CC7FC121CC8FCEDFF00A25D14015D14035D4A5A4A5A5D4A5A4AC7FC +147E5C495A14E0495A495A49C8FC011EEB01805B5B49130348481400485A485A90C75A48 +B6FC5A5A485CB6FCA321377CB62A>I<EB07F8EB3FFF90B512C03901F80FF03903C007F8 +48486C7E390E0001FEEA0F80391FE000FF7FA56C5A6C5AC7485AA25D14035D4A5A5DEC0F +80027FC7FCEB1FFCECFF809038000FE06E7EEC01FC816E7EED7F80A216C0A2153F16E0A2 +121EEA7F80A2487EA316C0157F491480007EC7FC0070ECFF006C495A121E390F8003F839 +07F00FF00001B512C06C6C90C7FCEB0FF823397DB62A>I<1538A2157815F8A214011403 +1407A2140F141F141B14331473146314C313011483EB030313071306130C131C13181330 +1370136013C01201EA038013005A120E120C5A123812305A12E0B712F8A3C73803F800AA +4A7E0103B512F8A325387EB72A>I<0006140CD80780133C9038F003F890B5FC5D5D1580 +92C7FC14FC38067FE090C9FCAAEB07F8EB1FFE9038780F809038E007E03907C003F0496C +7E130000066D7E81C8FC8181A21680A4121C127F5A7FA390C713005D12FC00605C12704A +5A6C5C6C1303001E495A6C6C485A3907E03F800001B5C7FC38007FFCEB1FE021397CB62A +>I<EC3FC0903801FFF0010713FC90380FE03E90383F800790387E001F49EB3F80484813 +7F485A12075B000FEC3F0049131E001F91C7FC5B123FA3127F90C9FCEB01FC903807FF80 +39FF1E07E090383801F0496C7E01607F01E0137E497F16805BED1FC0A390C713E0A57EA4 +7F123F16C0A2001FEC3F807F000F15006D5B000714FE6C6C5B6C6C485A3900FE07F09038 +7FFFC0011F90C7FCEB03FC23397DB62A>I<12301238123E003FB612E0A316C05A168016 +000070C712060060140E5D5D00E014304814705D5DC712014A5A4AC7FC1406140E5CA25C +1478147014F05C1301A213035C1307A2130FA3131F5CA2133FA5137FA96DC8FC131E233A +7BB72A>I<EB03F8EB1FFF017F13C09038FC07F03901E001F83903C0007C4848133C90C7 +123E48141E000E141F001E80A3121FA26D5B6D131E7FD80FF85B6D137C01FF13786C6D5A +6CEBE3E0ECF780C601FFC7FC6D5A6D6C7E010F13E0013F7F01F97F3901E07FFE48486C7E +380F800F48486C1380001E010113C0487F007C143F0078EC1FE0150F00F81407481403A2 +1501A36C15C0A200781403007C15806C14076CEC0F006C6C131ED807E0137C3903F803F0 +C6B55A013F1380D907FCC7FC23397DB62A>I<EB03F8EB1FFF017F13C03901FC07E04848 +6C7E3907E001F8000F6D7E4848137E5B003F80A248C71380A25AED1FC0A516E0A56C143F +A36C7E157F121F6C6C13FF6C6C13DF000313013901F0039F3900FC0F1FD93FFC13C0EB07 +F090C7FCA2153F1680A216005D120F486C137E486C5BA24A5A4A5A49485A381F000F001C +EB1F80260F807FC7FC3807FFFE000113F838003FC023397DB62A>I<121C127FEAFF80A5 +EA7F00121CC7FCB2121C127FEAFF80A5EA7F00121C092479A317>I<121C127FEAFF80A5 +EA7F00121CC7FCB2121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A +1206120E5A5A5A12600A3479A317>I<EF01C0EF0780EF1E0017F8EE03E0040FC7FC163C +16F0ED03C0030FC8FC153CEC01F0EC07C0021EC9FC1478EB01E0EB0780011ECAFC13F8EA +03E0000FCBFC123C12F0A2123C120FEA03E0EA00F8131EEB0780EB01E0EB0078141EEC07 +C0EC01F0EC003C150FED03C0ED00F0163C160FEE03E0EE00F8171EEF0780EF01C0322E79 +AB41>I<007FB812F8B912FCCCFCB0B912FC6C17F836147B9E41>I<12E01278121EEA07C0 +EA01F0EA003C130FEB03C0EB00F0143C140FEC03E0EC00F8151EED0780ED01E0ED007816 +1EEE07C0EE01F0EE003C170FEF03C0A2EF0F00173CEE01F0EE07C0041EC7FC1678ED01E0 +ED0780031EC8FC15F8EC03E0020FC9FC143C14F0EB03C0010FCAFC133CEA01F0EA07C000 +1ECBFC127812E0322E79AB41>I<EB3FE03801FFFE3907C03F80390E000FC0003CEB07F0 +00301303007014F8007C130100FE14FC7EA4127E003CEB03F8C7FCEC07F0A2EC0FE0EC1F +80EC3F00147E147C5C495A5C495A5CA249C7FCA31306AA90C8FCA8130EEB3F80497EA56D +5A010EC7FC1E3B7CBA27>I<1538A3157CA315FEA34A7EA34A6C7EA202077FEC063FA202 +0E7FEC0C1FA2021C7FEC180FA202387FEC3007A202707FEC6003A202C07F1501A2D90180 +7F81A249C77F167FA20106810107B6FCA24981010CC7121FA2496E7EA3496E7EA3496E7E +A213E0707E1201486C81D80FFC02071380B56C90B512FEA3373C7DBB3E>65 +D<B712E016FC16FF0001903980007FC06C90C7EA1FE0707E707E707EA2707EA283A75F16 +035F4C5A4C5A4C5A4C5AEEFF8091B500FCC7FCA291C7EA7F80EE1FE0EE07F0707E707E83 +707EA21880177F18C0A7188017FFA24C13005F16034C5AEE1FF8486DEB7FF0B812C094C7 +FC16F832397DB83B>I<913A01FF800180020FEBE003027F13F8903A01FF807E07903A03 +FC000F0FD90FF0EB039F4948EB01DFD93F80EB00FF49C8127F01FE153F12014848151F48 +48150FA248481507A2485A1703123F5B007F1601A35B00FF93C7FCAD127F6DED0180A312 +3F7F001F160318006C7E5F6C7E17066C6C150E6C6C5D00001618017F15386D6C5CD91FE0 +5C6D6CEB03C0D903FCEB0F80902701FF803FC7FC9039007FFFFC020F13F002011380313D +7BBA3C>I<B712C016F816FE000190398001FF806C90C7EA3FE0EE0FF0EE03F8707E707E +177FA2EF3F8018C0171F18E0170F18F0A3EF07F8A418FCAC18F8A4EF0FF0A218E0A2171F +18C0EF3F80A2EF7F0017FE4C5A4C5AEE0FF0EE3FE0486DEBFF80B8C7FC16F816C036397D +B83F>I<B812FEA3000190388000076C90C8FC173F838383A383A31880170116C0A394C7 +FCA31501A21503150F91B5FCA3EC000F15031501A21500A21860A318E093C712C0A41701 +A3EF0380A21707A2170F173F177F486D903807FF00B9FCA333397EB838>I<B812F8A300 +01903880001F6C90C71201EE00FC177C173C171CA2170CA4170E1706A2ED0180A21700A4 +1503A21507151F91B5FCA3EC001F15071503A21501A692C8FCAD4813C0B612C0A32F397D +B836>I<DBFF8013C0020FEBF001023F13FC9139FF803F03903A03FC000787D90FF0EB03 +CF4948EB00EF4948147F4948143F49C8121F485A4848150F48481507A248481503A2485A +1701123F5B007F1600A448481600AB93B6FCA26C7E9338007FE0EF3FC0A2123F7F121FA2 +6C7EA26C7EA26C7E6C7E6C6C157F6D7E6D6C14FF6D6C14EFD90FF8EB03C7D903FEEB0783 +903A00FFC03F0191393FFFFC00020F01F0130002001380383D7CBA41>I<B648B512FEA3 +0001902680000313006C90C76C5AB3A491B6FCA391C71201B3A6486D497EB648B512FEA3 +37397DB83E>I<B612C0A3C6EBC0006D5AB3B3AD497EB612C0A31A397EB81E>I<013FB512 +E0A39039001FFC00EC07F8B3B3A3123FEA7F80EAFFC0A44A5A1380D87F005B0070131F6C +5C6C495A6C49C7FC380781FC3801FFF038007F80233B7DB82B>I<B649B5FCA300010180 +9038007FF06C90C8EA3F80053EC7FC173C17385F5F4C5A4C5A4CC8FC160E5E5E5E5E4B5A +ED0780030EC9FC5D153E157E15FF5C4A7F4A6C7E140E4A6C7E4A6C7E14704A6C7E4A6C7E +14804A6C7E6F7EA26F7F707EA2707E707EA2707EA2707E707EA2707E707F8484486D497F +B6011FEBFF80A339397DB841>I<B612E0A3000101C0C8FC6C90C9FCB3AD1718A5173817 +30A31770A317F0A216011603160FEE1FE0486D13FFB8FCA32D397DB834>I<B5933807FF +F86E5DA20001F0FC002600DFC0ED1BF8A2D9CFE01533A3D9C7F01563A3D9C3F815C3A2D9 +C1FCEC0183A3D9C0FEEC0303A2027F1406A36E6C130CA36E6C1318A26E6C1330A36E6C13 +60A26E6C13C0A3913901FC0180A3913900FE0300A2ED7F06A3ED3F8CA2ED1FD8A3ED0FF0 +A3486C6D5A487ED80FFC6D48497EB500C00203B512F8A2ED018045397DB84C>I<B59138 +07FFFE8080C69238007FE06EEC1F80D9DFF0EC0F001706EBCFF8EBC7FCA2EBC3FEEBC1FF +A201C07F6E7EA26E7E6E7E81140F6E7E8114036E7E168080ED7FC016E0153FED1FF0ED0F +F8A2ED07FCED03FEA2ED01FF6F1386A2EE7FC6EE3FE6A2EE1FF6EE0FFEA216071603A216 +011600A2177E486C153E487ED80FFC151EB500C0140EA2170637397DB83E>I<EC03FF02 +1F13E09138FE01FC903901F8007ED907E0EB1F8049486D7ED93F80EB07F049C76C7E01FE +6E7E48486E7E49157E0003167F4848ED3F80A24848ED1FC0A2001F17E049150F003F17F0 +A3007F17F8491507A300FF17FCAC007F17F86D150FA3003F17F0A26C6CED1FE0A36C6CED +3FC0000717806D157F000317006C6C15FEA26C6C4A5A017F4A5A6D6C495A6D6C495AD907 +E0EB1F80D903F8017FC7FC903900FE01FC91381FFFE0020390C8FC363D7BBA41>I<B712 +C016FC16FF0001D9800013C06C90C7EA1FE0707EEE03F883707EA2707EA21880A71800A2 +4C5AA24C5A5FEE0FF04C5AEEFF8091B548C7FC16F091CAFCB3A5487FB6FCA331397EB838 +>I<EC03FF021F13E09138FE01FC903901F8007ED907E0EB1F8049486D7ED93F80EB07F0 +49C76C7E01FE6E7E48486E7EA24848157F0007178049153F000F17C049151F001F17E0A2 +4848ED0FF0A3007F17F8A2491507A200FF17FCAC007F17F8A26D150FA2003F17F0A26C6C +ED1FE0A36C6CED3FC00007027C14804AB4FC3C03F80383807F003B01FC0701C0FEEC0E00 +2600FE0CEBE1FC017FEC63F8D93F8CEB77F0D91FCCEB3FE0D907EE14806DB449C7FC0100 +D981FC130CEC1FFF0203131C91C7001E131C161F183CEF807CEFC0F8EE0FFFA318F08218 +E07013C07013809338007E00364B7BBA41>I<B612FEEDFFE016F8000190388007FE6C90 +C76C7EEE3FC0707E707E707EA2707EA283A65FA24C5AA24C5A4C5AEE3F8004FFC8FCED07 +FC91B512E05E9138000FF0ED03F8ED00FE82707E707EA2161F83A583A6F00180A217F816 +0F1803486D01071400B66D6C5A04011306933800FE0ECAEA3FFCEF07F0393B7DB83D>I< +D90FF813C090383FFE0190B512813903F807E33907E000F74848137F4848133F48C7121F +003E140F007E1407A2007C140312FC1501A36C1400A37E6D14006C7E7F13F86CB47E6C13 +F8ECFF806C14E06C14F86C14FEC680013F1480010714C0EB007F020713E0EC007FED3FF0 +151F150FED07F8A200C01403A21501A37EA216F07E15036C15E06C14076C15C06C140F6D +EB1F80D8FBF0EB3F00D8F0FE13FE39E03FFFF8010F13E0D8C00190C7FC253D7CBA2E>I< +003FB812E0A3D9C003EB001F273E0001FE130348EE01F00078160000701770A300601730 +A400E01738481718A4C71600B3B0913807FF80011FB612E0A335397DB83C>I<B6903807 +FFFEA3000101809038007FE06C90C8EA1F80EF0F001706B3B2170E6D150C80171C133F17 +186D6C14385F6D6C14F06D6C5C6D6C495A6D6CEB07806D6C49C7FC91387F807E91381FFF +F8020713E09138007F80373B7DB83E>I<B500FC91387FFF80A30003018091380FFC006C +90C8EA07E0715A6C705A6E1403017F93C7FCA280013F1506A26E140E011F150C80010F5D +A28001075DA26E147001031560A26D6C5CA2806D4A5AA2ED8003027F91C8FCA291383FC0 +06A215E0021F5BA2EDF01C020F1318A26E6C5AA215FC02035BA2EDFEE002015BA26E6C5A +A36FC9FCA3153EA2151CA3393B7EB83E>I<B5D8FC07B5D8F001B5FCA30007902780001F +FEC7EA1FF86C48C7D80FF8EC07E000010307ED03C01B807F6C6F6C1500A26E5F017F6E6C +1406A280013F4A6C5CA280011F4A6D5BEE067FA26D6C010E6D5BEE0C3FA26D6C011C6D5B +EE181FA26D6C6F5BEE300FA26D6C6F485AEE6007A26D6C4CC7FC9338C003FCA203805D91 +3B7F818001FE06A203C1150EDA3FC3C7EAFF0CA203E3151CDA1FE6EC7F98A215F6DA0FFC +EC3FF0A302075E4B141FA202035E4B140FA202015E4B1407A2020093C8FC4B80503B7EB8 +55>I<B500FE91383FFFE0A3000301E0913807FE00C649EC03F0017F6F5A606D6C5D6D6C +140395C7FC6D6C1406A26D6C5C6D6C141C17186D6C143817306D6D5B6E6C13E05F91383F +E0015F91381FF003DA0FF890C8FC1606913807FC0E160C913803FE1C913801FF185E6E13 +B016E0157F6F5AB3A24B7E023FB512C0A33B397FB83E>89 D<003FB7FCA39039FC0001FE +01C0130349495A003EC7FC003C4A5A5E0038141F00784A5A12704B5A5E006014FF4A90C7 +FCA24A5A5DC712074A5AA24A5A5D143F4A5AA24A5A92C8FC5B495AA2495A5C130F4948EB +0180A2495A5C137F495A16034890C7FC5B1203485AEE0700485A495C001F5D48485C5E48 +48495A49130FB8FCA329397BB833>I<EAFFFCA2EAFC00B3B3B3B3A7EAFFFCA20E5379BD +17>I<EAFFFCA21200B3B3B3B3A712FFA20E537FBD17>93 D<007FB81280B912C0A26C17 +803204797041>95 D<EB1FE0EBFFFC3803E03F3907000F80390F8007E0486C6C7E13E06E +7EA26E7E6C5A6C5AC8FCA4147FEB07FFEB3FE0EBFE00EA03F8EA0FF0EA1FC0123F485A90 +C7FC160C12FEA31401A26C13036CEB077C903980063E18383FC01E3A0FE0781FF03A03FF +F00FE03A007F8007C026277DA52A>97 D<EA03F012FFA3120F1203B0EC1FE0EC7FF89038 +F1E03E9039F3801F809039F7000FC001FEEB07E049EB03F049EB01F85BED00FCA216FEA2 +167E167FAA167E16FEA216FC15016D14F8ED03F07F01EEEB07E001C6EB0FC09039C7801F +00903881E07E903800FFF8C7EA1FC0283B7EB92E>I<EB03FC90381FFF8090387E03E039 +01F80070484813F83907E001FC380FC003A2EA1F80123F90380001F848EB00F01500A212 +7E12FEAA127E127FA26C14067F001F140E6D130C000F141C6C6C13386C6C13706C6C13E0 +39007C07C090381FFF00EB07F81F277DA525>I<ED0FC0EC03FFA3EC003F150FB0EB03F8 +EB1FFF90387E078F9038F801EF3903F0007F4848133F4848131FA24848130F123F90C7FC +5AA2127E12FEAA127E127FA27EA26C6C131FA26C6C133F6C6C137F6C6CEBEFF03A01F801 +CFFF39007C078F90381FFE0FD907F813C0283B7DB92E>I<EB07F8EB1FFF90387C0FC039 +01F803E03903F001F0D807E013F8380FC0004848137CA248C7127E153E5A153F127E12FE +A3B7FCA248C8FCA5127EA2127FA26C14037F001F14076C6C13060007140E6D131CD801F0 +13386C6C137090387E03E090381FFF80903803FC0020277EA525>I<147E903803FF8090 +380FC1E0EB1F8790383F0FF0137EA213FCA23901F803C091C7FCADB512FCA3D801F8C7FC +B3AB487E387FFFF8A31C3B7FBA19>I<ED03F090390FF00FF890393FFC3C3C9039F81F70 +7C3901F00FE03903E007C03A07C003E010000FECF000A248486C7EA86C6C485AA200075C +6C6C485A6D485A6D48C7FC38073FFC38060FF0000EC9FCA4120FA213C06CB512C015F86C +14FE6CECFF804815C03A0F80007FE048C7EA0FF0003E140348140116F8481400A56C1401 +007C15F06CEC03E0003F1407D80F80EB0F80D807E0EB3F003901FC01FC39007FFFF00107 +90C7FC26387EA52A>I<EA03F012FFA3120F1203B0EC0FF0EC3FFCECF03F9039F1C01F80 +9039F3800FC0EBF70013FE496D7EA25BA35BB3A3486C497EB500C1B51280A3293A7EB92E +>I<EA0380EA0FE0487EA56C5AEA0380C8FCAAEA03F012FFA312071203B3AA487EB512C0 +A312387EB717>I<EB01C0EB07F0EB0FF8A5EB07F0EB01C090C7FCAAEB01F813FFA31307 +1301B3B3A2123C127E00FF13F01303A214E038FE07C0127C383C0F00EA0FFEEA03F81549 +84B719>I<EA03F012FFA3120F1203B1913801FFFCA39138007FC01600157C15705D4A5A +4A5A4AC7FC141E1438147814FC13F1EBF3FEEBF73F01FE7FEBF81F496C7E8114076E7E6E +7E811400157E157F811680ED1FC0486CEB3FF0B500C0B5FCA3283A7EB92C>I<EA03F012 +FFA3120F1203B3B3AD487EB512C0A3123A7EB917>I<2703F00FF0EB1FE000FFD93FFCEB +7FF8913AF03F01E07E903BF1C01F83803F3D0FF3800FC7001F802603F70013CE01FE14DC +49D907F8EB0FC0A2495CA3495CB3A3486C496CEB1FE0B500C1B50083B5FCA340257EA445 +>I<3903F00FF000FFEB3FFCECF03F9039F1C01F803A0FF3800FC03803F70013FE496D7E +A25BA35BB3A3486C497EB500C1B51280A329257EA42E>I<EB03FE90380FFF8090383E03 +E09038F800F84848137C48487F48487F4848EB0F80001F15C090C712074815E0A2007EEC +03F0A400FE15F8A9007E15F0A2007F14076C15E0A26C6CEB0FC0000F15806D131F6C6CEB +3F006C6C137EC66C13F890387E03F090381FFFC0D903FEC7FC25277EA52A>I<3903F01F +E000FFEB7FF89038F1E07E9039F3801F803A07F7000FC0D803FEEB07E049EB03F04914F8 +49130116FC150016FEA3167FAA16FEA3ED01FCA26DEB03F816F06D13076DEB0FE001F614 +C09039F7803F009038F1E07E9038F0FFF8EC1FC091C8FCAB487EB512C0A328357EA42E> +I<D903F813C090381FFE0190387E07819038FC01C33903F000E300071477484813374913 +3F001F141F485A150F48C7FCA312FEAA127FA37E6D131F121F6D133F120F6C6C137F6C6C +13EF3901F801CF39007E078F90381FFE0FEB07F890C7FCABED1FE00203B5FCA328357DA4 +2C>I<3807E01F00FFEB7FC09038E1E3E09038E387F0380FE707EA03E613EE9038EC03E0 +9038FC0080491300A45BB3A2487EB512F0A31C257EA421>I<EBFF03000313E7380F80FF +381E003F487F487F00707F12F0A2807EA27EB490C7FCEA7FE013FF6C13E06C13F86C7F00 +037FC67F01071380EB007F141F00C0EB0FC01407A26C1303A37E15806C13077EEC0F00B4 +131E38F3C07C38E1FFF038C03F801A277DA521>I<1318A51338A31378A313F812011203 +1207001FB5FCB6FCA2D801F8C7FCB215C0A93800FC011580EB7C03017E13006D5AEB0FFE +EB01F81A347FB220>I<D803F0EB07E000FFEB01FFA3000FEB001F00031407B3A4150FA3 +151F12016D133F0000EC77F86D9038E7FF8090383F03C790381FFF87903A03FC07E00029 +267EA42E>I<B538803FFEA33A0FF8000FF06C48EB07E00003EC03C06D148000011500A2 +6C6C1306A26D130E017E130CA26D5BA2EC8038011F1330A26D6C5AA214E001075BA29038 +03F180A3D901FBC7FCA214FF6D5AA2147CA31438A227257EA32C>I<B53A1FFFE03FFEA3 +260FF8009038000FF86C48017EEB03E018C00003023EEB0180A26C6C013FEB0300A36C6C +EC8006156FA2017E9038EFC00C15C7171CD93F01EBE01815830281EBF038D91F83143015 +0102C3EBF87090260FC6001360A2D907E66D5A02EC137CA2D903FCEB7F804A133FA20101 +92C7FC4A7FA20100141E4A130E0260130C37257EA33C>I<B538807FFFA33A03FE003FF0 +0001EC1F80000092C7FC017E131C6D13186D6C5AECC070010F5B6D6C5AECF180EB03FB6D +B4C8FC6D5AA2147F804A7E8114CF903801C7E090380383F090380703F8EB0601496C7E01 +1C137E49137F01787F496D7E486C80000FEC3FF0D8FFFE90B51280A329247FA32C>I<B5 +38803FFEA33A0FF8000FF06C48EB07C00003EC03806C7E16007F00001406A2017E5BA213 +7F6D5BA26D6C5AA2ECC070010F1360A26D6C5AA214F101035BA2D901FBC7FCA214FF6D5A +A2147CA31438A21430A214701460A25CA2EA7C0100FE5B130391C8FC1306EAFC0EEA701C +6C5AEA1FF0EA0FC027357EA32C>I<003FB512FCA2EB8003D83E0013F8003CEB07F00038 +EB0FE012300070EB1FC0EC3F800060137F150014FE495AA2C6485A495AA2495A495A495A +A290387F000613FEA2485A485A0007140E5B4848130C4848131CA24848133C48C7127C48 +EB03FC90B5FCA21F247EA325>I<EC01F8140FEC3F80ECFC00495A495A495AA2130F5CB3 +A7131F5C133F49C7FC13FEEA03F8EA7FE048C8FCEA7FE0EA03F8EA00FE137F6D7E131F80 +130FB3A7801307A26D7E6D7E6D7EEC3F80EC0FF814011D537ABD2A>I<126012F0B3B3B3 +B3A91260045377BD17>I<12FCEAFFC0EA07F0EA01FCEA007E7F80131F80130FB3A78013 +07806D7E6D7EEB007EEC1FF0EC07F8EC1FF0EC7E00495A495A495A5C130F5CB3A7131F5C +133F91C7FC137E485AEA07F0EAFFC000FCC8FC1D537ABD2A>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fi ecbx1440 14.4 34 +/Fi 34 118 df<EE7FFC031FB57E4AB612E0020715F8023F9038C00FFC913AFFFC0001FE +4901F0EB007F010701C0EB03FF4949497F4990C75A5B5C495A4D7F01FF6F5B5CA27190C7 +FC715AEF00F895C8FCAA0407B512C0BAFCA5C601F8C7120F83B3B3A6B6D8F807B612C0A5 +42547DD349>28 D<B712E0AB230B7F9F2C>45 D<151E153E15FE1403140F147FEB07FF00 +03B5FCB6FCA3EBF87FEAFC00C7FCB3B3B3A6007FB712FCA52E4E76CD42>49 +D<EC1FFE49B512F0010F14FC013FECFF804915E02701FF803F7F2703FC000713FCD807F0 +01017F48486D7FD81F806E138048C87E7013C0D87FE016E001F8806D16F000FF817F7013 +F8A56C5AA26C5A6C5AEA0380C914F05EA218E05E18C05E18804C13005F4C5A4C5A5F4B5B +4B5B4B5B94C7FCED0FFC4B5A4B5AED7FC04B5A4A90C8FCEC03FC4A5A4A4814F84A5A4A5A +4AC8FC02FEEC01F0495A495A495A5CD90F80140349C8FC013E1507017FB7FC90B812E05A +5A5A5A5A5A5AB9FC18C0A4354E7ACD42>I<913807FFC0027F13FC0103B67E010F15E090 +261FF80313F890267FC0007F01FEC7EA3FFE48488148486E138013FE486C6C6D13C08048 +17E080A66C5B18C06C5B6C90C75AD80038168090C8FC4C1300A24C5A5F4C5A4B5B4B13C0 +030F5BDB7FFEC7FC91387FFFF816C016FCEEFF80DA000313E09238007FF8EE3FFE707E70 +138018C07013E018F07013F8A218FC82A218FEA3EA03C0EA0FF0EA3FFC487EA2B5FCA218 +FCA25E18F8A26C4816F0495C4916E0D83FE04A13C06C485CD80FF04A1380D807FE91387F +FE003B03FFE003FFFC6C90B65A6C6C15E0010F92C7FC010114FCD9001F1380374F7BCD42 +>I<17FC1601A216031607160FA2161F163F167FA216FF5D5DA25D5D5D167F153E157E15 +FC15F8EC01F01403EC07E015C0EC0F80141FEC3F00143E5C14FC495A5C495A1307495A5C +49C7FC5B137E137C5B1201485A5B485A120F485A90C8FC123E127E5ABA1280A5C901FCC7 +FCAF021FB71280A5394F7CCE42>I<486C150601F0153E01FEEC01FED9FFF0133F91B65A +5F5F5F5F5F94C7FC16FC5E16E093C8FC15FC01F0138091CAFCAC913807FF80023F13F891 +B512FE01F36E7E9026FFFC0113E09139E0007FF891C76C7E496E7E01F86E7E5B70138049 +16C0C9FC18E08218F0A418F8A31203EA0FE0EA3FF8487EA212FF7FA218F0A25B5E6C4816 +E05B01C016C06CC85A18806C6C4A13007FD80FF04A5A6C6CECFFFCD803FE4913F02701FF +E00F5B6C6CB612806D92C7FC010F14F8010114C09026003FFCC8FC354F7ACD42>I<EA07 +E0EA1FF8EA3FFCEA7FFEA2B5FCA6EA7FFEA2EA3FFCEA1FF8EA07E0C7FCB3A3EA07E0EA1F +F8EA3FFCEA7FFEA2B5FCA6EA7FFEA2EA3FFCEA1FF8EA07E0103576B425>58 +D<932603FFF01407047F01FF5C0307B600E05B033F03F85B92B700FE5B02039126C003FF +5B020F01F8C7EA3FC1023F01C0EC0FE391B5C80003B5FC4901FC814949814901E082011F +498249498292CA7E4948834948835A4A83485B4885A2484984A2485B87A2485B87A25AA2 +98C8FC91CFFCA2B5FCAE7E067FB7128080A37E95C76C90C7FC807EA36C7FA26C7FA26C7F +7E806C7F137F6D7E816D6D93B5FC01077F6D01F85D6D7F6D01FF5D023F01E0EC0FEF020F +01FCEC3FE30203903AFFE001FF81020091B6C6FC033F03FC133F030703F0130FDB007F02 +801303040301F8CAFC595479D267>71 D<B81280A5D8000701F0C7FCB3B3B3B2B81280A5 +29527DD130>73 D<B812E0A5D8000F01E0CAFCB3B3A91AF8A419011AF0A51903A31907A2 +190F1AE0191FA2193F197F19FF60180760187F0503B5FCBB12C0A545527CD14F>76 +D<B600F84BB612FC818181A2D800076E91C7383FE00070EE0F80828214DF02CF7F02C77F +8202C37F14C102C0806F7F836F7F816F7F6F7F83816F7F6F80707F8482707F707F707F84 +82707F7080717F8583717F717F85717F83717F7114801AC07213E0847213F07213F81AFC +7213FE847213FF72148F1BCF7313EF857313FF85A285858585A286868686A286868686EB +1FF0B600FE177F1B3F1B1F1B0FA25E527CD167>78 D<B912FCF0FFE019FE737E1AE0D800 +0F01E0C7003F7F060313FC06007F737E7313807313C07313E0851BF0A21BF885A21BFCA9 +1BF8A3611BF0A21BE04F13C0614F13804F13004F5A060713F8063F5B92B812C097C7FC19 +F8198003E0CBFCB3AEB712FEA54E527CD15A>80 D<93381FFF800303B512FC033FECFFC0 +92B712F00207D9F80113FE021F903AC0003FFF804A48C700077FDAFFF8020113F049496E +7F49496F7E49496F7E49496F7E4990C96C7F4948707F4948707F01FF854849707F4A8248 +86A24849717E48864A83A2481B80A248497113C0A4481BE0A291CB7EA3B51AF0AF6C1BE0 +A36E5FA26C1BC0A36C1B806E5FA26C1B006E5F6C62A26C6DD903FC4A5A6CDB0FFF5D6E49 +EBC0016C4B01E05C6D6C90277E07F0035B6E9039F801F807902A3FFF01F000780F5B6D04 +7C5C6DD981E06D4890C7FC6D01E191381F7FFE010101F1EDFFF86DD9F9F06D5BDA3FFF16 +C06E6D013F5B02079027FE01FFFEC8FC020190B612F8DA003F4B141003071838DB001FEB +83F893C7EA03FC1C7885726C14F8F2C003F2F01F97B512F084A31CE085A27314C01C8085 +1C00735B735B735B735B9638003FC0556A79D263>I<B912E018FF19F019FE737ED80007 +01F0C714E0060F7F060313FC06007F737E737F8587737FA28785A287A863A26163636163 +4F90C8FC4F5A4F5A06035B060F13E095B5128092B748C9FC19F019C019F09226F0000713 +FC050013FF063F7F727F727F727F727FA2727FA28486A886A71D707513F8A2851C017301 +C013F0A273EBE003B86C6D9038F007E0739038FC1FC0070190B51280736C1400080F5BCE +13F85D537CD162>I<DA0FFE141C91B500F0133C010702FC137C011F02FF13FC017F15C1 +9026FFF00113E148903980001FFB4890C7EA07FFD807FC14014848804848153F171F4848 +150FA2007F1607491503A2170112FFA217007FA26D167CA27F7F6D93C7FC6C7E14C014F8 +ECFF806C14F8EDFFC06C15FC6CEDFF8017F06C16FC6C826C707E6C836D82011F82010782 +13016D6C81020781EC007F030380ED003F040314801600173F837113C0838312F883A383 +7EA319807EA26C5E19007F6D4B5A7F6D4B5A01FC4B5A6D151FD9FFC04A5AD97FF8ECFFE0 +28FE1FFF80075B010790B6C7FCD8FC0115FC486C6C14F048010F14C0489026007FFCC8FC +3A5479D249>I<003FBB12FCA59126C0007FEB000301FCC7ED003FD87FF0F00FFE491807 +49180349180190C81600A2007E1A7EA3007C1A3EA500FC1A3F481A1FA6C91700B3B3AC49 +B912C0A550517BD05B>I<EC3FFE0107B512E0011F14FC017F14FF2701FFC00F13C02703 +FE00037F486C01007F6E6D7E486D80707EA2707EA3707F6C5B6C90C7FC6C5AC9FCA60307 +B5FC0203B6FC147F0103B7FC011FEBF00F017F1300EBFFFC000313F04813C0485B4890C7 +FC5A5B485AF081F012FF5BA35EA26D5C127F6D5C003F03F713C36DD901E314E06CD9C007 +14FF00079026F01F8114C06C90B5C61480C602FC6D1300011F01F0EB3FFC01010180EB07 +F03C387CB642>97 D<913803FFE0023F13FE91B67E010315E0010F9038003FF8D93FFCEB +07FC4948497E4948131F4849497E485B485BA24890C7FC5A5B003F6F5A705A705A007F92 +C8FC5BA312FFAD127F7FA3123F7F6CEE0F80A26C6D141F18006C6D5C6C6D143E6C6D147E +6C6D5C6D6C495A6DB4EB07F0010F9038C01FE06D90B5128001014AC7FCD9003F13F80203 +138031387CB63A>99 D<943803FF80040FB5FCA5EE003F170FB3A4913803FF80023F13F8 +49B512FE0107ECFF8F011F9038C03FEF90273FFE0007B5FCD97FF8130149487F48498048 +4980484980488291C8FC5A5B123FA2127F5BA312FFAD127FA37F123FA3121F7F6C5E6C6D +5C5F6C6D91B5FC6C6D5B6C6D4914E0D97FFCD90FEFEBFF80D91FFFEB7F8F010790B5120F +010114FC6D6C13E00207010049C7FC41547CD249>I<913807FF80027F13F849B512FE01 +076E7E011F010313E0903A3FFC007FF0D97FF06D7E49486D7E4849130F48496D7E488248 +90C77E1880485A82003F17C0A3485A18E082A212FFA290B8FCA401FCCAFCA6127FA37F12 +3FA2EF03E06C7E17076C17C06C6D140F18806C6D141F6C6DEC3F006C6D147ED97FFC495A +D91FFFEB07F86D9038E03FF0010390B512C001005D023F01FCC7FC020113E033387CB63C +>I<ED1FF8913803FFFE020FEBFF80023F14C09139FFF83FE001039038E0FFF049138049 +010113F85BEB3FFEA2EB7FFCA26F13F0495AEE7FE0EE1F8093C7FCAEB712C0A5C601F8C8 +FCB3B3A7B612FEA52D547CD328>I<DA1FFE14FE49B539E007FF80010FDAFC1F13C0013F +DAFF7F13E090267FF807EBFF072701FFE001EBF07F48497E484990387FF83F91C7003F14 +C048EEFC1F489338FE070049021F90C7FCA2003F82A9001F5EA26D143F6C5E6C5E6E137F +6C6D495A6C6D485B6CD9F80713804890B6C8FCD803EF14FC01C114E02707C01FFEC9FC49 +CBFCA2487EA37FA27F13FC90B612FE6CEDFFF017FCEFFF806C8318F06C836C837F48B87E +1207D80FFCC700037F4848EC003F4848150F48486F138083485A83A56D5D007F18006D5D +003F5F6C6C4B5A01FE153FD807FFED7FF06C01C049485AC601FC011F1380013FB648C7FC +010F15F8010115C0D9000F01F8C8FC3B4F7CB542>I<EB3FF8B5FCA51203C6FCB3A4EE1F +FC93B57E030314E0030F14F892391FC07FFC92397E003FFE03F86D7EECF9F04B6D7FECFB +C0ECFF8092C76C7FA25CA25CA45CB3ACB6D8F807B612C0A542537CD249>I<133FEBFFC0 +487F487FA2487FA66C5BA26C5B6C5B013FC7FC90C8FCAEEB1FF8B5FCA512017EB3B3A6B6 +12F0A51C547CD324>I<EB3FF8B5FCA51203C6FCB3B3B3B1B612F8A51D537CD224>108 +D<D93FF0D91FF84AB47EB591B56C010F13F8030302E0013F13FE030F6E90B6FCDB3F8090 +27F803F80F7F922A7E007FFC07E0077F000302F890283FFE0F80037FC6D9F1F0011F4948 +7EDAF3E0DAFF3E814B153CDAF7805D92C76C496D7F14FF4A5EA24A5EA34A5EB3ADB6D8F8 +0FB66CB612F8A565367BB56E>I<D93FF0EB1FFCB591B57E030314E0030F14F892391FC0 +7FFC92397E003FFE000302F86D7EC6EBF1F04B6D7FECF3C0ECF78092C76C7F14FF5CA25C +A45CB3ACB6D8F807B612C0A542367CB549>I<913801FFC0023F13FE91B67E010315E001 +0F018013F8903A3FFC001FFED97FF0EB07FF49486D7F48496D7F48496D7F91C8127F4883 +488349153F001F83A2003F8349151FA2007F83A400FF1880AC007F1800A3003F5F6D153F +A2001F5FA26C6C4B5AA26C6D4A5A6C5F6C6D495B6C6D495B6D6C4990C7FCD93FFCEB1FFE +6DB46CB45A010790B512F0010115C0D9003F49C8FC020313E039387CB642>I<D93FF8EB +7FF0B50107B5FC031F14C0037F14F09126F9FF0013FCDAFFF8EB3FFF000302E0010F7FC6 +02806D7F92C76C7F4A824A804A6E7F85187F85A2183F85A4721380AD4E1300A44E5AA261 +18FF616E5C616E4A5B6E4A5B6F495B03E04990C7FC6FEB7FFE913AF9FE01FFF802F8B65A +033F14C0030749C8FC030013E093CAFCB1B612F8A5414D7DB549>I<90393FF001FCB590 +380FFF804B13E0037F13F09238FE1FF89138F1F83F00019138F07FFC6CEBF3E015C0ECF7 +80A2ECFF00EE3FF84AEB1FF0EE0FE093C7FC5CA45CB3ABB612FEA52E367DB535>114 +D<903903FFC00E011FEBFC1E90B6127E000315FE3907FE003FD80FF0130F484813034848 +1301491300127F90C8127EA248153EA27FA27F01F091C7FC13FCEBFF806C13FEECFFF06C +14FE6F7E6C15E06C816C15FC6C81C681133F010F15801301D9000F14C0EC003F030713E0 +150100F880167F6C153FA2161F7EA217C07E6D143F17807F6DEC7F0001F85C6DEB03FE90 +39FF801FFC486CB512F0D8F81F14C0D8F00791C7FC39E0007FF02B387CB634>I<147CA6 +14FCA41301A31303A21307A2130F131F133F137F13FF1203000F90B512FEB7FCA426007F +FCC8FCB3A9EE0F80ABEE1F006D7EA2011F143E806D6D5A6DEBC1F86DEBFFF001005C023F +1380DA03FEC7FC294D7ECB33>I<D93FF8913801FFC0B50207B5FCA50003ED001FC61607 +B3AE5FA35FA25F137F5F6D6C14F7DC01E713F06D6CD907C7EBFFC0903A0FFF801F876D90 +B51207010114FC6D6C13F0020701C091C7FC42377CB549>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fj ecrm0900 9 5 +/Fj 5 109 df<123C127E12FFA4127E123C08087A8715>46 D<EB7F803803FFF0380F80 +FC381C003E003F133F6D6C7E6E7EA26E7EEA1F00C7FCA4EB01FF131FEBFF873803FC07EA +0FF0EA1FC0EA3F80127F13004815C05AA3140FA26C131F6C133B3A3F8071F180391FC1E1 +FF2607FFC013003900FE003C22237DA126>97 D<EA03F012FFA312071203AEEC3F80ECFF +E09038F3C0F89038F7007E01FE7F49EB1F8049EB0FC05BED07E016F0A2150316F8AA16F0 +150716E0A2ED0FC07F6DEB1F8001ECEB3F0001CF137C90388381F8903801FFE0C76CC7FC +25357EB32B>I<EA03F012FFA312071203AEEC1FC0EC7FF09038F1E0FC9038F3807C9038 +F7007E13FE497FA25BA25BB3486CEB7F80B538C7FFFCA326347EB32B>104 +D<EA07E012FFA3120F1207B3B3A7EA0FF0B5FCA310347EB315>108 +D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fk ecbx0900 9 7 +/Fk 7 117 df<ED1F80A24B7EA24B7EA34B7EA24A7FA34A7FA24A7F15CFA2020F7F1587 +021F801503023F80EC3E01A2027E80EC7C0002FC804A137FA20101814A133F0103814A13 +1FA249B67EA24981A290271F8000077F91C77EA24982013E80017E82017C80A201FC8249 +157FB500F0013FB512F0A43C347DB343>65 D<EB7FFE0003B512E04814F8390FF00FFC39 +1FF803FF806E138016C0157F6C5A6C5AEA0180C8FCEC7FFF010FB5FC90B6FC0003EBF07F +000F1300EA1FF8485A485A485A5BA315FF7F007F5B6D4813E03A3FF80FBFFF000FB5121F +0003EBFC0F39007FE00728217EA02B>97 D<EA01FC12FFA4120F1207ADEC0FF8EC7FFF01 +FDB512C09039FFF01FF09138800FF84A6C7E496D7E496D7EA2178081A217C0A91780A25D +1700A26D495A6D495A6E485A9039F7E03FF001E1B512C0D9C07F90C7FC9038801FF02A34 +7DB331>I<903807FF80013F13F090B512FC3903FE01FE4848487EEA0FF8EA1FF0EA3FE0 +A2007F6D5A496C5A153000FF91C7FCA9127F7FA2003FEC07807F6C6C130F000FEC1F00D8 +07FE133E3903FF80FCC6EBFFF8013F13E0010790C7FC21217DA027>I<3901F81F8000FF +EB7FF0ECFFF89038F9E3FC9038FBC7FE380FFF876C1307A213FEEC03FCEC01F8EC006049 +1300B1B512F0A41F217EA024>114 D<9038FFE1C0000713FF5A383F803F387E000F1407 +5A14037EA26C6CC7FC13FCEBFFE06C13FC806CEBFF80000F14C06C14E0C6FC010F13F0EB +007F140F00F0130714037EA26C14E06C13076CEB0FC09038C01F8090B5120000F913FC38 +E03FE01C217DA023>I<133CA5137CA313FCA21201A212031207001FB51280B6FCA3D807 +FCC7FCB0EC03C0A79038FE078012033901FF0F006C13FEEB3FFCEB0FF01A2F7EAE22>I +E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fl ecrm1200 12 25 +/Fl 25 122 df<121EEA7F8012FF13C0A213E0A3127FEA1E601200A413E013C0A3120113 +80120313005A1206120E5A5A5A12600B1D78891B>44 D<14FF010713E090381F81F89038 +3E007C01FC133F4848EB1F8049130F4848EB07C04848EB03E0A2000F15F0491301001F15 +F8A2003F15FCA390C8FC4815FEA54815FFB3A46C15FEA56D1301003F15FCA3001F15F8A2 +6C6CEB03F0A36C6CEB07E0000315C06D130F6C6CEB1F806C6CEB3F00013E137C90381F81 +F8903807FFE0010090C7FC28447CC131>48 D<EB03FE90381FFFC0017F13F03901F80FFC +3903C001FE48486C7E000EC7EA7F8048EC3FC0ED1FE04815F00030140F007015F8006014 +07126CB415FC7F7F1503A46C4813076CC7FCC8FC16F8A2150F16F0151F16E0A2ED3FC0ED +7F8016005D5D4A5A4A5A4A5A5D4A5A4A5A4AC7FC147C5C5C495A495A495A49C7120C131E +5B013814185B5B485A4848143848C81230000E1570001FB612F0A25A5AB712E0A326427B +C131>50 D<EC07FCEC3FFF91B512C0903903FC03E0903907E000F0D91FC0133849C71258 +017EEB01FC01FE1303491307485A485AA24848EB03F8000FEC01F092C7FC485AA3485AA3 +127FA29038007F80903801FFF090380780FC39FF0E003E49EB1F8049EB0FC049EB07E013 +6001E0EB03F04914F8150116FC5BED00FEA390C812FFA47EA57F123FA216FE121F15016D +14FC120FED03F86C7EED07F06C6C14E06C6CEB0FC06C6CEB1F80017EEB3F0090383F80FE +90380FFFF8010313E00100138028447CC131>54 D<16C04B7EA34B7EA34B7EA34B7EA3ED +19FEA3ED30FFA203707FED607FA203E07FEDC03FA2020180ED801FA2DA03007F160FA202 +06801607A24A6D7EA34A6D7EA34A6D7EA20270810260147FA202E08191B7FCA249820280 +C7121FA249C87F170FA20106821707A2496F7EA3496F7EA3496F7EA201788313F8486C83 +D80FFF03037FB500E0027FEBFFC0A342477DC649>65 D<B8FC17E017FC00019039C00003 +FF6C6C4801007FEF3FC0717E717E717E84170384170184A760A21703601707604D5A4D5A +EF7FC04DC7FCEE03FEEE3FF091B65A17FC0280C7B47EEF1FC0EF0FF0717E717E717E717E +1980187F19C0A2183F19E0A8F07FC0A2198018FF4D1300A24D5AEF0FFC4D5AEF7FE04848 +6C903803FFC0B9C7FC17FC17C03B447CC345>I<B712FEEEFFE017F800019039C00007FE +6C6C48903800FF80EF3FC0EF0FF0717E717EEF00FE8484F03F80F01FC0A2F00FE019F018 +0719F8A2180319FCA3F001FEA419FFAD19FEA3180319FCA319F8180719F0180F19E0A2F0 +1FC0F03F80A2F07F0018FE4D5A4D5AEF0FF0EF3FE0EFFF8048486C010790C7FCB812FC17 +E04CC8FC40447CC34A>68 D<B56C933807FFFC6E5EA20001F1FE0026006FE0EE1BF8A3D9 +67F01633A2D963F81663A3D961FC16C3A3D960FEED0183A2027FED0303A36E6C1406A36E +6C140CA26E6C1418A36E6C1430A36E6C1460A26E6C14C0A36E6CEB0180A3037FEB0300A2 +92383F8006A36F6C5AA36F6C5AA26F6C5AA36F6C5AA36F6C5AA26FB45AA370C7FC13F0A2 +486C143ED80FFFEF0FFEB500F0011C0107B512FCA34E447BC359>77 +D<003FB912F8A3903BF0001FF8001F01806D481303003EC7150048187C0078183CA20070 +181CA30060180CA5481806A5C81600B3B3A54B7EED7FFE49B77EA33F447DC346>84 +D<B600C0010FB5FCA3000101E0C813F026007F80ED1F80F00F00A21806B3B3A7180E6D6C +150CA2181C131F6E1518010F163818306D6C1570606D6C14016D6C5D6D6CEC0780027F4A +C7FC6E6C131EDA1FE0137C913907FC03F00201B55A6E6C1380DB07FCC8FC40467CC349> +I<EB07FC90383FFF809038F80FE03903C003F048C66C7E000E6D7ED80FC0137E486C137F +6D6D7EA36F7EA26C5AEA0380C8FCA4EC0FFF49B5FC90380FFE1FEB3FC0EBFF00EA03FC48 +5A485A485A485A127F5B176048C7FCA3153FA36D137F007F14EF6D9038C7E0C0003F1301 +3A1FE00783F13B07F81E03FF802701FFFC0113003A001FE0007C2B2E7CAC31>97 +D<EC7F80903803FFF090380FC07C90383F000F01FCEB03804848EB01C00003140F4848EB +1FE049133F120F485AA2485AED1FC0007FEC070092C7FCA290C9FC5AAB7E7FA2123F1630 +7F001F15706C6C146016E06C6C14C06C6C13010001EC03806C6CEB0700013F131E90381F +C078903807FFF001001380242E7DAC2B>99 D<167FED3FFFA315018182B3EC7F80903803 +FFF090380FC07C90383F000E017E1307496D5AD803F87F48487F5B000F81485AA2485AA2 +127FA290C8FC5AAB7E7FA2123FA26C7EA2000F5D7F6C6C5B00035C6C6C9038077F806C6C +010E13C0013F011C13FE90380FC0F8903803FFE09026007F0013002F467DC436>I<EB01 +FE903807FFC090381F03F090387E00FC49137E48487F485A4848EB1F80000F15C049130F +121F484814E01507A2007F15F090C7FCA25AA390B6FCA290C9FCA67EA27FA2123F16306C +7E1670000F15606D14E06C6C14C0000314016C6CEB03806C6CEB0700013E131E90381F80 +F8903803FFE0010090C7FC242E7DAC2B>I<EE0F80D901FCEB7FE0903A0FFF81F0F09039 +3F07E3819039FC01FF033A01F800FE014848017E13E00007027FC7FC497F000F8149131F +001F81A9000F5D6D133F000792C7FC6D5B0003147E6C6C5B6D485A3903BF07E090380FFF +80260701FCC8FC90CAFCA25AA37F6C7E7F90B512F86C14FF16E06C15F86C6C8048B67E3A +07C0000FFF48481300003FC8EA3F80003E151F48ED0FC0A2481507A56C150F007C168000 +7E151F003E16006C153E6C6C5CD807E0495AD801F8EB07E0D8007FEB3F8090261FFFFEC7 +FC010113E02C427DAC31>103 D<EA01E0EA07F8A2487EA46C5AA2EA01E0C8FCADEA01FC +12FFA3120712031201B3B0487EB512F8A315437DC21C>105 D<EA01FC12FFA312071203 +1201B3B3B3A5487EB512F8A315457DC41C>108 D<3901FC01FE00FF903807FFC091381E +07F091383801F8000701707F0003EBE0002601FDC07F5C01FF147F91C7FCA25BA35BB3A8 +486CECFF80B5D8F83F13FEA32F2C7DAB36>110 D<EC7F80903803FFF090380FC0FC9038 +3E001F496D7E496D7E48486D7E48486D7E48486D7E000F81A24848147E003F157FA290C8 +7E481680A44816C0AA6C1680A26D147F003F1600A2001F157E6D14FE000F5D6D13010007 +5D6C6C495A6C6C495A6C6C495A013E49C7FC90381FC0FE903807FFF89038007F802A2E7D +AC31>I<3903F803F000FFEB1FFCEC3C3EEC707F0007EBE0FF3803F9C000015B13FBEC00 +7E153C01FF13005BA45BB3A748B4FCB512FEA3202C7DAB26>114 +D<90383FE0183901FFFC383907E01F78390F0003F8001E1301481300007C1478127800F8 +1438A21518A27EA27E6C6C13006C7E13FC383FFFE06C13FC6C13FF6C14C06C14E0C614F0 +011F13F81300EC0FFC140300C0EB01FE1400157E7E153EA27EA36C143C6C147C15786C14 +F86CEB01F039F38003E039F1F00F8039E07FFE0038C00FF01F2E7DAC26>I<1306A5130E +A4131EA3133E137EA213FE12011207001FB512F0B6FCA2C648C7FCB3A4150CAA017E131C +017F1318A26D133890381F8030ECC070903807E0E0903801FFC09038007F001E3E7EBC26 +>I<D801FC147F00FFEC3FFFA300071401000380000181B3A85EA35DA212006D5B017E90 +38077F80017F010E13C06D011C13FE90380FC078903803FFF09026007F8013002F2D7DAB +36>I<B539F001FFFCA3000790C7EA7FE06C48EC1F8000011600160E1200160C017F5CA2 +80013F5CA26E1370011F146080010F5CA2ECF00101075CA26D6C48C7FCA26E5A01011306 +A26D6C5AA214FF6E5AA215B8EC3FB015F06E5AA36E5AA26E5AA36EC8FC2E2C7EAA33>I< +B539F001FFFCA3000790C7EA7FE06C48EC1F8000011600160E0000150C6D141C6D1418A2 +6E1338013F1430A26D6C5BA26E13E0010F5CA26D6C485AA2ECF803010391C7FCA2903801 +FC06A2ECFE0E0100130CA2EC7F18A215B8EC3FB0A2EC1FE0A36E5AA26E5AA36EC8FCA214 +06A35CA25CA2123C007E5BB4FC5CA25CEAFE01387C0380D87007C9FCEA3C1EEA0FFCEA03 +F02E3F7EAA33>121 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fm ecbx1200 12 47 +/Fm 47 123 df<0118140C017C143E01FC147E48485C4848495A495C4848495A4848495A +001F140F90C75B003E4AC7FCA2003C141E007C143E0078143CA200F8147CA2481478D8F1 +F014F8D8F7FCEB7BFEB46CEB7FFF6D1580028014C0A36C80A36C806C496C13806C486D13 +006C486D5AD801F0EB00F82A2283C427>16 D<D807C0EB03E0D81FF0EB0FF8486C497E48 +6C497E486C497E6D1580A3028014C0A36C806C80D81FF7EB0FFBD807C7EB03E3D80007EB +0003010F1407A291C71380A249140F011E1500013E5CA249143E01FC147E49147C48485C +4848495A000714034848495A4848495A90C75B000C0206C7FC2A2281C427>I<ED0FFF4A +B512C0020F14F0027F80903A01FFF803FC499038C000FE010FEB00034948497E49485B5C +495A4C138001FF6E13005CA3705AEE01F893C8FCA74BB51280B9FCA5C69038E00003B3B0 +007FD9FFC1B6FCA538467EC53E>28 D<EA07C0EA1FF0EA3FF8EA7FFCEAFFFEA7EA7FFCEA +3FF8EA1FF0EA07C00F0F788E1F>46 D<EC3FF849B5FC010F14E0013F14F890397FF01FFC +9039FFC007FE4890380001FF48486D1380000716C049147F000F16E049143F001F16F0A2 +003F16F8A249141F007F16FCA600FF16FEB3A3007F16FCA56C6CEC3FF8A3001F16F0A200 +0F16E06D147F000716C06D14FF6C6C4913806C6D4813006C6D485A90397FF01FFC6DB55A +010F14E0010314809026003FF8C7FC2F427CC038>48 D<EC03C01407141F147FEB03FF13 +3FB6FCA413C3EA0003B3B3ADB712FCA5264177C038>I<ECFFE0010F13FE013F6D7E90B6 +12E0000315F82607FC0313FE3A0FE0007FFFD81F806D138048C7000F13C0488001C015E0 +01F07F00FF6E13F07F17F881A46C5A6C5A6C5AC9FC17F05DA217E05D17C04B13804B1300 +A2ED1FFC4B5A5E4B5A4B5A4A90C7FC4A5A4A5AEC0FF04A5AEC3F804AC7127814FE495A49 +4814F8D907E014F0495A495A49C8FC017C140149140348B7FC4816E05A5A5A5A5AB8FC17 +C0A42D417BC038>I<ECFFF0010713FF011F14C0017F14F049C66C7ED803F8EB3FFED807 +E06D7E81D80FF86D138013FE001F16C07FA66C5A6C4815806C485BC814005D5E4B5A4B5A +4B5A4A5B020F1380902607FFFEC7FC15F815FF16C090C713F0ED3FFCED0FFEEEFF80816F +13C017E0A26F13F0A217F8A3EA0FC0EA3FF0487EA2487EA217F0A25D17E06C5A494913C0 +5BD83F80491380D81FF0491300D80FFEEBFFFE6CB612F800015D6C6C14C0011F49C7FC01 +0113E02D427BC038>I<163FA25E5E5D5DA25D5D5D5DA25D92B5FCEC01F7EC03E7140715 +C7EC0F87EC1F07143E147E147C14F8EB01F0EB03E0130714C0EB0F80EB1F00133E5BA25B +485A485A485A120F5B48C7FC123E5A12FCB91280A5C8000F90C7FCAC027FB61280A53141 +7DC038>I<0007150301E0143F01FFEB07FF91B6FC5E5E5E5E5E16804BC7FC5D15E092C8 +FC01C0C9FCAAEC3FF001C1B5FC01C714C001DF14F09039FFE03FFC9138000FFE01FC6D7E +01F06D13804915C0497F6C4815E0C8FC6F13F0A317F8A4EA0F80EA3FE0487E12FF7FA317 +F05B5D6C4815E05B007EC74813C0123E003F4A1380D81FC0491300D80FF0495AD807FEEB +FFFC6CB612F0C65D013F1480010F01FCC7FC010113C02D427BC038>I<4AB47E021F13F0 +027F13FC49B6FC01079038807F8090390FFC001FD93FF014C04948137F4948EBFFE04849 +5A5A1400485A120FA248486D13C0EE7F80EE1E00003F92C7FCA25B127FA2EC07FC91381F +FF8000FF017F13E091B512F89039F9F01FFC9039FBC007FE9039FF8003FF17804A6C13C0 +5B6F13E0A24915F0A317F85BA4127FA5123FA217F07F121FA2000F4A13E0A26C6C15C06D +4913806C018014006C6D485A6C9038E01FFC6DB55A011F5C010714C0010191C7FC903800 +3FF02D427BC038>I<121E121F13FC90B712FEA45A17FC17F817F017E017C0A248168000 +7EC8EA3F00007C157E5E00785D15014B5A00F84A5A484A5A5E151FC848C7FC157E5DA24A +5A14035D14074A5AA2141F5D143FA2147F5D14FFA25BA35B92C8FCA35BA55BAA6D5A6D5A +6D5A2F447AC238>I<EA07C0EA1FF0EA3FF8EA7FFCEAFFFEA7EA7FFCEA3FF8EA1FF0EA07 +C0C7FCAEEA07C0EA1FF0EA3FF8EA7FFCEAFFFEA7EA7FFCEA3FF8EA1FF0EA07C00F2C78AB +1F>58 D<1A60F101F01907191FF17FC0953801FF00F007FCF01FF0F07FC04D48C7FCEF07 +FCEF3FF0EFFFC0040390C8FCEE0FFCEE3FE0EEFF80DB03FEC9FCED0FF8ED3FE0EDFF80DA +07FECAFCEC1FF8EC7FE0903801FF80D907FCCBFCEB1FF0EB7FC04848CCFCEA07FCEA1FF0 +EA7FC048CDFCA2EA7FC0EA1FF0EA07FCEA01FF38007FC0EB1FF0EB07FC903801FF809038 +007FE0EC1FF8EC07FE913800FF80ED3FE0ED0FF8ED03FE923800FF80EE3FE0EE0FFCEE03 +FF040013C0EF3FF0EF07FCEF01FF9438007FC0F01FF0F007FCF001FF9538007FC0F11FF0 +19071901F10060444277B957>60 D<126012F812FE6C7EEA3FE0EA0FF8EA03FEC66C7EEB +3FE0EB0FF8EB03FE903800FFC0EC3FF0EC0FFCEC03FF9138007FC0ED1FF0ED07FCED01FF +9238007FC0EE1FF0EE07FE933801FF809338007FE0EF1FF8EF03FE943800FF80F03FE0F0 +0FF8F003FE953800FF80F13FE0F10FF0A2F13FE0F1FF80953803FE00F00FF8F03FE0F0FF +80DD03FEC7FCEF1FF8EF7FE0933801FF80DC07FEC8FCEE1FF0EE7FC04B48C9FCED07FCED +1FF0ED7FC0DA03FFCAFCEC0FFCEC3FF0ECFFC0D903FECBFCEB0FF8EB3FE0EBFF80D803FE +CCFCEA0FF8EA3FE0EAFF8048CDFC12F81260444277B957>62 D<923803FFF0037FEBFF80 +0203B612F0020F15FC913A3FFC000FFFDAFFC0010013C0D903FEC8EA1FF0D907F0ED03F8 +D91FC0ED00FE4948167F017ECAEA1F8049717E4848717E49DAFF8013034848010F01F06D +7E4848013F01FC6D7E92B6FC4848489026C07F80137C49489026001FC0133C484948D907 +E0133E001E49486D6C131E003E49480101141F023F913800FFE0003C4A82007C017F1880 +007819074A5AA300F81AC04848491603AB6C6C7F12781B801A076E7E127C003C133F003E +6E1700021F4A5C001E6D6C5B001F6D6C49EBF01E6C6D6C011F143E6D6CD9C07F6D5A6C6C +6C90B5383FFFF8033FD9FC0F5B6C6C010FD9F0035B6C6C0100903980007F806D91CBFC6C +7E137E6D7E6D6CEF7FC0D907F0EE03FFD903FE043F1300902600FFC0913803FFF8DA3FFC +49B512C0020FB748C7FC020316E0DA007F02FCC8FC030349C9FC4A477AC557>64 +D<EE1F80A24C7EA24C7EA34C7EA24B7FA34B7FA24B7FA34B7F169F031F80161F82033F80 +ED3E07037E80157C8203FC804B7E02018115F0820203814B137F0207815D173F020F814B +7F021F8292C77EA24A82023E80027E82027FB7FCA291B87EA2498302F0C8FCA20103834A +157F0107834A153FA249488284011F8491C97E4984133E017E82B6020FB612F0A54C457C +C455>I<B9FC18F018FE727E19E026003FFCC700077F05017F716C7E727E727EA2721380 +A37213C0A74E1380A24E1300A24E5A4E5A4E5A4D5B05075B94B5128091B700FCC7FC18F0 +18FF19E002FCC7000113F8716C7EF01FFE727E7213801AC07213E0A27213F0A31AF8A71A +F0A2601AE0604E13C0604E138095B5120005075BBA12F86119C04EC7FC18E045447CC350 +>I<DCFFF01470031F01FF14F04AB6EAE0010207EDF803023FEDFE0791B539E001FF0F49 +49C7EA3F9F010701F0EC0FFF4901C0804990C87E4948814948814948167F4849163F4849 +161F5A4A160F485B19074890CAFC19035A5BA2007F1801A34994C7FC12FFAE127F7F1AF0 +A2123FA27F6C18011AE06C7F19036C6D17C06E16077E6C6DEE0F806C6DEE1F006D6C5E6D +6C167E6D6C6C5D6D6D4A5A6D01F0EC07F0010101FEEC1FE06D903AFFF001FF80023F90B6 +C7FC020715FC020115F0DA001F1480030001F8C8FC44467AC451>I<B9FC18F018FE727E +19E026003FFEC7001F13F805017F9438003FFF060F7F727F727F727F84737E737EA2737E +A2737EA21B80A2851BC0A51BE0AD1BC0A51B8061A21B006162193F624F5A19FF624E5B06 +075B4E5B063F90C7FC4DB45A050F13F8BA5A19C04EC8FC18F095C9FC4B447CC356>I<B7 +12E0A5D8001F90C7FCB3B3B3A4B712E0A523447DC32A>73 D<B500FE067FB512806E95B6 +FCA26F5EA2D8003F50C7FC013D6DEE03DFA2013C6DEE079FA26E6CEE0F1FA26E6C161EA2 +6E6C163CA36E6C1678A26E6C16F0A26E6DEC01E0A26E6DEC03C0A36E6DEC0780A26F6CEC +0F00A26F6C141EA26F6C5CA36F6C5CA26F6C5CA26F6D485AA26F6D485AA26F6D485AA370 +6C48C7FCA293383FF81EA2706C5AA2706C5AA3706C5AA2705BA2705BA2705BA2B6057FB6 +128071C7FCA2173E171C61447CC36A>77 D<923807FFC092B512FE0207ECFFC0021F15F0 +91267FFE0013FC902601FFF0EB1FFF01070180010313C04990C76C7FD91FFC6E6C7E4948 +6F7E49486F7E01FF8348496F7E48496F1380A248496F13C0A24890C96C13E0A24819F049 +82003F19F8A3007F19FC49177FA400FF19FEAD007F19FC6D17FFA3003F19F8A26D5E6C19 +F0A26E5D6C19E0A26C6D4B13C06C19806E5D6C6D4B13006C6D4B5A6D6C4B5A6D6C4B5A6D +6C4A5B6D01C001075B6D01F0011F5B010101FE90B5C7FC6D90B65A023F15F8020715C002 +004AC8FC030713C047467AC454>79 D<DAFFE0131C010701FE133C013F9038FF807C90B6 +EAE0FC4815F9489038801FFF3907FC00014848EB007F4848143F4848140F491407007F15 +035B1601160012FF177CA27FA26D153C7F7F6D92C7FC6C7EEBFFE014FE6CEBFFF015FF6C +15E016FC6C816C6F7E6C826C826C6C81011F810107811300020F80140003077FED007F82 +040F1380828212F082A282A27EA218007EA26C5D6C5E6D14036D5D6D140701F84A5A01FF +EC3FF002F8EBFFE0486CB65AD8FC1F92C7FCD8F80714FC48C614F0480107138031467AC4 +3E>83 D<007FBA12E0BB12F0A46C19E04406776757>95 D<903801FFE0011F13FE017F6D +7E48B612E03A03FE007FF84848EB1FFC6D6D7E486C6D7EA26F7FA36F7F6C5A6C5AEA00F0 +90C7FCA40203B5FC91B6FC1307013F13F19038FFFC01000313E0481380381FFE00485A5B +127F5B12FF5BA35DA26D5B6C6C5B4B13F0D83FFE013EEBFFC03A1FFF80FC7F0007EBFFF8 +6CECE01FC66CEB8007D90FFCC9FC322F7DAD36>97 D<EB7FC0B5FCA512037EB1ED0FF892 +B57E02C314E002CF14F89139DFC03FFC9139FF000FFE02FCEB03FF4A6D13804A15C04A6D +13E05CEF7FF0A218F8173FA318FCAC18F8A2177F18F0A3EFFFE06E15C06E5B6E49138002 +7C491300496C495A903AFC1FC07FFC496CB512F0D9F00314C049C691C7FCC8EA1FF03646 +7DC43E>I<EC3FFC49B512C0010F14F0013F14FC90397FF003FE9039FFC001FF0003495A +48494813805B120F485AA2485A6F1300007F6E5AED00784991C7FCA212FFAC6C7EA3123F +6DEC03C0A26C6C1407000F16806D140F6C6DEB1F006C6D133E6C01F05B3A007FFC03F86D +B55A010F14C0010391C7FC9038003FF82A2F7CAD32>I<EE03FEED07FFA5ED001F160FB1 +EC3FE0903803FFFC010FEBFF8F013F14CF9039FFF807FF48EBC00148903880007F4890C7 +123F4848141F49140F121F485AA3127F5BA212FFAC127FA37F123FA26C6C141FA26C6C14 +3F0007157F6C6C91B5FC6CD9C00314FC6C9038F01FEF6DB5128F011FEBFE0F010713F890 +26007FC0EBF80036467CC43E>I<EC3FF80103B57E010F14E0013F8090397FF83FF89039 +FFC007FC48496C7E48496C7E48486D1380485A001FED7FC05B003FED3FE0A2127F5B17F0 +161F12FFA290B7FCA401F0C9FCA5127FA27FA2123F17F06C7E16016C6C15E06C6C14036C +6DEB07C06C6DEB0F806C01F0EB3F0090397FFE01FE011FB55A010714F0010114C0902600 +1FFEC7FC2C2F7DAD33>I<EDFF80020F13E0027F13F049B512F849EB8FFC90390FFE0FFE +90381FFC1F14F8133FEB7FF0A2ED0FFCEBFFE0ED03F0ED00C01600ABB612F8A5C601E0C7 +FCB3B0007FEBFFE0A527467DC522>I<DAFFE0137E010F9039FE03FF80013FEBFF8F90B8 +12C048D9C07F133F489038001FF84848EB0FFC4848903907FE1F80001F9238FF0F00496D +90C7FCA2003F82A8001F93C7FCA26D5B000F5D6C6C495A6C6C495A6C9038C07FF04890B5 +5A1680D8078F49C8FC018013E0000F90CAFCA47F7F7F90B612C016FC6CEDFF8017E06C82 +6C16FC7E000382000F82D81FF0C77ED83FC014074848020113808248C9FC177FA46D15FF +007F17006D5C6C6C4A5A6C6C4A5AD80FFEEC3FF83B07FFC001FFF0000190B612C06C6C92 +C7FC010F14F8D9007F90C8FC32427DAC38>I<EB7FC0B5FCA512037EB1ED07FE92383FFF +8092B512E002C114F89139C7F03FFC9138CF801F9139DF000FFE14DE14FC4A6D7E5CA25C +A35CB3A7B60083B512FEA537457CC43E>I<137C48B4FC4813804813C0A24813E0A56C13 +C0A26C13806C1300EA007C90C7FCAAEB7FC0EA7FFFA512037EB3AFB6FCA518467CC520> +I<EB7FC0B5FCA512037EB3B3B3A3B61280A519457CC420>108 D<90277F8007FEEC0FFC +B590263FFFC090387FFF8092B5D8F001B512E002816E4880913D87F01FFC0FE03FF8913D +8FC00FFE1F801FFC0003D99F009026FF3E007F6C019E6D013C130F02BC5D02F86D496D7E +A24A5D4A5DA34A5DB3A7B60081B60003B512FEA5572D7CAC5E>I<90397F8007FEB59038 +3FFF8092B512E0028114F8913987F03FFC91388F801F000390399F000FFE6C139E14BC02 +F86D7E5CA25CA35CB3A7B60083B512FEA5372D7CAC3E>I<EC1FFC49B512C0010714F001 +1F14FC90397FF80FFF9026FFC0017F48496C7F4848C7EA3FE000078248486E7E49140F00 +1F82A2003F82491407007F82A400FF1780AA007F1700A46C6C4A5AA2001F5E6D141F000F +5E6C6C4A5AA26C6C6CEBFFE06C6D485B27007FF80F90C7FC6DB55A010F14F8010114C090 +26001FFCC8FC312F7DAD38>I<90397FC00FF8B590B57E02C314E002CF14F89139DFC03F +FC9139FF001FFE000301FCEB07FF6C496D13804A15C04A6D13E05C7013F0A2EF7FF8A4EF +3FFCACEF7FF8A318F017FFA24C13E06E15C06E5B6E4913806E4913006E495A9139DFC07F +FC02CFB512F002C314C002C091C7FCED1FF092C9FCADB67EA536407DAC3E>I<DA3FE013 +1E902603FFFC133E010F01FF137E013F1480903AFFF80FE0FE489038E003F148EBC00148 +90388000FB4890C7127F49143F001F151F485A160F5B127FA3485AAC6C7EA46C7EA26C6C +141F163F6C6C147F6C15FF6C6D5A6C9038E003EF6C9038F01FCF6DB5128F011FEBFE0F01 +0313F89038007FC091C7FCAD0307B512FCA536407CAC3B>I<90387F807FB53881FFE002 +8313F0028F13F8ED8FFC91389F1FFE000313BE6C13BC14F8A214F0ED0FFC9138E007F8ED +01E092C7FCA35CB3A5B612E0A5272D7DAC2E>I<90391FFC038090B51287000314FF120F +381FF003383FC00049133F48C7121F127E00FE140FA215077EA27F01E090C7FC13FE387F +FFF014FF6C14C015F06C14FC6C800003806C15806C7E010F14C0EB003F020313E0140000 +F0143FA26C141F150FA27EA26C15C06C141FA26DEB3F8001E0EB7F009038F803FE90B55A +00FC5CD8F03F13E026E007FEC7FC232F7CAD2C>I<EB01E0A51303A41307A2130FA2131F +A2133F137F13FF1203000F90B51280B7FCA4C601E0C7FCB3A3ED01E0A9150302F013C013 +7F150790393FF80F8090391FFC1F006DB5FC6D13FC01015B9038003FE023407EBE2C>I< +D97FC049B4FCB50103B5FCA50003EC000F6C81B3A85EA25EA25E7E6E491380017FD901F7 +13FE9138F807E76DB512C7010F1407010313FE9026007FF0EBFC00372E7CAC3E>I<B690 +3803FFFCA5000101E09038003E006C163C80017F5D8017F8013F5D6E1301011F5D6E1303 +010F5D6E13076D5DED800F6D92C7FC15C05E6DEBE01E163E6D143CEDF07C027F1378EDF8 +F8023F5B15FD021F5B15FF6E5BA36E5BA26E90C8FCA26E5AA26E5AA21578362C7EAB3B> +I<B500FE90383FFFF0A5C601F0903803E0006D6C495A6D6C495A011F4AC7FC6E5B6D6C13 +7E6DEB807C6D6D5A6DEBC1F0EDE3E06DEBF7C06EB45A806E90C8FC5D6E7E6E7F6E7FA24A +7F4A7F8291381F3FFCEC3E1F027C7F4A6C7E49486C7F01036D7F49487E02C08049486C7F +49C76C7E013E6E7E017E141FB500E090B512FCA5362C7EAB3B>120 +D<001FB71280A49026FC001F130001E0495A5B49495A90C7485A48495B123E4A5B4A5B00 +3C495BA24A90C7FC4A5A4A5AC7FC4A5A495B495BA2495B499038800780491300A2495A49 +48130F49481400A2485B48495B485BA248495B4890C75A48485C15034848EB1FFEB7FCA4 +292C7DAB32>122 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fn ecrm1728 17.28 8 +/Fn 8 117 df<B912F018FF19E019F8C601FCC8EA7FFED93FF892380FFF80011F04017F +9538007FF0F11FF8737EF103FE737E737F747E747E747E1A0F87747E1A0387747EA27413 +80A2F37FC0A21CE01B3FA21CF0A21B1F1CF8A31CFCA21B0FA41CFEAF1CFCA51B1F1CF8A4 +F33FF0A21CE0A21B7F1CC01BFF1C80A2501300A2505A505AA2505A505A505A505A1AFF4F +5B4F90C7FCF107FCF11FF8F17FF0953801FFC0013F04075BD9FFFCDB7FFEC8FCBA12F819 +E096C9FC18F0576278E167>68 D<BB12FCA4C601FCC8120FD93FF89238007FFE011F171F +190719031900A21A7E1A3EA21A1EA21A1F86A486A6F20380A318E0A297C7FCA61701A417 +031707170F171F17FF91B7FCA402F8C7FC171F170F170717031701A41700A895C9FCB3A5 +80133F90B57EB712E0A4496278E158>70 D<EC3FE0903803FFFE010F6D7E90393FC03FE0 +90397C000FF801F0EB03FC48486D7E48486D7E48486E7E48C86C7E7F01F06E7E487E6D6E +7EA3707EA36C5AEA03E0C9FCA6167FED7FFF020FB5FC91387FF807903801FF80903807FC +00EB1FF0EB7FC0495AD803FEC7FC485A120F5B485A485AA24848EE01C0A312FF5BA2160F +A3161F6D141B007F153B16736D17806C6C9138E1FC03001FEC03C16C6C903A0780FE0700 +D807FE49486C5A2701FF807CEB7FFE6C6CB4486D5A011F01E06D5A010390C7EA07E03A41 +79BF43>97 D<ED1FE0EDFFF8020313FE91380FF03F91391FC01F8091383F807F91397F00 +FFC014FE1301495A5C0107EC7F80A24948EB1E0093C7FCA2495AB3A5B712E0A426001FE0 +C8FCB3B3B0497EEB7FFC003FB512FEA42A657DE429>102 D<1378EA01FE487E487FA66C +90C7FC6C5AEA007890C8FCB3A2EB0780EA0FFFB5FCA41203C6FCA2137FB3B3AC497E487F +B61280A4195F7BDE25>105 D<010FEB07F8D80FFFEB1FFEB590387FFF809238F81FC091 +3801E03F913903C07FE00003EB0780C6EB0F00140E6D5A0218EB3FC00238EB1F800230EB +0600027090C7FCA2146014E0A25CA55CB3B0497E4813F0B612F8A42B3F7BBE34>114 +D<9138FFC003010FEBF807017FEBFE0F3A01FF003F9FD803F0EB07DF48486DB4FCD80F80 +1300001F8148C8FC003E81007E81127C00FC81A4827EA27E7F6C7E6D91C7FC13F8EA3FFE +381FFFE06C13FF15F0000314FE6C6E7E6C6C14E0011F14F801078001008002077FDA003F +13801507030113C0ED007F00E0ED3FE0161F17F06C150F1607A36C1503A37EA26C16E016 +077E17C06D140F6D15806D141FD8FDF0EC3F00D8F8F8147E017C495A3AF01F801FF06DB5 +12C0D8E00391C7FC39C0007FF02C417CBF35>I<1470A714F0A51301A31303A21307A213 +0FA2131F133F137F13FF1203000F90B6FCB8FCA326000FF0C8FCB3AEEE01C0AE6D6CEB03 +80A316076D6C14005E6D6C130E6D6C131E6E6C5A91383FE0F86EB45A020713C0020090C7 +FC2A597ED734>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fo ecbx1728 17.28 18 +/Fo 18 117 df<BB7E1AFCF2FFC01BF01BFED8000191C8001F6D7E070014E0081F7F0807 +13FC08017F747F093F7F757F757F757F757F757F757FA2767E1E80881EC0881EE0881EF0 +A2881EF8A31EFC88A31EFEA61EFFB01EFEA61EFCA2641EF8A31EF064A21EE0641EC0641E +80521300A2525A515B515BA2515B515B093F5B515B504848C7FC08075B081F5B97B512E0 +070F1480BC48C8FC1BF81BC008FCC9FC1A8068627BE177>68 D<942603FFF8151C94B66C +143C040F03F0147C047F03FC14FC0303B81301030FDAC00113C0033F01F8C7381FF00392 +B500C0913807F807020349C83801FE0F020F01F89238007F1F4A01E0EE3FBF4A49EE0FFF +91B5CA7E494983494983494983495B4949187F4B183F491A1F495B90B5CC120FA2484919 +075A4A19035A4A19015AA24A19005AA348491A7CA35A9AC8FCA35CA2B5FCB07EA26E043F +B81280A47E96C7000701FCC7FCA26C7FA37E80A27E807E807E6C7FA26D7F6D7F7F816D7F +6D6D5F6D7F6D6D5F6D6D7E023F6D5E6E01F05E6E6DEEFE7F020301FF923801FC3F020002 +C0913807F80F033F01FC91381FF007030F903BFFE001FFC001030391B6EA8000DB007F4B +C7123C040F03F8140C040003C091C8FC050301F8CBFC696677E37A>71 +D<BA12E0F1FF801AF81AFF1BC0D8000191C7000114F0DE000F13FC070313FF070080083F +7F747F747F747F747FA2747F88A28986A389A865A35091C8FCA26462646462505B505B50 +138097B5C9FC070313FC070F5B4EB512C093B8CAFC1AF81AC01AF893C7000713FE06006D +7E073F7F7313F007077F737F87737F85888688A2747FAA88A91F707614F8A286A2746D13 +011FF086746D13037614E0B800FE6EED07C0746CEBC00F759038F07F80090F90B5120009 +035CCF6C13F80A0313E06D647BE173>82 D<001FBD12F0A59126F8000191C7123F4801C0 +060713F849C71700491A7F01F01A1F491A0F491A07A2491A03A290C81801A2007EF300FC +A4007C1C7CA7481C3EA5C91900B3B3B3A5023FB912F8A55F617AE06C>84 +D<913803FFF0027F13FF0103B612E0010F15F890263FFC0013FED97FC090381FFF8049C7 +6C7F4801C06D7F486D6D7F6E6D7F48836E7F84177F84A36C496E7FA26C5B6C5B013FC8FC +90C9FCA75F0307B6FC4AB7FC141F91B5EAF03F0103EBFE00010F13F0013F1380D9FFFEC7 +FC485B485B485B485B485B485BA24890C8FC1A7CA2485AA35FA394B5FC7F6C5D6EEB03DF +6CDB07CFEBC0F86C6DEB0F8F6C6DD91F07EBF3F06C01F8017E14FF6C9027FE01FC0314E0 +C690B5D8F00114C0013F9126C0007F1380010791C7383FFE009026003FF8EC07F846437B +C14D>97 D<903807FF80B6FCA5C6FC7F7FB3A9933801FFE0041F13FE047FEBFFC00381B6 +12F0922687FC0113FC923A9FE0003FFEDBBF8090380FFF8003FEC76C7F4B6E7F4B6E7F4B +6E7F4B824B157F4B82737EA21B80851BC0A31BE085A41BF0AE1BE0A44F13C0A31B80A24F +1300A262197F6F5E6F4B5A4E5B6F4A5BDAFCF84A5BDAF87E4A5B4A6C4A90C7FC9126E01F +C0EB7FFC913BC00FF803FFF8DA8003B612E091C71580013E023F01FCC8FC90C800031380 +4C657CE356>I<ED1FFF4AB512F8020F14FF027F15C0902701FFF80013F04901E0EB0FF8 +010F0180EB03FC4990C7EA0FFE49484A7E49485C4948168048495C5A5C5A485BA2487013 +005C48705A715AEF03F04893C8FC91CBFCA4B5FCAE7EA280A27EA36C7FF003E07E6E1507 +6C18C06E150F6C18806C6D151F6C6DED3F006D6C157E6D6C15FE6D6D495A6D6D495A6D01 +F0EB0FE0010101FEEB7FC06D6CB6C7FC021F14FC020314E09126001FFEC8FC3B437BC145 +>I<ED3FFE0203B512E0021F14FC027F14FF902701FFF80F13C00107D9C0037F4990C77F +49486E7E49486E7E49486E7E49486E7E5A48496E13805A4A16C0488219E0485B834818F0 +A34890C8FCA27113F8A3B5FCA391B8FCA491CBFCA67EA4807EA27E19F8806C17016C18F0 +806C17036C6DED07E06E16C06C170F6D6CED1F806D6CED3F006D6C6C14FE01076DEB03FC +6D01F8EB0FF8010001FFEB7FE0023F90B51280020F4AC7FC020114F8DA000F13803D437C +C146>101 D<EEFFE0031F13FC92B6FC02031580020F9038E03FC04A903800FFE091267F +FE0113F04A485A49494813F84913F04913E0A25B15C05B7013F04913807013E09338007F +80EF1E0094C7FCB1B8FCA5D8003F0180C8FCB3B3B2B712F8A535657CE42F>I<F13F8091 +2601FFF0903801FFE0021F01FF010713F091B6D8E01F13F801039238F87FCF010F903BC0 +7FFEFC0FFC903B1FFE000FFFF0D97FFC6DEBE01F49486D140F48496D13F01AF848496DEB +F807489438FC01E096C7FC48496E7EA44883A96C5FA46C6D4A5AA26C5F6C6D495BA26C6D +495B6D6C495B6D6C4990C8FC903A7FFFC07FFE017B90B512F801F015E0021F91C9FC0001 +010113F049CCFC1203A27FA37FA27F7F6D7E91B612FCEFFFE06C17FCF0FF806C18E0856D +17FC6D836D837F017F188048BA12C000070180C712074848C96C13E04848160F48481603 +4982007F19F084485A197FA56D17FF007F19E0A26D5E6C6C4C13C0001F19806D5E6C6C4C +1300000301C0ED3FFC6C01F0EDFFF826007FFC020313E090261FFFE0017F1380010790B6 +48C7FC010116F8D9001F1580DA007F01E0C8FC46607CC14D>I<EB0FE0EB3FF8497E497E +487FA24880A76C91C7FCA26C5B6D5A6D5AEB0FE090C9FCB1903807FF80007FB5FCA5C6FC +7F7FB3B3B0B712C0A522657CE42A>105 D<903807FF80B6FCA5C6FC7F7FB3B3B3B3AFB7 +12E0A523647CE32A>108 D<D90FFFEC7FF8B60103B5FC040F14E0043F80DC7F0113FC92 +2601F8007FC6DA03E06D7E6D49487F6D49488193C77E031E825D153803788003708215F0 +5DA35DA35DB3B3A2B7D8E03FB612F8A54D417BC056>110 D<92381FFF804AB512F8020F +14FF023F15C09126FFFC0313F001039039E0007FFC490180EB1FFED91FFEC73807FF8049 +486E7F49486E7F49486E7F48496F7EA248496F7E4884A248496F7EA2481980A24819C091 +C97EA24819E0A5B518F0AD6C19E0A46C6D4B13C0A36C1980A26C6D4B1300A26C606E157F +6C606C6D4B5A6C606D6C4A5B6D6C4A5B6D6C4A5B6D6C6C011F90C7FC010301E0EB7FFC6D +9039FC03FFF86D6CB612E0020F92C8FC020114F8DA001F138044437CC14D>I<903B07FF +8001FFE0B6011F13FE047FEBFFC00381B612F0922687FC0313FC923A9FE0007FFEC6DABF +806D6C7E6D01FEC7000F7F6D496E7F4B824B6E7F4B6E7F4B804B82737EA21B80851BC0A2 +851BE0A4851BF0AE4F13E0A41BC061A21B80A24F1300A24F5AA26F4A5B6F4A5B626F4A5B +6F4A5B03FE4A5B03BF027F90C7FCDB9FC0EBFFFC92268FF8075B0383B612E00380158004 +3F01FCC8FC0403138093CBFCB3A4B712E0A54C5D7CC056>I<D90FFFEB07F8B6EB3FFF4C +13804BB512E0923903F83FF0923907E07FF8C691380F80FF6D020113FC6D131E153E153C +1578A21570DBF00013F8EF7FF04BEB3FE0EF0F8094C7FC5DA65DB3B1B712F8A536417DC0 +3E>114 D<DA7FFC131C0107B5EAC03C011FECF0FC90B612FD489038C003FFD807FEC712 +7FD80FF8143F49140F4848140748481403A248481401A2160012FFA26D157CA27F7F7F6D +92C7FCEBFF806C13F0ECFFC015FE6CECFFC016F86C15FE6C6F7E6C826C826C826C82013F +81010F81010181EB003F02011580EC000F1500041F13C000F88182826C8182A26C167FA3 +7E18807F17FF6D16007F6D4A5A7F6D4A5A6DEC0FF86D6C495A3BFE1FF001FFE0486CB612 +80D8F8034AC7FC48C614F048010F90C8FC32437BC13D>I<EC07C0A6140FA5141FA3143F +A2147FA214FF5BA25B5B5B5B137F48B5FC000F91B512F8B8FCA4D8001F01C0C7FCB3B017 +1FAD6D153E81A26D157C816D15F86D7F6D9038FC01F091397FFF07E06EEBFFC0020F1480 +0203EBFE009138003FF8305C7DDA3C>I E +%EndDVIPSBitmapFont +end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin +%%PaperSize: A4 + +%%EndSetup +%%Page: 1 1 +1 0 bop 290 639 a Fo(Genealogical)56 b(Represen)l(tation)e(of)f(T)-13 +b(rees)52 b(in)g(Databases)1686 822 y Fn(First)46 b(Draft)1247 +1063 y Fm(Miguel)36 b(Sofer)i(<mig@utdt.edu>)1359 1179 +y Fl(Univ)m(ersidad)33 b(T)-8 b(orcuato)33 b(Di)f(T)-8 +b(ella)1728 1295 y(Buenos)33 b(Aires)1797 1411 y(Argen)m(tina)1746 +1606 y(Ma)m(y)h(6,)e(2000)1839 1905 y Fk(Abstract)441 +2035 y Fj(blah)25 b(blah)h(.)13 b(.)g(.)118 2310 y Fi(1)131 +b(In)l(tro)t(duction)118 2491 y Fh(T)-7 b(rees)28 b(are)h(a)g(v)n(ery)f +(frequen)n(t)h(data)f(structure.)41 b(They)30 b(are)e(the)h(natural)g +(represen)n(tation)e(for)i(instance)g(for)f(organiza-)118 +2591 y(tional)f(c)n(harts,)g(threaded)g(discussion)g(groups,)f(some)h +(bills)g(of)h(materials,)e(.)14 b(.)g(.)243 2691 y(A)n(t)28 +b(least)f(t)n(w)n(o)f(alternativ)n(e)h(represen)n(tations)e(for)i +(trees)g(in)h(RDBMs)g(are)e(kno)n(wn)h(and)h(used:)220 +2857 y(1.)41 b Fg(P)m(oin)m(ters:)k Fh(a)31 b(\034eld)h(in)h(the)f(c)n +(hild)g(record)e(references)h(the)h(paren)n(t)f(no)r(de.)50 +b(This)32 b(seems)g(to)f(b)r(e)i(the)f(canonical)326 +2956 y(represen)n(tation.)38 b(Some)29 b(DB)g(engines)f(pro)n(vide)g +(sp)r(ecial)g(SQL)g(extensions)g(to)h(simplify)g(tree)g(searc)n(hes;)e +(Oracle)326 3056 y(tree)d(extensions)g(are)g(an)h(example)f(\(see)h +(for)f(instance)g([1]\);)i(DB2's)f(WITH)g(can)f(b)r(e)i(used)e(for)h +(this)g(purp)r(ose)f(to)r(o)326 3156 y(\(see)j([3],)g(pp)h(139-162\).) +220 3322 y(2.)41 b Fg(Nested)35 b(Sets:)43 b Fh(t)n(w)n(o)30 +b(n)n(umeric)h(\034elds)g(in)g(ev)n(ery)f(no)r(de)h(record)f(co)r(de)h +(the)g(tree)g(structure.)47 b(I)31 b(can't)g(pro)n(vide)f(a)326 +3421 y(b)r(etter)e(or)e(briefer)h(description)g(of)h(this)g(metho)r(d)g +(than)f(the)h(four)f(articles)g([2].)118 3587 y(These)g(t)n(w)n(o)g +(metho)r(ds)h(o\033er)f(di\033eren)n(t)h(adv)-5 b(an)n(tages)25 +b(and)j(disadv)-5 b(an)n(tages:)243 3753 y Ff(\017)41 +b Fh(P)n(oin)n(ters)30 b(are)g(extremely)g(e\036cien)n(t)h(for)f(no)r +(de)h(insertion)f(and/or)g(deletion,)h(but)h(require)e(recursiv)n(e)f +(table)i(ac-)326 3853 y(cesses)e(to)h(searc)n(h)f(the)h(tree)g(\(I)h +(do)f(not)g(kno)n(w)f(the)i(implemen)n(tation)f(details)g(of)g(the)h +(Oracle)e(tree)g(extensions,)326 3953 y(whic)n(h)e(as)g(far)g(as)g(I)g +(kno)n(w)g(ma)n(y)g(solv)n(e)f(this)i(problem)f(in)n(ternally;)g(they)g +(de\034nitely)h(solv)n(e)f(it)g(for)g(the)h(end)g(user\).)243 +4119 y Ff(\017)41 b Fh(Nested)30 b(sets)g(are)f(v)n(ery)f(e\036cien)n +(t)i(for)g(tree)f(searc)n(hes,)g(but)i(are)e(rather)f(exp)r(ensiv)n(e)i +(for)f(no)r(de)h(insertion)f(and/or)326 4218 y(deletion:)37 +b(they)27 b(require)g(up)r(dating)g(p)r(oten)n(tially)h(man)n(y)f(no)r +(des.)243 4384 y(W)-7 b(e)30 b(prop)r(ose)f(here)h(a)g(di\033eren)n(t)h +(represen)n(tation,)e(based)g(on)i(no)r(de)f(iden)n(ti\034ers)g(whic)n +(h)g(are)f(\020genealogical)f(iden)n(ti-)118 4484 y(\034ers\021:)44 +b(they)32 b(con)n(tain)f(the)h(complete)f(genealogy)f(of)h(the)h(no)r +(de,)h(i.e.,)g(the)f(list)g(of)g(ancestors)d(up)j(to)g(the)g(ro)r(ot)f +(of)g(the)118 4584 y(tree.)243 4683 y(This)j(allo)n(ws)f(to)i(replace)e +(man)n(y)h(searc)n(hes)f(in)h(database)g(tables)g(with)h(string)f(op)r +(erations)f(on)h(the)h(index.)58 b(The)118 4783 y(result,)24 +b(as)f(explained)h(in)g(Section)g(3)f(is)h(that)g(tree)f(searc)n(hes)f +(pro)r(ceed)h(at)h(\020nested)f(sets\021)30 b(sp)r(eed,)25 +b(while)f(no)r(de)g(insertions)118 4882 y(and)k(deletions)f(are)f(as)h +(fast)h(as)f(with)h(p)r(oin)n(ters.)243 4982 y(The)i(ob)n(vious)f(do)n +(wnside)h(of)h(the)g(metho)r(d)g(is)f(that)h(the)g(primary)f(k)n(ey)f +(in)i(the)g(tree)f(needs)h(to)f(b)r(e)h(a)g(v)-5 b(ariable)29 +b(size)118 5082 y(text)j(\034eld,)h(and)f(that)g(the)g(iden)n +(ti\034ers)f(ma)n(y)g(b)r(e)i(extremelly)e(long)g(for)g(deep)h(trees.) +49 b(W)-7 b(e)32 b(will)g(pro)n(vide)e(estimates)i(of)118 +5181 y(the)c(size)f(required)g(as)g(a)g(function)h(of)g(the)f +(magnitude)h(of)f(the)h(tree.)1987 5653 y(1)p eop +%%Page: 2 2 +2 1 bop 118 291 a Fi(2)131 b(Genealogical)45 b(iden)l(ti\034ers)g(for)f +(trees)118 489 y Fm(2.1)112 b(De\034nition)118 642 y +Fh(W)-7 b(e)28 b(de\034ne)g Fe(gene)l(alo)l(gic)l(al)k(identi\034ers)j +Fh(recursiv)n(ely)25 b(as)i(follo)n(ws:)326 808 y Fg(De\034nition:)59 +b Fe(The)42 b(gene)l(alo)l(gic)l(al)h(identi\034er)f(\(gID\))e(of)i(a)f +(no)l(de)h(is)f(obtaine)l(d)h(by)g(app)l(ending)g(a)f(child)326 +908 y(identi\034er)30 b(to)g(the)g(gene)l(alo)l(gic)l(al)h +(identi\034er)g(of)f(the)g(p)l(ar)l(ent)f(no)l(de.)243 +1074 y Fh(Remark)40 b(that)h(genealogical)e(iden)n(ti\034ers)i(are)f +(rather)g(w)n(ell)h(kno)n(wn)f(and)h(used;)48 b(common)41 +b(examples)f(are)g(the)118 1174 y(\020path+\034le-name\021)33 +b(in)28 b(a)f(computer)g(\034le)h(system)f(and)h(the)f(URLs)h(within)g +(a)f(WWW.)243 1273 y(The)d(name)g(\020genealogical)e(iden)n +(ti\034er\021)30 b(is)24 b(suggested)g(b)n(y)g(the)g(fact)h(that)f(the) +h(v)-5 b(alue)24 b(of)g(the)h(iden)n(ti\034er)f(con)n(tains)f(the)118 +1373 y(complete)30 b(genealogy)d(of)j(the)g(no)r(de:)41 +b(it)30 b(con)n(tains)e(as)h(a)h(substring)f(the)h(gID)f(of)h(its)g +(father,)g(whic)n(h)f(in)h(turn)g(con)n(tains)118 1472 +y(as)d(a)g(substring)g(the)h(gID)g(of)f(the)h(grandfather,)e(.)14 +b(.)g(.)243 1572 y(The)27 b(ro)r(ot)g(no)r(de)h(of)f(the)h(tree)f(has)g +(a)h(gID)f(with)h(v)-5 b(alue)28 b(\021)34 b(\(the)28 +b(empt)n(y)g(string\),)f(as)g(it)h(has)f(no)g(paren)n(t.)118 +1804 y Fm(2.2)112 b(Child)36 b(iden)m(ti\034ers)118 1958 +y Fh(The)26 b(ob)n(vious)e(c)n(hild)i(iden)n(ti\034er)g(is)f(a)h +(zero-based)d(coun)n(ter:)35 b(iden)n(tify)26 b(the)h(c)n(hild)e(b)n(y) +h(the)g(n)n(um)n(b)r(er)f(of)h(older)f(brethren)g(it)118 +2057 y(has.)243 2157 y(W)-7 b(e)25 b(could)f(represen)n(t)g(the)h(coun) +n(ter)f(in)h(base)f(10;)h(this)g(ho)n(w)n(ev)n(er)e(is)i(extremely)f(w) +n(asteful)g(of)h(resources.)34 b(It)25 b(is)g(m)n(uc)n(h)118 +2257 y(b)r(etter)33 b(to)f(represen)n(t)f(the)h(coun)n(ter)g(in)g(as)g +(large)e(a)i(base)g(as)f(p)r(ossible:)46 b(in)n(terpret)32 +b(as)f(n)n(um)n(b)r(ers)h(a)g(set)g(of)g(c)n(haracters)118 +2356 y(larger)26 b(than)h({0,1,.)14 b(.)g(.)g(9}.)243 +2456 y(As)26 b(tree)f(op)r(erations)f(will)i(in)n(v)n(olv)n(e)f(string) +g(op)r(erations)f(on)i(the)g(indices,)g(in)g(order)f(to)g(a)n(v)n(oid)g +(a)g(\020quoting)g(hell\021)33 b(it)26 b(is)118 2555 +y(desirable)d(to)h(a)n(v)n(oid)e(using)h(an)n(y)g(c)n(haracter)f(with)i +(a)g(sp)r(ecial)f(meaning)h(in)g(LIKE)g(expressions)e(or)g(regular)g +(expressions;)118 2655 y(i.e.,)28 b(w)n(e)f(will)h(not)f(use)h(an)n(y)f +(of)g(the)h(sym)n(b)r(ols)70 b Fd(.)44 b(*)f(^)g(\\)g([)g(])g({)h(})f +(\()g(\))g(<)g(>)71 b Fh(?)37 b(|)28 b(&)f($)243 2755 +y(W)-7 b(e)28 b(prop)r(ose)e(to)h(reserv)n(e)f(also)g(/)i(as)f(a)g +(separator)e(\(see)i(\020V)-7 b(ariable)27 b(Sized)g(gID\021)34 +b(b)r(elo)n(w\).)243 2854 y(If)g(w)n(e)f(limit)i(ourselv)n(es)d(to)i +(ascii)f(c)n(haracters,)g(and)h(a)n(v)n(oid)e(to)i(b)r(e)g(safe)f(a)h +(lot)g(of)g(other)f(c)n(haracters,)g(w)n(e)g(can)h(use)118 +2954 y(n)n(um)n(b)r(ers)27 b(in)h(base)f(64)g(b)n(y)g(represen)n(ting) +243 3120 y Ff(\017)41 b Fh(0-9)26 b(with)i('0'-'9')f(\(dec)g(ascii)g +(co)r(de)h(48-57\))243 3286 y Ff(\017)41 b Fh(10)26 b(with)i(':')37 +b(\(dec)28 b(ascii)f(co)r(de)h(58\))243 3452 y Ff(\017)41 +b Fh(11)26 b(with)i(';')g(\(dec)g(ascii)f(co)r(de)g(59\))243 +3618 y Ff(\017)41 b Fh(12-37)25 b(with)j('A'-'Z')g(\(dec)f(ascii)g(co)r +(de)h(65-90\))243 3784 y Ff(\017)41 b Fh(38-63)25 b(with)j('a'-'z')f +(\(dec)h(ascii)f(co)r(de)g(97-122\))118 3950 y(By)g(using)g(base)f(64,) +h(up)g(to)h(4096)d(c)n(hildren)i(can)f(b)r(e)i(represen)n(ted)e(using)h +(t)n(w)n(o)f(suc)n(h)h(digits,)g(up)h(to)f(262144)d(with)k(three)118 +4050 y(digits,)g(and)f(up)h(to)f(16777216)d(with)k(four)f(digits.)243 +4149 y(If)37 b(the)g(RDBMs)g(supp)r(orts)f(in)n(ternational)g(c)n +(haracters,)h(it)g(is)g(p)r(ossible)f(to)h(further)f(increase)g(the)h +(base;)k(as)36 b(an)118 4249 y(example,)30 b(b)n(y)f(using)g(the)h(95)f +(additional)g(c)n(haracters)e(of)i(the)h(latin-1)f(c)n(haracter)e(set,) +k(w)n(e)e(could)g(co)r(de)g(n)n(um)n(b)r(ers)g(in)h(a)118 +4349 y(base)f(up)g(to)g(160)f(\025)g(remark)g(that)h(ev)n(ery)f(single) +h(digit)g(is)g(still)h(one)e(b)n(yte)h(in)h(this)f(represen)n(tation.) +40 b(This)29 b(means)f(that)118 4448 y(w)n(e)f(expand)h(the)f(sym)n(b)r +(ols)g(ab)r(o)n(v)n(e)f(b)n(y)i(represen)n(ting)243 4614 +y Ff(\017)41 b Fh(64-159)25 b(with)j(dec)f(latin1)g(co)r(de)h(160-255) +243 4780 y(In)23 b(base)g(160,)g(up)g(to)h(25600)d(c)n(hildren)i(can)f +(b)r(e)i(represen)n(ted)e(using)h(t)n(w)n(o)g(digits,)h(up)g(to)f +(4096000)d(with)k(three)f(digits,)118 4880 y(and)28 b(up)f(to)h +(6.5E+08)e(with)i(four)f(digits.)243 4980 y(Remark)g(that)h(base)f(con) +n(v)n(ersions)f(only)h(need)i(to)e(b)r(e)i(p)r(erformed)e(at)h +(insertion)g(time,)g(when)h(the)f(index)g(of)g(a)g(new)118 +5079 y(no)r(de)g(is)f(computed.)37 b(They)28 b(will)f(therefore)g(only) +g(ha)n(v)n(e)f(an)i(impact)f(on)h(insertion)f(timings.)1987 +5653 y(2)p eop +%%Page: 3 3 +3 2 bop 118 291 a Fm(2.3)112 b(Coun)m(ters:)50 b(\020delimited\021)44 +b(vs.)51 b(\020\034xed)38 b(size\021)118 444 y Fh(The)33 +b(standard)g(represen)n(tation)e(of)i(gID)h(uses)e(a)h(v)-5 +b(ariable)32 b(size)h(c)n(hild)h(iden)n(ti\034er,)g(and)f(delimiters)g +(to)h(separate)d(the)118 543 y(gID)f(of)g(the)h(c)n(hild)f(no)r(de)g +(from)f(the)i(gID)f(of)g(its)g(paren)n(t.)43 b(F)-7 b(or)30 +b(example,)g(w)n(e)g(can)f(represen)n(t)g(the)i(\034fth)g(c)n(hild)f +(of)g(no)r(de)118 643 y('/23/27/1')24 b(as)j('/23/27/1/4'.)32 +b(Let)c(us)f(call)g(this)h(a)f Fg(vgID)h Fh(represen)n(tation)e(\(V)-7 +b(ariable)27 b(Size)h(Genealogical)d(ID\).)243 743 y(This)30 +b(represen)n(tation)f(allo)n(ws)f(for)i(an)n(y)g(n)n(um)n(b)r(er)g(of)g +(c)n(hildren)g(of)h(a)f(no)r(de,)h(sub)5 b(ject)30 b(only)g(to)g(the)h +(limitations)f(the)118 842 y(RDBMS)e(ma)n(y)f(ha)n(v)n(e)f(as)h(to)h +(the)g(length)f(of)h(a)f(v)-5 b(ariable)27 b(sized)g(string.)243 +942 y(Alternativ)n(ely)-7 b(,)24 b(w)n(e)f(could)h(c)n(ho)r(ose)f(to)h +(limit)g(from)g(the)g(outset)g(the)g(quan)n(tit)n(y)g(of)f(c)n(hildren) +h(that)g(a)g(no)r(de)g(ma)n(y)f(ha)n(v)n(e;)118 1042 +y(this)28 b(limit)g(w)n(ould)f(dep)r(end)i(of)e(course)f(on)i(the)g +(application.)36 b(Let)27 b(us)h(call)f(this)h(a)f Fg(fgID)h +Fh(represen)n(tation.)243 1141 y(F)-7 b(or)25 b(example,)h(if)g(no)g +(no)r(de)f(is)h(allo)n(w)n(ed)f(to)g(ha)n(v)n(e)g(more)g(than)h(25600)d +(c)n(hildren,)j(w)n(e)g(could)f(represen)n(t)g(the)h(coun)n(ters)118 +1241 y(alw)n(a)n(ys)36 b(with)i(2)f(digits.)67 b(The)38 +b(no)r(de)f(whic)n(h)h(w)n(as)f(previously)f('/23/27/1/4')d(is)k(no)n +(w)g('23270104'.)64 b(If)38 b(w)n(e)f(require)118 1340 +y(a)g(three)g(digit)h(represen)n(tation)d(of)i(no)r(des)g(\(up)h(to)f +(ab)r(out)h(4)f(million)g(c)n(hildren\),)j(then)d(it)h(will)g(b)r(e)f +(represen)n(ted)f(as)118 1440 y('023027001004'.)118 1672 +y Fm(2.4)112 b(Ordering)37 b(of)h(no)s(des)118 1825 y +Fh(F)-7 b(or)35 b(some)g(applications)g(it)h(is)f(necessary)f(to)i +(obtain)f(subtrees)g(ordered)f(according)g(to)i(some)f(sp)r(ecial)g +(rules.)60 b(F)-7 b(or)118 1925 y(instance:)220 2090 +y(1.)41 b(the)34 b(complete)g(subtree)f(starting)g(at)h(a)f(no)r(de)h +(is)g(listed)g(immediately)g(after)f(the)i(no)r(de)f(in)g(question)f +(\(\020depth)326 2189 y(\034rst\021\))220 2354 y(2.)41 +b(no)r(des)27 b(with)h(a)f(common)g(paren)n(t)g(are)g(listed)g(c)n +(hronologically)243 2519 y(F)-7 b(or)39 b(instance,)k(the)d(displa)n(y) +f(of)h(an)f(organization)f(c)n(hart)h(is)g(usually)h(required)e(to)i +(satisfy)g(at)f(least)h(the)g(\034rst)118 2619 y(condition.)h(In)29 +b(a)g(threaded)f(discussion)h(group)e(one)i(wishes)g(to)f(satisfy)h(b)r +(oth)h(conditions)e(to)h(displa)n(y)f(the)h(messages)118 +2718 y(in)20 b(a)g(thread)g(\025)f(the)i(threads)e(themselv)n(es)h +(\(i.e.,)i(c)n(hildren)e(of)g(the)g(ro)r(ot)f(no)r(de\))i(are)e +(usually)g(listed)i(in)f(in)n(v)n(erse)f(c)n(hronolical)118 +2818 y(order.)243 2917 y(T)-7 b(o)35 b(mak)n(e)f(a)h(particular)f +(ordering)g(e\036cien)n(t,)j(it)f(w)n(ould)f(b)r(e)h(a)f(nice)g +(feature)g(if)h(it)g(could)f(b)r(e)h(made)f(to)g(coincide)118 +3017 y(with)28 b(a)f(lexicographic)f(ordering)f(of)j(the)g(indices)f +(\025i.e.,)g(as)g(pro)r(duced)g(b)n(y)h(an)f(\020ORDER)h(BY)f(id)h +(ASC\021)35 b(in)27 b(SQL.)h(The)118 3117 y(lexicographic)d(ordering)h +(of)h(fgID)h(satis\034es)e(b)r(oth)i(conditions.)36 b(The)27 +b(lexicographic)f(ordering)f(of)i(vgID)g(as)g(describ)r(ed)118 +3216 y(ab)r(o)n(v)n(e)34 b(satis\034es)g(the)h(\034rst)g(requisite)f +(if)i(the)f(separator)d(has)j(the)g(minimal)g(binary)g(represen)n +(tation)e(of)i(all)f(allo)n(w)n(ed)118 3316 y(sym)n(b)r(ols)c(in)h(an)f +(index)h(\025)f(this)h(is)g(wh)n(y)f(w)n(e)g(reserv)n(ed)f(/)h(for)g +(the)i(separator.)43 b(But)31 b(the)g(second)f(prop)r(ert)n(y)g(is)g +(missing:)118 3416 y(for)d(instance,)g(the)h(index)g('/1/10')d(is)j +(lexicographically)d(b)r(efore)i('/1/2'.)243 3515 y(If)c(the)h(second)e +(prop)r(ert)n(y)g(is)i(also)e(required)g(for)h(vgID,)g(w)n(e)f(can)h +(sp)r(ecify)h(the)f(c)n(hild)h(iden)n(ti\034ers)e(with)i(coun)n(ters)e +(built)118 3615 y(in)28 b(the)g(follo)n(wing)e(w)n(a)n(y:)36 +b(represen)n(t)26 b(a)h(n)n(um)n(b)r(er)h(b)n(y)f(a)g(string)g(of)g +(digits,)h(where)243 3779 y Ff(\017)41 b Fh(the)25 b(\034rst)g(digit)h +Fc(D)896 3791 y Fb(0)958 3779 y Fh(represen)n(ts)e(the)i(length)f(in)h +(digits)f(of)g(the)h(decimal)f(expansion)f(of)i(the)f(n)n(um)n(b)r(er,) +h(min)n(us)f(one)243 3945 y Ff(\017)41 b Fh(the)28 b(follo)n(wing)e +Fa(\()p Fc(D)920 3957 y Fb(0)976 3945 y Fa(+)18 b(1\))27 +b Fh(digits)h(are)e(the)i(decimal)g(expansion)e(of)i(the)g(n)n(um)n(b)r +(er)118 4109 y(Let)g(us)f(call)h(these)f(iden)n(ti\034ers)g +Fg(m-vgID)p Fh(,)g(\020m\021)34 b(for)27 b(mo)r(di\034ed.)243 +4209 y(As)e(an)f(example,)h(the)g(no)r(de)g(whic)n(h)g(w)n(as)f +(previously)f(represen)n(ted)h(b)n(y)g(/15/3/182)d(will,)k(after)g +(this)g(mo)r(di\034cation,)118 4309 y(ha)n(v)n(e)h(the)i(index)g +(/115/03/2182.)243 4408 y(The)37 b(lexicographic)f(ordering)g(of)i +(m-vgID)f(is)h(the)g(desired)f(ordering)f(of)h(the)h(tree)g(no)r(des.) +67 b(The)38 b(cost)f(of)g(this)118 4508 y(prop)r(ert)n(y)31 +b(is)i(that)f(\(a\))h(the)g(ID)f(are)g(no)n(w)g(longer,)g(\(b\))h(no)f +(no)r(de)g(can)g(ha)n(v)n(e)g(more)f(than)i Fa(160)3106 +4478 y Fb(160)3240 4508 y Fh(c)n(hildren)f(\(actually)-7 +b(,)118 4607 y(this)32 b(is)g(a)f(non-issue\),)h(and)f(\(c\))h(the)g +(index)g(structure)f(is)h(redundan)n(t,)g(some)f(formally)f(correct)h +(indices)g(are)g(in)n(v)-5 b(alid)118 4707 y(\025e.g.,)24 +b(/316/013/11.)30 b(The)24 b(third)g(issue)g(can)g(b)r(e)g(addressed)f +(b)n(y)g(k)n(eeping)g(a)h(strict)g(con)n(trol)e(on)i(the)g(generation)f +(of)h(new)118 4807 y(indices)k(to)f(insure)g(that)h(all)f(indices)h +(are)e(formally)h(correct.)243 4906 y(The)32 b(issue)f(of)h(the)g(rev)n +(erse)e(c)n(hronological)f(indexing)j(of)f(threads)h(in)g(threaded)f +(discussion)g(groups)g(can)g(b)r(e)h(ad-)118 5006 y(dressed)d(easily)f +(enough)h(in)h(fgID:)f(coun)n(t)g(\020do)n(wn\021)36 +b(instead)29 b(of)g(\020up\021)36 b(the)30 b(c)n(hildren)f(of)g(the)h +(ro)r(ot)e(no)r(de)i(\025)f(this)h(implies)118 5106 y(only)e(an)g +(inconsequen)n(tial)f(mo)r(di\034cation)h(of)g(the)g(no)r(de)h +(insertion)e(routine,)h(as)g(sho)n(wn)f(b)r(elo)n(w.)38 +b(The)29 b(problem)e(is)h(less)118 5205 y(trivial)i(with)g(vgID;)h(in)f +(this)h(case,)f(ma)n(yb)r(e)f(a)h(thread)g(iden)n(ti\034er)g(should)g +(b)r(e)h(k)n(ept)f(in)g(a)g(di\033eren)n(t)g(\034eld)h(-)f(i.e.,)h +(repre-)118 5305 y(sen)n(ting)h(the)h(structure)f(as)g(a)h(forest)f +(rather)f(than)i(a)f(tree,)i(where)e(the)h(thread_id)f(\034eld)h +(selects)f(the)h(\020tree\021)38 b(in)33 b(the)118 5404 +y(forest.)1987 5653 y(3)p eop +%%Page: 4 4 +4 3 bop 118 291 a Fi(3)131 b(T)-11 b(ree)45 b(op)t(erations)e(using)h +(genealogical)g(indices)118 472 y Fh(In)32 b(this)f(section)g(w)n(e)g +(sho)n(w)g(ho)n(w)g(to)g(implemen)n(t)h(v)-5 b(arious)30 +b(tree)h(op)r(erations)f(using)h(gID)g(as)g(the)h(primary)e(k)n(ey)h +(in)g(the)118 572 y(no)r(de)d(table.)243 672 y(Some)h(implemen)n +(tation)h(issues)g(are)f(relev)-5 b(an)n(t)29 b(here,)h(esp)r(ecially)f +(concerning)g(the)h(utilisation)g(of)g(indices)g(b)n(y)f(the)118 +771 y(DB)f(engine.)243 871 y(W)-7 b(e)28 b(discuss)f(a)g(tree)g +(represen)n(ted)f(in)i(a)f(table)h(of)f(the)h(form)326 +1034 y Fd(CREATE)41 b(TABLE)g(tree)h(\()456 1134 y(gid)304 +b(text)42 b(PRIMARY)f(KEY,)456 1234 y(nchildren)f(integer)h(DEFAULT)f +(0,)456 1333 y(\\ldots)h(the)i(actual)e(node)h(data)326 +1433 y(\);)118 1597 y Fh(The)26 b(\034eld)g(\020nc)n(hildren\021)32 +b(is)26 b(a)f(coun)n(ter)g(for)g(the)i(n)n(um)n(b)r(er)e(of)h(c)n +(hildren)f(that)h(the)h(no)r(de)f(has)f Fe(ever)35 b +Fh(had;)27 b(w)n(e)e(assume)g(here)118 1696 y(it)j(is)g(not)f(up)r +(dated)h(when)g(no)r(des)f(or)g(subtrees)g(are)f(deleted.)243 +1796 y(Section)h(4)g(pro)n(vides)f(a)i(complete)f(implemen)n(tation)h +(of)f(these)h(op)r(erations)e(for)h(fgID)h(in)g(P)n(ostgreSQL.)118 +2028 y Fm(3.1)112 b(Computing)37 b(the)g(lev)m(el)f(of)h(a)h(no)s(de) +118 2181 y Fg(Cost:)f Fe(string)30 b(op)l(er)l(ations)g(\(no)g(table)g +(ac)l(c)l(ess\))243 2280 y Fh(This)d(is)h(a)f(pure)g(string)g(op)r +(eration,)f(no)i(table)f(access)g(is)g(required.)243 +2460 y Ff(\017)41 b Fg(vgID:)27 b Fh(coun)n(t)h(the)g(n)n(um)n(b)r(er)f +(of)g(separators)e(\('/'\))j(in)g(the)g(PK)243 2625 y +Ff(\017)41 b Fg(fgID:)27 b Fh(coun)n(t)g(the)h(n)n(um)n(b)r(er)g(of)f +(c)n(haracters)e(in)j(the)g(PK,)g(divide)g(b)n(y)f(the)h(\034xed)f +(size)h(of)f(the)h(coun)n(ters.)118 2857 y Fm(3.2)112 +b(Selecting)36 b(or)h(deleting)f(a)i(subtree)118 3010 +y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 +3173 y Ff(\017)41 b Fg(vgID:)27 b Fh(The)h(subtree)f(ro)r(oted)g(at)g +(/26/5/7)e(is)i(selected)g(b)n(y)508 3338 y Fd(...)43 +b(WHERE)e(id)i(LIKE)f('/26/5/7\045')d(AND)j(id)h(<)g('/26/5/70')243 +3503 y Ff(\017)e Fg(m-vgID:)26 b Fh(The)h(subtree)h(ro)r(oted)e(at)i +(/126/05/07)22 b(is)28 b(selected)f(b)n(y)508 3668 y +Fd(...)43 b(WHERE)e(id)i(LIKE)f('/126/06/07\045')243 +3833 y Ff(\017)f Fg(fgID:)27 b Fh(The)h(subtree)f(ro)r(oted)g(at)g +(260507)e(is)i(selected)h(b)n(y)508 3997 y Fd(...)43 +b(WHERE)e(id)i(LIKE)f('260507\045')118 4229 y Fm(3.3)112 +b(Selecting)36 b(the)h(direct)f(c)m(hildren)g(of)i(a)g(no)s(de)118 +4382 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 +4562 y Ff(\017)41 b Fg(vgID:)27 b Fh(The)h(direct)f(c)n(hildren)g(of)h +(/26/5/7)c(are)j(selected)g(b)n(y)508 4727 y Fd(...)43 +b(WHERE)e(id)i(LIKE)f('/26/5/7/\045')d(AND)j(id)h(NOT)f(LIKE)g +('26/5/7/\045/\045')243 4892 y Ff(\017)f Fg(m-vgID:)26 +b Fh(The)h(direct)h(c)n(hildren)f(of)g(/26/5/7)e(are)h(selected)i(b)n +(y)508 5056 y Fd(...)43 b(WHERE)e(id)i(LIKE)f('/126/06/07/\045')37 +b(AND)43 b(id)f(NOT)h(LIKE)f('/126/05/07/\045/\045)o(')243 +5221 y Ff(\017)f Fg(fgID:)27 b Fh(The)h(direct)f(c)n(hildren)g(of)h +(260507)c(are)j(selected)g(b)n(y)508 5386 y Fd(...)43 +b(WHERE)e(id)i(LIKE)f('260507\045')d(AND)k(char_length\(id\))37 +b(=)43 b(\(char_length\('26)o(05)o(07')o(\)+)o(2\))1987 +5653 y Fh(4)p eop +%%Page: 5 5 +5 4 bop 118 291 a Fm(3.4)112 b(Inserting)37 b(a)h(no)s(de)g(or)f(a)h +(subtree)118 444 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l +(e)l(e)f(+)h(string)f(and)h(math)g(op)l(er)l(ations)243 +543 y Fh(Insertion)f(is)g(a)h(pro)r(cedural)e(op)r(eration.)42 +b(As)30 b(eac)n(h)f(RDBMS)h(has)f(a)h(di\033eren)n(t)f(w)n(a)n(y)g(of)g +(de\034ning)h(pro)r(cedures,)f(w)n(e)118 643 y(will)f(just)g(describ)r +(e)f(here)g(the)h(necessary)e(steps.)37 b(Examples)27 +b(for)g(P)n(ostgreSQL)f(are)h(pro)n(vided)f(in)i(4.)243 +743 y(In)22 b(order)f(to)h(insert)g(a)g(new)g(c)n(hild)h(of)f +(\020daddy\021)28 b(\(either)23 b(one)f(of)g(/26/5/7,)e(/126/05/07)d +(or)22 b(260507)d(in)k(the)f(examples)118 842 y(ab)r(o)n(v)n(e\))27 +b(y)n(ou)f(ha)n(v)n(e)h(to)220 1008 y(1.)41 b(add)27 +b(one)g(to)h(the)g(n)n(um)n(b)r(er)f(of)g(c)n(hildren)h(of)f +(\020daddy\021)508 1174 y Fd(UPDATE)41 b(tree)h(SET)h(nchildren)c(=)k +(\(nchildren)d(+)j(1\))g(WHERE)e(ID)i(=)g(``daddy'';)220 +1340 y Fh(2.)e(enco)r(de)27 b(the)h(n)n(um)n(b)r(er)f(of)g(c)n(hildren) +g(of)h(\020daddy\021)33 b(in)28 b(base)f(160,)f(bring)h(it)h(to)f(the)h +(correct)e(format)h(dep)r(ending)h(on)326 1440 y(the)c(v)-5 +b(arian)n(t)23 b(of)h(gID)g(\(pad)g(with)h(0)e(or)g(not,)i(prep)r(end)f +(a)g(digit)g(coun)n(ter)f(or)g(not,)i(prep)r(end)f(/)g(or)f(not,)i +(coun)n(t)e(do)n(wn)326 1540 y(or)j(up,)i(.)14 b(.)g(.)g(\))37 +b(and)28 b(app)r(end)f(it)h(to)g(daddy's)f(gID)g(to)h(obtain)f(the)h +(new)g(no)r(de's)f(gID.)220 1706 y(3.)41 b(insert)27 +b(the)h(new)f(no)r(de)243 1872 y(When)35 b(inserting)g(a)f(subtree,)j +(the)e(index)g(of)g(the)h(ro)r(ot)e(of)h(the)g(subtree)g(has)f(to)h(b)r +(e)h(computed)f(as)f(ab)r(o)n(v)n(e,)i(and)118 1971 y(prep)r(ended)28 +b(to)f(the)h(index)g(of)f(eac)n(h)g(no)r(de)h(of)f(the)h(subtree)f(b)r +(efore)h(insertion.)243 2071 y(Remark)e(that)i(only)f(the)h(paren)n(t)f +(no)r(de)h(has)f(to)g(b)r(e)h(up)r(dated)g(on)f(insertion.)118 +2303 y Fm(3.5)112 b(Selecting)36 b(the)h(ancestors)h(of)g(a)g(no)s(de) +118 2457 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 +2556 y Fh(Y)-7 b(ou)27 b(can)g(sp)r(ecify)h(all)g(ancestors)d(of)j(a)f +(no)r(de)h(in)f(a)h(single)f(SQL)g(statemen)n(t;)g(for)g(instance)h +(for)f(vgID)326 2722 y Fd(...)42 b(WHERE)f('/25/6/7')f(LIKE)i(\(id)g +(||)h('/\045'\))f(AND)g(id)h(<)g('/25/6/7')118 2888 y +Fh(The)31 b(second)e(part)h(of)h(the)g(clause,)f(while)h(logically)e +(redundan)n(t,)h(is)h(a)f(\020hin)n(t\021)37 b(to)30 +b(the)h(optimizer.)45 b(A)n(t)31 b(least)f(in)g(P)n(ost-)118 +2988 y(greSQL,)c(without)i(it)g(the)g(optimizer)f(will)h(c)n(ho)r(ose)e +(a)i(sequen)n(tial)e(scan)h(of)h(the)g(table)f(and)h(disregard)d(the)j +(index.)118 3220 y Fm(3.6)112 b(Selecting)36 b(all)g(lea)m(v)m(es)118 +3374 y Fg(Cost:)h Fe(sc)l(an)30 b(of)g(the)g(tr)l(e)l(e)243 +3473 y Fh(A)e(leaf)f(is)g(a)h(no)r(de)f(without)h(descendan)n(ts:)36 +b(it)28 b(has)f(0)g(c)n(hildren.)37 b(Hence)326 3639 +y Fd(...)42 b(WHERE)f(nchildren)f(=)j(0)118 3805 y Fh(If)28 +b(this)g(t)n(yp)r(e)g(of)f(query)g(is)h(often)f(necessary)-7 +b(,)26 b(y)n(ou)h(ma)n(y)g(b)r(e)h(w)n(ell)f(advised)g(to)g(k)n(eep)g +(an)h(index)f(on)h(tree\(nc)n(hildren\).)118 4038 y Fm(3.7)112 +b(Determining)35 b(if)i(A)g(is)g(a)h(descendan)m(t)g(of)g(B)118 +4191 y Fg(Cost:)f Fe(string)30 b(op)l(er)l(ations,)h(no)f(table)g(ac)l +(c)l(ess)243 4291 y Fh(This)d(is)h(a)f(pure)g(string)g(op)r(eration)f +(on)i(the)g(indices,)f(no)g(table)h(access)e(is)i(necessary)-7 +b(.)118 4565 y Fi(4)131 b(Putting)45 b(it)f(all)h(together:)57 +b(a)44 b(P)l(ostgreSQL)f(implemen)l(tation)118 4747 y +Fh(h)n(ttp://www.p)r(ostgresql.org/mhonarc/pgsq)o(l-sql/)o(20)o(00)o +(-0)o(4/)o(msg0)o(02)o(67)o(.h)n(tml)243 4847 y(W)-7 +b(e)30 b(describ)r(e)g(here)g(a)g(small)f(pac)n(k)-5 +b(age)29 b(that)i(can)e(b)r(e)i(used)f(for)g(implemen)n(ting)g(gID)g +(on)g(P)n(ostgreSQL.)f(It)i(can)e(b)r(e)118 4946 y(found)f(at)f(<h)n +(ttp://...>)243 5046 y(The)21 b(pac)n(k)-5 b(age)21 b(uses)g(the)h(pro) +r(cedural)e(language)h(PL/PGsql.)35 b(A)22 b(b)r(etter)g(implemen)n +(tation)g(w)n(ould)f(probably)g(de\034ne)118 5145 y(the)28 +b(gID)g(as)f(new)g(P)n(ostgres)f(t)n(yp)r(es,)i(and)f(co)r(de)g(all)h +(this)g(in)f(C.)243 5245 y(The)g(\034les)h(should)f(b)r(e)h(loaded)f +(in)h(alphab)r(etical)f(order.)1987 5653 y(5)p eop +%%Page: 6 6 +6 5 bop 118 291 a Fm(4.1)112 b(tree0_enco)s(ding.sql)118 +444 y Fh(This)28 b(\034le)f(de\034nes)h(and)f(p)r(opulates)h(the)f +(table)h(_b160_digits)d(of)j(\020digits\021)33 b(in)28 +b(base)f(160,)326 604 y Fd(CREATE)41 b(TABLE)g(\\_b160\\_digits)d +(\(deci)j(integer,)f(code)i(char\);)118 764 y Fh(and)28 +b(the)f(t)n(w)n(o)g(functions)326 924 y Fd(CREATE)41 +b(FUNCTION)f(\\_b160\\_encode\(i)o(nt)o(eg)o(er\))d(RETURNS)j(string) +413 1024 y(AS)j('....')e(LANGUAGE)f('plpgsql';)326 1124 +y(CREATE)h(FUNCTION)f(\\_b160\\_encode\(i)o(nt)o(eg)o(er,)o(in)o(te)o +(ger)o(\))d(RETURNS)k(string)413 1223 y(AS)i('....')e(LANGUAGE)f +('plpgsql';)118 1384 y Fh(The)22 b(\034rst)h(function)f(returns)g(a)g +(v)-5 b(ariable)21 b(size)h(enco)r(ding;)i(the)f(second)e(a)h(\034xed)h +(size)f(enco)r(ding)g(\(the)h(second)e(parameter)118 +1483 y(is)g(the)h(size\),)g(and)f(raises)e(an)i(exception)g(if)h(the)f +(n)n(um)n(b)r(er)g(is)g(to)r(o)g(large)e(to)i(b)r(e)h(represen)n(ted)e +(with)h(the)h(requested)e(n)n(um)n(b)r(er)118 1583 y(of)28 +b(digits.)118 1814 y Fm(4.2)112 b(tree1_de\034ne.sql)118 +1967 y Fh(This)28 b(\034le)f(pro)n(vides)f(a)i(function)326 +2127 y Fd(CREATE)41 b(FUNCTION)f(_tree_create\(tex)o(t,)o(in)o(teg)o +(er)o(,t)o(ext)o(,t)o(ex)o(t\))d(RETURNS)k(bpchar)413 +2227 y(AS)i('....')e(LANGUAGE)f('plpgsql';)118 2387 y +Fh(that)e(creates)f(a)h(tree)f(infrastructure)g(of)h(either)g(fgID)g +(or)f(vgID.)h(Assuming)f(y)n(ou)g(ha)n(v)n(e)g(a)h(table)f(\020m)n +(ytable\021)44 b(with)118 2487 y(primary)26 b(k)n(ey)h(\020m)n +(yid\021,)g(then)h(calling)326 2647 y Fd(SELECT)41 b(_tree_create\('m)o +(yt)o(ree)o(',)o(2,')o(my)o(ta)o(ble)o(',)o('m)o(yid)o('\))o(;)118 +2807 y Fh(will)28 b(cause:)220 2967 y(1.)41 b(the)28 +b(creation)e(of)i(a)f(table)508 3131 y Fd(CREATE)41 b(TABLE)h +(mytree_bkg\()683 3230 y(gid)g(text)g(PRIMARY)e(KEY,)683 +3330 y(nchildren)f(int,)683 3429 y(sid)j(integer)f(REFERENCES)e +(mytable\(myid\))508 3529 y(\);)508 3629 y(CREATE)i(UNIQUE)g(INDEX)h +(mytree_bkg_sid)37 b(ON)43 b(mytree_bkg\(sid\);)326 3792 +y Fh(for)27 b(the)h(tree)f(structure.)220 3955 y(2.)41 +b(the)28 b(creation)e(of)i(a)f(view)508 4118 y Fd(CREATE)41 +b(VIEW)h(mytree)f(AS)639 4218 y(SELECT)g(t.gid,n.*)900 +4317 y(FROM)h(mytable)f(n,)i(mytree_bkg)c(t)900 4417 +y(WHERE)j(t.sid=n.myid;)326 4580 y Fh(with:)35 b(a)23 +b(trigger)e(on)i(UPD)n(A)-7 b(TE)25 b(that)e(blo)r(c)n(ks)g(up)r +(dating)g(the)h(gid)f(and)g(allo)n(ws)f(up)r(dating)h(the)g(no)r(de)h +(data,)f(a)g(rule)326 4680 y(on)k(DELETE)i(that)f(deletes)f(the)h +(corresp)r(onding)e(en)n(try)h(b)r(oth)h(in)g(m)n(ytree_bkg)d(and)j(m)n +(ytable,)f(and)g(a)g(trigger)326 4779 y(ON)h(INSER)-7 +b(T)30 b(that)f(raises)e(an)h(exception)g(and)g(informs)h(the)f(user)g +(to)h(use)f(the)h(insertion)f(function)h(describ)r(ed)326 +4879 y(b)r(elo)n(w.)220 5042 y(3.)41 b(t)n(w)n(o)26 b(insertion)h +(functions)h(that)g(compute)g(automatically)e(the)i(gID)g(of)f(the)h +(new)g(no)r(de:)425 5205 y Ff(\017)41 b Fh(a)27 b(function)i(m)n +(ytree_insert\(text,text,in)n(teger,text\))d(for)h(insertion)g(sim)n +(ultaneosly)f(in)i(b)r(oth)g(tables:)508 5305 y(m)n +(ytree_insert\('2201','hello',0,'not)15 b(m)n(uc)n(h'\))j(inserts)g(a)g +(new)g(c)n(hild)h(of)f(2201)f(with)h(data1='hello',)h(data2=0)508 +5404 y(and)28 b(data3='not)e(m)n(uc)n(h')1987 5653 y(6)p +eop +%%Page: 7 7 +7 6 bop 425 291 a Ff(\017)41 b Fh(a)27 b(function)i(m)n +(ytree_insert_no)r(de\(text,in)n(teger\))c(for)i(insertion)g(in)h(m)n +(ytree_bkg)508 390 y(m)n(ytree_insert\('2201',25\))c(inserts)j(in)h(m)n +(ytree_bkg)e(a)h(new)h(c)n(hild)f(of)h(2201)d(with)j(sid=25)220 +556 y(4.)41 b(a)27 b(function)h(m)n(ytree_mo)n(v)n(e\(text,text\))e +(that)i(mo)n(v)n(es)e(subtrees:)326 656 y(m)n(ytree_mo)n(v)n +(e\('2201','23'\))d(mo)n(v)n(es)j(the)i(subtree)f(ro)r(oted)g(at)g +(2201)f(to)h(a)h(place)f(b)r(elo)n(w)g(23)f(\(ma)n(yb)r(e)i(2307\))220 +822 y(5.)41 b(a)c(function)g(m)n(ytree_len\(\))g(that)h(returns)e(the)i +(length)f(of)g(the)h(enco)r(dings)f(used)g(in)h(the)f(gID)g(\(2)h +(here;)j(0)c(if)326 922 y(v)-5 b(ariable)26 b(size\).)118 +1196 y Fi(5)131 b(Non-tree)44 b(hierarc)l(hies)118 1378 +y Fh(sequence)22 b(as)f(id,)j(table)e(with)h(\(id,g-index\))f(with)g(p) +r(ossibly)g(man)n(y)g(g-indices)f(for)h(eac)n(h)f(id)h(\(if)h(TOO)f +(man)n(y)-7 b(,)23 b(bad)f(mo)r(del:)118 1478 y(list)28 +b(all)f(genealogies,)f(i.e.,)h(paths)h(from)f(the)h(ro)r(ot\))118 +1752 y Fi(References)160 1934 y Fh([1])41 b(Philip)28 +b(Greenspun,)g Fe(T)-6 b(r)l(e)l(es)29 b(in)h(Or)l(acle)g(SQL)p +Fh(,)d(in)h Fg(SQL)k(for)g(W)-8 b(eb)31 b(Nerds)289 2033 +y Fh(<h)n(ttp://photo.net/sql/trees.h)n(tml>)160 2200 +y([2])41 b(Jo)r(e)27 b(Celk)n(o,)f Fe(SQL)j(for)i(Smarties)p +Fh(,)d(in)g Fg(DBMS)j(Online)p Fh(,)26 b(Marc)n(h)h(to)g(June)h(1996) +289 2299 y(<h)n(ttp://www.dbmsmag.com/9603d06.h)n(tml>)289 +2399 y(<h)n(ttp://www.dbmsmag.com/9604d06.h)n(tml>)289 +2498 y(<h)n(ttp://www.dbmsmag.com/9605d06.h)n(tml>)289 +2598 y(<h)n(ttp://www.dbmsmag.com/9606d06.h)n(tml>)160 +2764 y([3])41 b(Graeme)26 b(Birc)n(hall,)h Fg(DB2)32 +b(UDB)g(V6.1)f(SQL)h(Co)s(okb)s(o)s(ok)p Fh(,)289 2864 +y(<h)n(ttp://ourw)n(orld.compuserv)n(e.com/homepag)o(es/)o(Gra)o +(eme_Bir)o(c)n(ha)o(ll/HTM_CO)o(OK)o(.HTM>)1987 5653 +y(7)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF |