From 19922f22a1f6c4dd27b11f449c4ff86183842303 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 7 Dec 2006 00:27:10 +0100 Subject: [PATCH] Imported from util-linux-2.13-pre5 tarball. --- NEWS | 8 + configure | 27 +- configure.ac | 9 +- disk-utils/fsck.cramfs.c | 779 ++++++++++++++++++++++----------------- disk-utils/mkfs.cramfs.c | 30 +- mount/fstab.c | 21 +- mount/fstab.h | 1 - mount/mount.8 | 3 + mount/umount.c | 5 +- po/Makefile.in.in | 2 +- po/ca.gmo | Bin 208170 -> 208336 bytes po/ca.po | 27 +- 12 files changed, 500 insertions(+), 412 deletions(-) diff --git a/NEWS b/NEWS index 9254158b..eb53e09f 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,11 @@ +util-linux 2.13-pre5 + +* {fsck,mkfs}.cramfs: updated to cramfs-1.1 +* {fsck,mkfs}.cramfs: removed PAGE_CACHE_SIZE usage +* umount: fix "umount -n -r" (Derick Swanepoel) +* misc build system and code cleanups and fixes +* updated translation: ca + util-linux 2.13-pre4 * don't build fdisk on m68k (Mike Frysinger) diff --git a/configure b/configure index 71c7da86..47be8afc 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59 for util-linux 2.13-pre4. +# Generated by GNU Autoconf 2.59 for util-linux 2.13-pre5. # # Report bugs to . # @@ -269,8 +269,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='util-linux' PACKAGE_TARNAME='util-linux' -PACKAGE_VERSION='2.13-pre4' -PACKAGE_STRING='util-linux 2.13-pre4' +PACKAGE_VERSION='2.13-pre5' +PACKAGE_STRING='util-linux 2.13-pre5' PACKAGE_BUGREPORT='bunk@stusta.de' ac_unique_file="mount/mount.c" @@ -781,7 +781,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures util-linux 2.13-pre4 to adapt to many kinds of systems. +\`configure' configures util-linux 2.13-pre5 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -847,7 +847,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of util-linux 2.13-pre4:";; + short | recursive ) echo "Configuration of util-linux 2.13-pre5:";; esac cat <<\_ACEOF @@ -1007,7 +1007,7 @@ fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -util-linux configure 2.13-pre4 +util-linux configure 2.13-pre5 generated by GNU Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. @@ -1021,7 +1021,7 @@ cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by util-linux $as_me 2.13-pre4, which was +It was created by util-linux $as_me 2.13-pre5, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -1668,7 +1668,7 @@ fi # Define the identity of the package. PACKAGE='util-linux' - VERSION='2.13-pre4' + VERSION='2.13-pre5' cat >>confdefs.h <<_ACEOF @@ -8837,7 +8837,7 @@ done -if test x$ac_cv_header_ncurses_h = xyes || x$ac_cv_header_ncurses_ncurses_h = xyes; then +if test x$ac_cv_header_ncurses_h = xyes || test x$ac_cv_header_ncurses_ncurses_h = xyes; then have_ncurses=yes { echo "$as_me:$LINENO: you have ncurses" >&5 echo "$as_me: you have ncurses" >&6;} @@ -9167,7 +9167,7 @@ fi done - if test x$ac_cv_header_slcurses_h = xyes || x$ac_cv_header_slang_slcurses_h = xyes; then + if test x$ac_cv_header_slcurses_h = xyes || test x$ac_cv_header_slang_slcurses_h = xyes; then use_slang=yes else { { echo "$as_me:$LINENO: error: slang selected but slcurses.h not found" >&5 @@ -10381,11 +10381,10 @@ _ACEOF fi +CPPFLAGS="-fsigned-char -fomit-frame-pointer $CPPFLAGS" LIBS="" -CPPFLAGS="-fsigned-char -Wall -Wmissing-prototypes -Wstrict-prototypes -Wundef -Werror-implicit-function-declaration -fomit-frame-pointer $CPPFLAGS" - ac_config_headers="$ac_config_headers config.h" @@ -10986,7 +10985,7 @@ _ASBOX } >&5 cat >&5 <<_CSEOF -This file was extended by util-linux $as_me 2.13-pre4, which was +This file was extended by util-linux $as_me 2.13-pre5, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -11049,7 +11048,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -util-linux config.status 2.13-pre4 +util-linux config.status 2.13-pre5 configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" diff --git a/configure.ac b/configure.ac index 269e6310..ac0f6c93 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(util-linux, 2.13-pre4, bunk@stusta.de) +AC_INIT(util-linux, 2.13-pre5, bunk@stusta.de) AC_PREREQ(2.59) @@ -67,7 +67,7 @@ AC_CHECK_HEADERS(ncurses.h) AC_CHECK_HEADERS(ncurses/ncurses.h) -if test x$ac_cv_header_ncurses_h = xyes || x$ac_cv_header_ncurses_ncurses_h = xyes; then +if test x$ac_cv_header_ncurses_h = xyes || test x$ac_cv_header_ncurses_ncurses_h = xyes; then have_ncurses=yes AC_MSG_NOTICE([you have ncurses]) else @@ -85,7 +85,7 @@ AC_ARG_WITH([slang], if test x$with_slang = xyes; then AC_CHECK_HEADERS(slcurses.h) AC_CHECK_HEADERS(slang/slcurses.h) - if test x$ac_cv_header_slcurses_h = xyes || x$ac_cv_header_slang_slcurses_h = xyes; then + if test x$ac_cv_header_slcurses_h = xyes || test x$ac_cv_header_slang_slcurses_h = xyes; then use_slang=yes else AC_MSG_ERROR([slang selected but slcurses.h not found]) @@ -379,11 +379,10 @@ if test x$enable_use_tty_group = xyes; then AC_DEFINE(USE_TTY_GROUP, 1, [Should wall and write be installed setgid tty?]) fi +CPPFLAGS="-fsigned-char -fomit-frame-pointer $CPPFLAGS" LIBS="" -CPPFLAGS="-fsigned-char -Wall -Wmissing-prototypes -Wstrict-prototypes -Wundef -Werror-implicit-function-declaration -fomit-frame-pointer $CPPFLAGS" - AC_CONFIG_HEADERS(config.h) diff --git a/disk-utils/fsck.cramfs.c b/disk-utils/fsck.cramfs.c index d46a5695..68bbf518 100644 --- a/disk-utils/fsck.cramfs.c +++ b/disk-utils/fsck.cramfs.c @@ -1,7 +1,8 @@ /* * cramfsck - check a cramfs file system * - * Copyright (C) 2000-2001 Transmeta Corporation + * Copyright (C) 2000-2002 Transmeta Corporation + * 2005 Adrian Bunk * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,12 +29,16 @@ * 2000/07/11: Daniel Quinlan (file length tests, start at offset 0 or 512, * fsck-compatible exit codes) * 2000/07/15: Daniel Quinlan (initial support for block devices) + * 2002/01/10: Daniel Quinlan (additional checks, test more return codes, + * use read if mmap fails, standardize messages) */ /* compile-time options */ -#define INCLUDE_FS_TESTS /* include cramfs checking and extraction */ +//#define INCLUDE_FS_TESTS /* include cramfs checking and extraction */ +#define _GNU_SOURCE #include +#include #include #include #include @@ -59,32 +64,34 @@ static const char *progname = "cramfsck"; static int fd; /* ROM image file descriptor */ static char *filename; /* ROM image filename */ -struct cramfs_super *super; /* just find the cramfs superblock once */ +struct cramfs_super super; /* just find the cramfs superblock once */ static int opt_verbose = 0; /* 1 = verbose (-v), 2+ = very verbose (-vv) */ -#ifdef INCLUDE_FS_TESTS -static int opt_extract = 0; /* extract cramfs (-x) */ char *extract_dir = NULL; /* extraction directory (-x) */ -unsigned long start_inode = 1 << 28; /* start of first non-root inode */ -unsigned long end_inode = 0; /* end of the directory structure */ -unsigned long start_data = 1 << 28; /* start of the data (256 MB = max) */ -unsigned long end_data = 0; /* end of the data */ -/* true? cramfs_super < start_inode < end_inode <= start_data <= end_data */ -static uid_t euid; /* effective UID */ +/* Exit codes used by fsck-type programs */ +#define FSCK_OK 0 /* No errors */ +#define FSCK_NONDESTRUCT 1 /* File system errors corrected */ +#define FSCK_REBOOT 2 /* System should be rebooted */ +#define FSCK_UNCORRECTED 4 /* File system errors left uncorrected */ +#define FSCK_ERROR 8 /* Operational error */ +#define FSCK_USAGE 16 /* Usage or syntax error */ +#define FSCK_LIBRARY 128 /* Shared library error */ #define PAD_SIZE 512 -#include -#ifdef PAGE_SIZE -#define PAGE_CACHE_SIZE ((int) PAGE_SIZE) -#elif defined __ia64__ -#define PAGE_CACHE_SIZE (16384) -#elif defined __alpha__ -#define PAGE_CACHE_SIZE (8192) -#else -#define PAGE_CACHE_SIZE (4096) -#endif +#ifdef INCLUDE_FS_TESTS + +static int opt_extract = 0; /* extract cramfs (-x) */ + +static uid_t euid; /* effective UID */ + +/* (cramfs_super + start) <= start_dir < end_dir <= start_data <= end_data */ +static unsigned long start_dir = ~0UL; /* start of first non-root inode */ +static unsigned long end_dir = 0; /* end of the directory structure */ +static unsigned long start_data = ~0UL; /* start of the data (256 MB = max) */ +static unsigned long end_data = 0; /* end of the data */ + /* Guarantee access to at least 8kB at a time */ #define ROMBUFFER_BITS 13 @@ -93,12 +100,16 @@ static uid_t euid; /* effective UID */ static char read_buffer[ROMBUFFERSIZE * 2]; static unsigned long read_buffer_block = ~0UL; -/* Uncompressing data structures... */ -static char outbuffer[PAGE_CACHE_SIZE*2]; -z_stream stream; +static z_stream stream; +/* Prototypes */ +static void expand_fs(char *, struct cramfs_inode *); #endif /* INCLUDE_FS_TESTS */ +static char *outbuffer; + +static size_t page_size; + /* Input status of 0 to print help and exit without an error. */ static void usage(int status) { @@ -113,6 +124,157 @@ static void usage(int status) exit(status); } +static void die(int status, int syserr, const char *fmt, ...) +{ + va_list arg_ptr; + int save = errno; + + fflush(0); + va_start(arg_ptr, fmt); + fprintf(stderr, "%s: ", progname); + vfprintf(stderr, fmt, arg_ptr); + if (syserr) { + fprintf(stderr, ": %s", strerror(save)); + } + fprintf(stderr, "\n"); + va_end(arg_ptr); + exit(status); +} + +static void test_super(int *start, size_t *length) { + struct stat st; + + /* find the physical size of the file or block device */ + if (stat(filename, &st) < 0) { + die(FSCK_ERROR, 1, "stat failed: %s", filename); + } + fd = open(filename, O_RDONLY); + if (fd < 0) { + die(FSCK_ERROR, 1, "open failed: %s", filename); + } + if (S_ISBLK(st.st_mode)) { + if (ioctl(fd, BLKGETSIZE, length) < 0) { + die(FSCK_ERROR, 1, "ioctl failed: unable to determine device size: %s", filename); + } + *length = *length * 512; + } + else if (S_ISREG(st.st_mode)) { + *length = st.st_size; + } + else { + die(FSCK_ERROR, 0, "not a block device or file: %s", filename); + } + + if (*length < sizeof(struct cramfs_super)) { + die(FSCK_UNCORRECTED, 0, "file length too short"); + } + + /* find superblock */ + if (read(fd, &super, sizeof(super)) != sizeof(super)) { + die(FSCK_ERROR, 1, "read failed: %s", filename); + } + if (super.magic == CRAMFS_MAGIC) { + *start = 0; + } + else if (*length >= (PAD_SIZE + sizeof(super))) { + lseek(fd, PAD_SIZE, SEEK_SET); + if (read(fd, &super, sizeof(super)) != sizeof(super)) { + die(FSCK_ERROR, 1, "read failed: %s", filename); + } + if (super.magic == CRAMFS_MAGIC) { + *start = PAD_SIZE; + } + } + + /* superblock tests */ + if (super.magic != CRAMFS_MAGIC) { + die(FSCK_UNCORRECTED, 0, "superblock magic not found"); + } + if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) { + die(FSCK_ERROR, 0, "unsupported filesystem features"); + } + if (super.size < page_size) { + die(FSCK_UNCORRECTED, 0, "superblock size (%d) too small", super.size); + } + if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) { + if (super.fsid.files == 0) { + die(FSCK_UNCORRECTED, 0, "zero file count"); + } + if (*length < super.size) { + die(FSCK_UNCORRECTED, 0, "file length too short"); + } + else if (*length > super.size) { + fprintf(stderr, "warning: file extends past end of filesystem\n"); + } + } + else { + fprintf(stderr, "warning: old cramfs format\n"); + } +} + +static void test_crc(int start) +{ + void *buf; + u32 crc; + + if (!(super.flags & CRAMFS_FLAG_FSID_VERSION_2)) { +#ifdef INCLUDE_FS_TESTS + return; +#else /* not INCLUDE_FS_TESTS */ + die(FSCK_USAGE, 0, "unable to test CRC: old cramfs format"); +#endif /* not INCLUDE_FS_TESTS */ + } + + crc = crc32(0L, Z_NULL, 0); + + buf = mmap(NULL, super.size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if (buf == MAP_FAILED) { + buf = mmap(NULL, super.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (buf != MAP_FAILED) { + lseek(fd, 0, SEEK_SET); + read(fd, buf, super.size); + } + } + if (buf != MAP_FAILED) { + ((struct cramfs_super *) (buf+start))->fsid.crc = crc32(0L, Z_NULL, 0); + crc = crc32(crc, buf+start, super.size-start); + munmap(buf, super.size); + } + else { + int retval; + size_t length = 0; + + buf = malloc(4096); + if (!buf) { + die(FSCK_ERROR, 1, "malloc failed"); + } + lseek(fd, start, SEEK_SET); + for (;;) { + retval = read(fd, buf, 4096); + if (retval < 0) { + die(FSCK_ERROR, 1, "read failed: %s", filename); + } + else if (retval == 0) { + break; + } + if (length == 0) { + ((struct cramfs_super *) buf)->fsid.crc = crc32(0L, Z_NULL, 0); + } + length += retval; + if (length > (super.size-start)) { + crc = crc32(crc, buf, retval - (length - (super.size-start))); + break; + } + crc = crc32(crc, buf, retval); + } + free(buf); + } + + if (crc != super.fsid.crc) { + die(FSCK_UNCORRECTED, 0, "crc error"); + } +} + #ifdef INCLUDE_FS_TESTS static void print_node(char type, struct cramfs_inode *i, char *name) { @@ -148,6 +310,10 @@ static void *romfs_read(unsigned long offset) static struct cramfs_inode *cramfs_iget(struct cramfs_inode * i) { struct cramfs_inode *inode = malloc(sizeof(struct cramfs_inode)); + + if (!inode) { + die(FSCK_ERROR, 1, "malloc failed"); + } *inode = *i; return inode; } @@ -157,29 +323,27 @@ static struct cramfs_inode *iget(unsigned int ino) return cramfs_iget(romfs_read(ino)); } -#if 0 static void iput(struct cramfs_inode *inode) { free(inode); } -#endif /* - * Return the offset of the root directory, - * or 0 if none. + * Return the offset of the root directory */ static struct cramfs_inode *read_super(void) { - unsigned long offset; - - offset = super->root.offset << 2; - if (super->magic != CRAMFS_MAGIC) - return NULL; - if (memcmp(super->signature, CRAMFS_SIGNATURE, sizeof(super->signature)) != 0) - return NULL; - if (offset < sizeof(super)) - return NULL; - return cramfs_iget(&super->root); + unsigned long offset = super.root.offset << 2; + + if (!S_ISDIR(super.root.mode)) + die(FSCK_UNCORRECTED, 0, "root inode is not directory"); + if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) && + ((offset != sizeof(struct cramfs_super)) && + (offset != PAD_SIZE + sizeof(struct cramfs_super)))) + { + die(FSCK_UNCORRECTED, 0, "bad root offset (%lu)", offset); + } + return cramfs_iget(&super.root); } static int uncompress_block(void *src, int len) @@ -190,16 +354,17 @@ static int uncompress_block(void *src, int len) stream.avail_in = len; stream.next_out = (unsigned char *) outbuffer; - stream.avail_out = PAGE_CACHE_SIZE*2; + stream.avail_out = page_size*2; inflateReset(&stream); + if (len > page_size*2) { + die(FSCK_UNCORRECTED, 0, "data block too large"); + } err = inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { - fprintf(stderr, - _("%s: error %d while decompressing! %p(%d)\n"), - filename, err, src, len); - exit(4); + die(FSCK_UNCORRECTED, 0, "decompression error %p(%d): %s", + zError(err), src, len); } return stream.total_out; } @@ -207,6 +372,51 @@ static int uncompress_block(void *src, int len) #if !HAVE_LCHOWN #define lchown chown #endif +static void do_uncompress(char *path, int fd, unsigned long offset, unsigned long size) +{ + unsigned long curr = offset + 4 * ((size + page_size - 1) / page_size); + + do { + unsigned long out = page_size; + unsigned long next = *(u32 *) romfs_read(offset); + + if (next > end_data) { + end_data = next; + } + + offset += 4; + if (curr == next) { + if (opt_verbose > 1) { + printf(" hole at %ld (%d)\n", curr, page_size); + } + if (size < page_size) + out = size; + memset(outbuffer, 0x00, out); + } + else { + if (opt_verbose > 1) { + printf(" uncompressing block at %ld to %ld (%ld)\n", curr, next, next - curr); + } + out = uncompress_block(romfs_read(curr), next - curr); + } + if (size >= page_size) { + if (out != page_size) { + die(FSCK_UNCORRECTED, 0, "non-block (%ld) bytes", out); + } + } else { + if (out != size) { + die(FSCK_UNCORRECTED, 0, "non-size (%ld vs %ld) bytes", out, size); + } + } + size -= out; + if (opt_extract) { + if (write(fd, outbuffer, out) < 0) { + die(FSCK_ERROR, 1, "write failed: %s", path); + } + } + curr = next; + } while (size); +} static void change_file_status(char *path, struct cramfs_inode *i) { @@ -214,23 +424,114 @@ static void change_file_status(char *path, struct cramfs_inode *i) if (euid == 0) { if (lchown(path, i->uid, i->gid) < 0) { - perror(path); - exit(8); + die(FSCK_ERROR, 1, "lchown failed: %s", path); } if (S_ISLNK(i->mode)) return; if ((S_ISUID | S_ISGID) & i->mode) { if (chmod(path, i->mode) < 0) { - perror(path); - exit(8); + die(FSCK_ERROR, 1, "chown failed: %s", path); } } } if (S_ISLNK(i->mode)) return; if (utime(path, &epoch) < 0) { - perror(path); - exit(8); + die(FSCK_ERROR, 1, "utime failed: %s", path); + } +} + +static void do_directory(char *path, struct cramfs_inode *i) +{ + int pathlen = strlen(path); + int count = i->size; + unsigned long offset = i->offset << 2; + char *newpath = malloc(pathlen + 256); + + if (!newpath) { + die(FSCK_ERROR, 1, "malloc failed"); + } + if (offset == 0 && count != 0) { + die(FSCK_UNCORRECTED, 0, "directory inode has zero offset and non-zero size: %s", path); + } + if (offset != 0 && offset < start_dir) { + start_dir = offset; + } + /* TODO: Do we need to check end_dir for empty case? */ + memcpy(newpath, path, pathlen); + newpath[pathlen] = '/'; + pathlen++; + if (opt_verbose) { + print_node('d', i, path); + } + if (opt_extract) { + if (mkdir(path, i->mode) < 0) { + die(FSCK_ERROR, 1, "mkdir failed: %s", path); + } + change_file_status(path, i); + } + while (count > 0) { + struct cramfs_inode *child = iget(offset); + int size; + int newlen = child->namelen << 2; + + size = sizeof(struct cramfs_inode) + newlen; + count -= size; + + offset += sizeof(struct cramfs_inode); + + memcpy(newpath + pathlen, romfs_read(offset), newlen); + newpath[pathlen + newlen] = 0; + if (newlen == 0) { + die(FSCK_UNCORRECTED, 0, "filename length is zero"); + } + if ((pathlen + newlen) - strlen(newpath) > 3) { + die(FSCK_UNCORRECTED, 0, "bad filename length"); + } + expand_fs(newpath, child); + + offset += newlen; + + if (offset <= start_dir) { + die(FSCK_UNCORRECTED, 0, "bad inode offset"); + } + if (offset > end_dir) { + end_dir = offset; + } + iput(child); /* free(child) */ + } + free(newpath); +} + +static void do_file(char *path, struct cramfs_inode *i) +{ + unsigned long offset = i->offset << 2; + int fd = 0; + + if (offset == 0 && i->size != 0) { + die(FSCK_UNCORRECTED, 0, "file inode has zero offset and non-zero size"); + } + if (i->size == 0 && offset != 0) { + die(FSCK_UNCORRECTED, 0, "file inode has zero size and non-zero offset"); + } + if (offset != 0 && offset < start_data) { + start_data = offset; + } + if (opt_verbose) { + print_node('f', i, path); + } + if (opt_extract) { + fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, i->mode); + if (fd < 0) { + die(FSCK_ERROR, 1, "open failed: %s", path); + } + } + if (i->size) { + do_uncompress(path, fd, offset, i->size); + } + if (opt_extract) { + close(fd); + change_file_status(path, i); } } @@ -241,34 +542,39 @@ static void do_symlink(char *path, struct cramfs_inode *i) unsigned long next = *(u32 *) romfs_read(offset); unsigned long size; + if (offset == 0) { + die(FSCK_UNCORRECTED, 0, "symbolic link has zero offset"); + } + if (i->size == 0) { + die(FSCK_UNCORRECTED, 0, "symbolic link has zero size"); + } + + if (offset < start_data) { + start_data = offset; + } if (next > end_data) { end_data = next; } size = uncompress_block(romfs_read(curr), next - curr); if (size != i->size) { - fprintf(stderr, _("%s: size error in symlink `%s'\n"), - filename, path); - exit(4); + die(FSCK_UNCORRECTED, 0, "size error in symlink: %s", path); } outbuffer[size] = 0; if (opt_verbose) { char *str; - str = malloc(strlen(outbuffer) + strlen(path) + 5); - strcpy(str, path); - strncat(str, " -> ", 4); - strncat(str, outbuffer, size); - + asprintf(&str, "%s -> %s", path, outbuffer); print_node('l', i, str); if (opt_verbose > 1) { - printf(_(" uncompressing block at %ld " - "to %ld (%ld)\n"), - curr, next, next - curr); + printf(" uncompressing block at %ld to %ld (%ld)\n", curr, next, next - curr); } + free(str); } if (opt_extract) { - symlink(outbuffer, path); + if (symlink(outbuffer, path) < 0) { + die(FSCK_ERROR, 1, "symlink failed: %s", path); + } change_file_status(path, i); } } @@ -278,6 +584,9 @@ static void do_special_inode(char *path, struct cramfs_inode *i) dev_t devtype = 0; char type; + if (i->offset) { /* no need to shift offset */ + die(FSCK_UNCORRECTED, 0, "special file has non-zero offset: %s", path); + } if (S_ISCHR(i->mode)) { devtype = i->size; type = 'c'; @@ -286,14 +595,21 @@ static void do_special_inode(char *path, struct cramfs_inode *i) devtype = i->size; type = 'b'; } - else if (S_ISFIFO(i->mode)) + else if (S_ISFIFO(i->mode)) { + if (i->size != 0) { + die(FSCK_UNCORRECTED, 0, "fifo has non-zero size: %s", path); + } type = 'p'; - else if (S_ISSOCK(i->mode)) + } + else if (S_ISSOCK(i->mode)) { + if (i->size != 0) { + die(FSCK_UNCORRECTED, 0, "socket has non-zero size: %s", path); + } type = 's'; + } else { - fprintf(stderr, _("%s: bogus mode on `%s' (%o)\n"), - filename, path, i->mode); - exit(4); + die(FSCK_UNCORRECTED, 0, "bogus mode: %s (%o)", path, i->mode); + return; /* not reached */ } if (opt_verbose) { @@ -302,183 +618,84 @@ static void do_special_inode(char *path, struct cramfs_inode *i) if (opt_extract) { if (mknod(path, i->mode, devtype) < 0) { - perror(path); - exit(8); + die(FSCK_ERROR, 1, "mknod failed: %s", path); } change_file_status(path, i); } } -static void do_uncompress(int fd, unsigned long offset, unsigned long size) +static void expand_fs(char *path, struct cramfs_inode *inode) { - unsigned long curr = offset + 4 * ((size + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE); - - do { - unsigned long out = PAGE_CACHE_SIZE; - unsigned long next = *(u32 *) romfs_read(offset); - - if (next > end_data) - end_data = next; - - offset += 4; - if (curr == next) { - if (opt_verbose > 1) { - printf(_(" hole at %ld (%d)\n"), - curr, PAGE_CACHE_SIZE); - } - if (size < PAGE_CACHE_SIZE) - out = size; - memset(outbuffer, 0x00, out); - } - else { - if (opt_verbose > 1) { - printf(_(" uncompressing block at %ld " - "to %ld (%ld)\n"), - curr, next, next - curr); - } - out = uncompress_block(romfs_read(curr), next - curr); - } - if (size >= PAGE_CACHE_SIZE) { - if (out != PAGE_CACHE_SIZE) { - fprintf(stderr, - _("%s: Non-block (%ld) bytes\n"), - filename, out); - exit(4); - } - } else { - if (out != size) { - fprintf(stderr, _("%s: Non-size (%ld vs %ld) " - "bytes\n"), - filename, out, size); - exit(4); - } - } - size -= out; - if (opt_extract) { - write(fd, outbuffer, out); - } - curr = next; - } while (size); + if (S_ISDIR(inode->mode)) { + do_directory(path, inode); + } + else if (S_ISREG(inode->mode)) { + do_file(path, inode); + } + else if (S_ISLNK(inode->mode)) { + do_symlink(path, inode); + } + else { + do_special_inode(path, inode); + } } -static void expand_fs(int pathlen, char *path, struct cramfs_inode *inode) +static void test_fs(int start) { - if (S_ISDIR(inode->mode)) { - int count = inode->size; - unsigned long offset = inode->offset << 2; - char *newpath = malloc(pathlen + 256); - - if (count > 0 && offset < start_inode) { - start_inode = offset; - } - /* XXX - need to check end_inode for empty case? */ - memcpy(newpath, path, pathlen); - newpath[pathlen] = '/'; - pathlen++; - if (opt_verbose) { - print_node('d', inode, path); - } - if (opt_extract) { - mkdir(path, inode->mode); - change_file_status(path, inode); - } - while (count > 0) { - struct cramfs_inode *child = iget(offset); - int size; - int newlen = child->namelen << 2; - - size = sizeof(struct cramfs_inode) + newlen; - count -= size; - - offset += sizeof(struct cramfs_inode); - - memcpy(newpath + pathlen, romfs_read(offset), newlen); - newpath[pathlen + newlen] = 0; - if ((pathlen + newlen) - strlen(newpath) > 3) { - fprintf(stderr, - _("%s: invalid cramfs--bad " - "path length\n"), - filename); - exit(4); - } - expand_fs(strlen(newpath), newpath, child); - - offset += newlen; - - if (offset > end_inode) { - end_inode = offset; - } - } - return; - } - if (S_ISREG(inode->mode)) { - int fd = 0; - unsigned long offset = inode->offset << 2; + struct cramfs_inode *root; - if (offset > 0 && offset < start_data) { - start_data = offset; - } - if (opt_verbose) { - print_node('f', inode, path); - } - if (opt_extract) { - fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, inode->mode); - } - if (inode->size) { - do_uncompress(fd, offset, inode->size); + root = read_super(); + umask(0); + euid = geteuid(); + stream.next_in = NULL; + stream.avail_in = 0; + inflateInit(&stream); + expand_fs(extract_dir, root); + inflateEnd(&stream); + if (start_data != ~0UL) { + if (start_data < (sizeof(struct cramfs_super) + start)) { + die(FSCK_UNCORRECTED, 0, "directory data start (%ld) < sizeof(struct cramfs_super) + start (%ld)", start_data, sizeof(struct cramfs_super) + start); } - if (opt_extract) { - close(fd); - change_file_status(path, inode); + if (end_dir != start_data) { + die(FSCK_UNCORRECTED, 0, "directory data end (%ld) != file data start (%ld)", end_dir, start_data); } - return; } - if (S_ISLNK(inode->mode)) { - unsigned long offset = inode->offset << 2; - - if (offset < start_data) { - start_data = offset; + if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) { + if (end_data > super.size) { + die(FSCK_UNCORRECTED, 0, "invalid file data offset"); } - do_symlink(path, inode); - return; - } - else { - do_special_inode(path, inode); - return; } + iput(root); /* free(root) */ } #endif /* INCLUDE_FS_TESTS */ int main(int argc, char **argv) { - void *buf; - size_t length; - struct stat st; - u32 crc_old, crc_new; -#ifdef INCLUDE_FS_TESTS - struct cramfs_inode *root; -#endif /* INCLUDE_FS_TESTS */ int c; /* for getopt */ int start = 0; + size_t length; + + page_size = sysconf(_SC_PAGESIZE); if (argc) progname = argv[0]; + outbuffer = malloc(page_size * 2); + if (!outbuffer) + die(FSCK_ERROR, 1, "failed to allocate outbuffer"); + /* command line options */ while ((c = getopt(argc, argv, "hx:v")) != EOF) { switch (c) { case 'h': - usage(0); + usage(FSCK_OK); case 'x': #ifdef INCLUDE_FS_TESTS opt_extract = 1; - extract_dir = malloc(strlen(optarg) + 1); - strcpy(extract_dir, optarg); + extract_dir = optarg; break; -#else /* not INCLUDE_FS_TESTS */ - fprintf(stderr, _("%s: compiled without -x support\n"), - progname); - exit(16); +#else /* not INCLUDE_FS_TESTS */ + die(FSCK_USAGE, 0, "compiled without -x support"); #endif /* not INCLUDE_FS_TESTS */ case 'v': opt_verbose++; @@ -487,146 +704,18 @@ int main(int argc, char **argv) } if ((argc - optind) != 1) - usage(16); + usage(FSCK_USAGE); filename = argv[optind]; - /* find the physical size of the file or block device */ - if (lstat(filename, &st) < 0) { - perror(filename); - exit(8); - } - fd = open(filename, O_RDONLY); - if (fd < 0) { - perror(filename); - exit(8); - } - if (S_ISBLK(st.st_mode)) { - if (ioctl(fd, BLKGETSIZE, &length) < 0) { - fprintf(stderr, _("%s: warning--unable to determine " - "filesystem size \n"), filename); - exit(4); - } - length = length * 512; - } - else if (S_ISREG(st.st_mode)) { - length = st.st_size; - } - else { - fprintf(stderr, _("%s is not a block device or file\n"), - filename); - exit(8); - } - - if (length < sizeof(struct cramfs_super)) { - fprintf(stderr, _("%s: invalid cramfs--file length " - "too short\n"), filename); - exit(4); - } - - if (S_ISBLK(st.st_mode)) { - /* nasty because mmap of block devices fails */ - buf = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - read(fd, buf, length); - } - else { - /* nice and easy */ - buf = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - } - - /* XXX - this could be cleaner... */ - if (((struct cramfs_super *) buf)->magic == CRAMFS_MAGIC) { - start = 0; - super = (struct cramfs_super *) buf; - } - else if (length >= (PAD_SIZE + sizeof(struct cramfs_super)) && - ((((struct cramfs_super *) (buf + PAD_SIZE))->magic == CRAMFS_MAGIC))) - { - start = PAD_SIZE; - super = (struct cramfs_super *) (buf + PAD_SIZE); - } - else { - fprintf(stderr, _("%s: invalid cramfs--wrong magic\n"), - filename); - exit(4); - } - - if (super->flags & CRAMFS_FLAG_FSID_VERSION_2) { - /* length test */ - if (length < super->size) { - fprintf(stderr, _("%s: invalid cramfs--file length " - "too short\n"), filename); - exit(4); - } - else if (length > super->size) { - fprintf(stderr, _("%s: warning--file length too long, " - "padded image?\n"), filename); - } - - /* CRC test */ - crc_old = super->fsid.crc; - super->fsid.crc = crc32(0L, Z_NULL, 0); - crc_new = crc32(0L, Z_NULL, 0); - crc_new = crc32(crc_new, (unsigned char *) buf+start, super->size - start); - if (crc_new != crc_old) { - fprintf(stderr, _("%s: invalid cramfs--crc error\n"), - filename); - exit(4); - } - } - else { - fprintf(stderr, _("%s: warning--old cramfs image, no CRC\n"), - filename); - } - + test_super(&start, &length); + test_crc(start); #ifdef INCLUDE_FS_TESTS - super = (struct cramfs_super *) malloc(sizeof(struct cramfs_super)); - if (((struct cramfs_super *) buf)->magic == CRAMFS_MAGIC) { - memcpy(super, buf, sizeof(struct cramfs_super)); - } - else if (length >= (PAD_SIZE + sizeof(struct cramfs_super)) && - ((((struct cramfs_super *) (buf + PAD_SIZE))->magic == CRAMFS_MAGIC))) - { - memcpy(super, (buf + PAD_SIZE), sizeof(struct cramfs_super)); - } - - munmap(buf, length); - - /* file format test, uses fake "blocked" accesses */ - root = read_super(); - umask(0); - euid = geteuid(); - if (!root) { - fprintf(stderr, _("%s: invalid cramfs--bad superblock\n"), - filename); - exit(4); - } - stream.next_in = NULL; - stream.avail_in = 0; - inflateInit(&stream); - - if (!extract_dir) - extract_dir = "root"; - - expand_fs(strlen(extract_dir), extract_dir, root); - inflateEnd(&stream); + test_fs(start); +#endif /* INCLUDE_FS_TESTS */ - if (start_data != 1 << 28 && end_inode != start_data) { - fprintf(stderr, - _("%s: invalid cramfs--directory data end " - "(%ld) != file data start (%ld)\n"), - filename, end_inode, start_data); - exit(4); - } - if (super->flags & CRAMFS_FLAG_FSID_VERSION_2) { - if (end_data > super->size) { - fprintf(stderr, - _("%s: invalid cramfs--invalid file " - "data offset\n"), - filename); - exit(4); - } + if (opt_verbose) { + printf("%s: OK\n", filename); } -#endif /* INCLUDE_FS_TESTS */ - exit(0); + exit(FSCK_OK); } diff --git a/disk-utils/mkfs.cramfs.c b/disk-utils/mkfs.cramfs.c index f204364e..32891285 100644 --- a/disk-utils/mkfs.cramfs.c +++ b/disk-utils/mkfs.cramfs.c @@ -1,7 +1,7 @@ /* * mkcramfs - make a cramfs file system * - * Copyright (C) 1999-2001 Transmeta Corporation + * Copyright (C) 1999-2002 Transmeta Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,27 +35,25 @@ #include #include #include +#include #include #include "cramfs.h" #include "md5.h" #include "nls.h" -#define PAD_SIZE 512 /* only 0 and 512 supported by kernel */ +/* Exit codes used by mkfs-type programs */ +#define MKFS_OK 0 /* No errors */ +#define MKFS_ERROR 8 /* Operational error */ +#define MKFS_USAGE 16 /* Usage or syntax error */ + +/* The kernel only supports PAD_SIZE of 0 and 512. */ +#define PAD_SIZE 512 static const char *progname = "mkcramfs"; static int verbose = 0; -#ifdef __ia64__ -#define PAGE_CACHE_SIZE (16384) -#elif defined __alpha__ -#define PAGE_CACHE_SIZE (8192) -#else -#define PAGE_CACHE_SIZE (4096) -#endif - -/* The kernel assumes PAGE_CACHE_SIZE as block size. */ -static unsigned int blksize = PAGE_CACHE_SIZE; /* settable via -b option */ +static unsigned int blksize; /* settable via -b option */ static long total_blocks = 0, total_nodes = 1; /* pre-count the root node */ static int image_length = 0; @@ -88,7 +86,7 @@ static int warn_uid = 0; /* In-core version of inode / directory entry. */ struct entry { /* stats */ - char *name; + unsigned char *name; unsigned int mode, size, uid, gid; unsigned char md5sum[16]; unsigned char flags; @@ -97,6 +95,7 @@ struct entry { /* FS data */ char *path; + int fd; /* temporarily open files while mmapped */ struct entry *same; /* points to other identical file */ unsigned int offset; /* pointer to compressed data in archive */ unsigned int dir_offset; /* offset of directory entry in archive */ @@ -121,13 +120,13 @@ usage(int status) { FILE *stream = status ? stderr : stdout; fprintf(stream, - _("usage: %s [-h] [-v] [-b blksz] [-e edition] [-i file] " + _("usage: %s [-h] [-v] [-b blksize] [-e edition] [-i file] " "[-n name] dirname outfile\n" " -h print this help\n" " -v be verbose\n" " -E make all warnings errors " "(non-zero exit status)\n" - " -b blksz use this blocksize, must equal page size\n" + " -b blksize use this blocksize, must equal page size\n" " -e edition set edition number (part of fsid)\n" " -i file insert a file image into the filesystem " "(requires >= 2.4.0)\n" @@ -730,6 +729,7 @@ int main(int argc, char **argv) u32 crc = crc32(0L, Z_NULL, 0); int c; + blksize = sysconf(_SC_PAGESIZE); total_blocks = 0; if (argc) { diff --git a/mount/fstab.c b/mount/fstab.c index 1a7ce4e5..1bedcf4b 100644 --- a/mount/fstab.c +++ b/mount/fstab.c @@ -46,7 +46,7 @@ mtab_does_not_exist(void) { return var_mtab_does_not_exist; } -int +static int mtab_is_a_symlink(void) { get_mtab_info(); return var_mtab_is_a_symlink; @@ -54,7 +54,7 @@ mtab_is_a_symlink(void) { int mtab_is_writable() { - static int ret = -1; + int fd; /* Should we write to /etc/mtab upon an update? Probably not if it is a symlink to /proc/mounts, since that @@ -63,15 +63,12 @@ mtab_is_writable() { if (mtab_is_a_symlink()) return 0; - if (ret == -1) { - int fd = open(MOUNTED, O_RDWR | O_CREAT, 0644); - if (fd >= 0) { - close(fd); - ret = 1; - } else - ret = 0; - } - return ret; + fd = open(MOUNTED, O_RDWR | O_CREAT, 0644); + if (fd >= 0) { + close(fd); + return 1; + } else + return 0; } /* Contents of mtab and fstab ---------------------------------*/ @@ -572,7 +569,7 @@ update_mtab (const char *dir, struct my_mntent *instead) { struct mntentchn mtabhead; /* dummy */ struct mntentchn *mc, *mc0, *absent = NULL; - if (mtab_does_not_exist() || mtab_is_a_symlink()) + if (mtab_does_not_exist() || !mtab_is_writable()) return; lock_mtab(); diff --git a/mount/fstab.h b/mount/fstab.h index 5cc53668..f1d4e5c6 100644 --- a/mount/fstab.h +++ b/mount/fstab.h @@ -1,7 +1,6 @@ #include "mntent.h" int mtab_is_writable(void); int mtab_does_not_exist(void); -int mtab_is_a_symlink(void); int is_mounted_once(const char *name); struct mntentchn { diff --git a/mount/mount.8 b/mount/mount.8 index 59a5e91a..736cd6e7 100644 --- a/mount/mount.8 +++ b/mount/mount.8 @@ -582,6 +582,9 @@ until the network has been enabled on the system). Do not update inode access times on this file system (e.g, for faster access on the news spool to speed up news servers). .TP +.B nodiratime +Do not update directory inode access times on this filesystem. +.TP .B noauto Can only be mounted explicitly (i.e., the .B \-a diff --git a/mount/umount.c b/mount/umount.c index 80030c9e..676ed8cc 100644 --- a/mount/umount.c +++ b/mount/umount.c @@ -349,7 +349,8 @@ umount_one (const char *spec, const char *node, const char *type, remnt.mnt_type = remnt.mnt_fsname = NULL; remnt.mnt_dir = xstrdup(node); remnt.mnt_opts = xstrdup("ro"); - update_mtab(node, &remnt); + if (!nomtab) + update_mtab(node, &remnt); return 0; } else if (errno != EBUSY) { /* hmm ... */ perror("remount"); @@ -402,7 +403,7 @@ umount_one (const char *spec, const char *node, const char *type, del_loop(loopdev); writemtab: - if (!nomtab && mtab_is_writable() && + if (!nomtab && (umnt_err == 0 || umnt_err == EINVAL || umnt_err == ENOENT)) { update_mtab (node, NULL); } diff --git a/po/Makefile.in.in b/po/Makefile.in.in index 22eddd19..15c644f2 100644 --- a/po/Makefile.in.in +++ b/po/Makefile.in.in @@ -23,7 +23,7 @@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ -datadir = @prefix@/usr/share +datadir = $(prefix)/usr/share localedir = $(datadir)/locale gettextsrcdir = $(datadir)/gettext/po diff --git a/po/ca.gmo b/po/ca.gmo index 74d4784c4d326839d61f4f71ac2035d215da6cb5..27ec1990cd941507c572426054f369971e177165 100644 GIT binary patch delta 40925 zcmZ791#}n3;`Z@Pf`=d>xCIXu+#v}X+}+*Xi!Ih-#oeK}ySsaF_u}qu@Avu5VnuH&S^H<$?H&vTq^j^jGP1X7al59YxAm>u6^ z2&S9wIG4N}r#TKGUTA^iB*8rx2d|+oK0{Uf34<`sLdWsL0@iShLA(a4d}EwO`%Yg1 z^+*U<vUfJ5F-kjH&Pf=EaW~fLWI~PAe>i8kyy&j_kz2co9=$?WK;B z4f|p|T!H?y@9ZI<9-Tvt#0v~Wzh&kPgE1}fP)vc%u@ECN#HR0A?l|d5zmI#-cZK83 z;Q2`$NW9f5jkDuC#;MqPwV4WM4e9D}S^}E;yw++MNW3$~#_?DJ=cDHGA!fjMYfZjF zn3#Bd)LQ6?VK@ObQs-?v#yUoccsVSNW7g3xb>N(Ra3A$18P*#sqB8bC4e2&)r~KFn zLpC^0PF#%|!Mj)kzhh>sy3wqm0jPYtkoE1n#)Oz<6XT+cB{n%u5$ue5)74lB-(dkP zzS(hdV}C4<>oE*}VOb2@Vk#bGJ%ag2_u1+=d9VdR4lIBVt${nui`K=0q`T7y#2|3q zddvF6`W`hxzc3Ip?=rigJZdqv#UwZa6XQbE8rhBN$TJK?zujhA2BYG&FuB%cZvrYf z1+(K?)Lh-g1Q@W#?262&hRUHj)Do${nP8u<#YDuV&I|TKzpy70$toxXV6&gsF)8?KkzO$2n4w{FkIg5Y5yh#|UKpj+iZ`7(^fEuZI2hALou)0`=^zEoM6zPze>q1zX z_#YU8`>_Oi9p>eW5GX}Ji*G2Z!JVi@b=~^N`p)_bRe|pjlfSaH6Q(153~DMiVgR19 z@&8a$`VHfw|53(Y8H0|R4iv?N#Q(t9I3CrZ`KUFr7uCQuOoq-eGsMX;4bhV5k8M!p z`k~6rM0I2nssqPS?cP1c_-iP?lAwk&A2$|9eLU)+GPXhWcrYf#X{d@fqVoNV8o?W= z#T9VE&ONGQwNUAOu^>*tjCj^1P>jGgRF6YWnvX*REI_;qYX7f5P1Q}Cp7fMSuYn~= zABO6{Db(CY{?{~A7)ulHh52zWs=hB67v0RKO;3xUDrkY3a5gIAQ7npIu`(7uWAcwi zO~oeEn_S0e82PN@M8#Mb855w=lVK!GhcPe{G8L|qhd@~p%41BNip6muYUm%MM#Afy zsWhXLhb*_1XSTF)FL@-Gh9c_^%snV z@h_MYEG_EIE1)lSv%07?F$$G`5yr)hsF65~8i|vr_AX+m_Ww%)S{%U_%|TQKwY_>_ zdfbU>=pOpvE7U6ffm*Zym(0%zSuh*%BB%qW0|w$)48^sm#rPWa0s)s9|H=dk5-5kG zumWDj=$P(`nVM{<9{0i6I1%-R3otjXM@`)$jDzn{Zyx!o`T8Y9O<@I0jKfgdcm7qz zKLdf?BxnR4VovnBX0~N+RJ;X-<1|!9@1PpYa@|y10CN%VhH795sssBlDW13KuP_Pm z=r_zrroF-Vt0y^0kd-hiwnr75fqJ9O7=%Y~IKIZ4_y_-^3TxdmL){g%`X{2MZYIXV z{g@0dVMTn0Ik1>}+i_|V=#JI!1g5~0cg&E7U~=NMFxZ=)gis@}@IN!OuTi@t{XMha z+oHDPBGd?-#x!^XHRsNK(~ z5pRjvaRzEgPoO&f1Jz)%$L57{qt-@QYjcdN{Xc*}S{{r;4b>)81y`{YenuTEp-;@( zXp4cwr=dn<8wTJR%zzJUy5CdNfwZW#RM^IAqh6#ldVc<&No|}d;R>GsG7fAG)`S%Rz zYxCJ`fZ2I42{rVGtdFeG-S6)n^D!8&qoyXtTeGXOV_xDdQEOy2>iHp; zfO`H6YoYVbd?ae4My3ho$G)h=xzVOyL6v)paWLw8Gct+LpLhn;&=_;0#4MQgyGgH$8nFSW z4sSu7p#Ne3K1X%b>xXs$^BQt1@cQ)kcj(Q;d%tQLB5XjjzT);s;T0 z_`t?v{WSGtL)DWHGh^6{W0rocI<3U;A7 zavKX`%t&6IpJu}`koY)Mhu2{qJd2uwsF6*2c2vAFY9#+ay~r5U8d?cskn8ksb{rlJtk;;Vw{Xb05PO|Y)B>1R-@{{yN6 zzc3K}V|qI7I=Kj_U`HKfaId_OARMb!4ZgW4s}QH${%YD(ky zd3kf&Y`hEcTtLt=S(e)KAds%ScD)h|LF!6z^~K0vMd1hGweZqyK0M6Hzu zsHy6JS|fjAUYv<~!E>l{mMs5Q_J zwaOQwD%^}(&Btx}UDSxZv--vJ^8B=$0kutgqDF8Esv{fYvHx`->>@#n>pp5V|3WpG zI>7X_thF*~&TFEkstIZeI-ok*5B28LP*XAwH9~7qyXqQhP5eZy5#RXi|0x85;(Iv* zaSvw3umom1wMT8AL8tVBYxG(kf1JQ=D3MNl2Cfa+Ln)aSY}s(csM zX6S>SMT6QdGf_je2vzX`^n7MfYvTuM=)Dt}lQJ>t%?epdqo%3`s=-#M{Jm{_tc|<# z2$bT%7Hp0`F()=l?B)5Ha0==TkD`Y7E^4j(K)qS6Bwo%!48dV|54C&RB{d^39<`?C zqt?te)YP3qUf6Z663{+>h3e@K)SSjjW(p)nZND6-6S664txP~2SgTM|b{#cEQIngF zrbTr;49{X6)CgxzVMeAX#@7C?Mj(s_%}}d!A*z9cs5iciT8!UpJWWb7l%c5fniz@$ zP^*78Y9y~9A3Uc>AR~%lsmwXhEw$;$1WZl)&Qb!I@C0hLenc&nz%*tz1fe=q4%I+Q z)Q}ED&qv3mFGr2sLDZX`$F%qaHG;9ynyCv#mFt17hJF|UEwahzS$x(-s5xGPs(8Ci zKZaUt=k4=5)@P`EAMNwV>C77NM|CJQs=oZFk5%z>?0=nDwMo$2wL`u6aMU6khguT{ zP(8kYI!Yg+hCXt7Q!Xo}B3>4?xZ0z(S8ptYgHRpbg?i!RsB`B^deO5Fr(>K`k^DY7P^a^Sb z-NmAqDx*33o1u>Awx}WOh?=6Is0zoRMs5zO!#hxG<&=#-M%DKfHPVGMnUSc3I$zxS z1T+_YFe{El9TdB4`UTW}euA2c*qOaNf5Zwz?T!|xh6iB~PDH)XPSlhfLXGSr)YSNA zF(Z-!>uLX|A<&NpE>_3ys3EM9)%=K52eS|#k9yZt+j2gi^HvI#t zzF(--9y_}kxg^%isPw{^Q~N)hfL3)MRKwFzBd`M1;|*8?pP?38(H!P$RtXjFhT1KI zP}_K;P2Y~{=uy=EKZlwUA5NoSOoy%tR<{Ymuq5%#mJFo(;vMSXijv3dvJ`pP|A8bFB|$btH8=!S@E_EoJB=!M2i1Yk zs3Fdh*A69W1+yPew-f%qX z06Byjfd{Cs*+&5y-iR< z*Avyi2-FCSwoXQ^_SrVR7`3=oqxSVy`~0AdpF+LRRqK6JeXnf%lZm^IcOmm22C4)8 zsGg=nbu0umLe)?s(h1ezSX2WuQ57#n?S|E;gJ>t}AbWs%q3@^@)G6%c`5Tu6m|gq7 z4uK4$k3=o1^%xKLqdIa4HKec5^L0agh9eg-i!~*x10fg_OQF6I)vyAN!~%E)wVnM# z%*d5RKkfhO1hg2MqTXn%bq4B97uona)R6DA9!9<48Ps-sgnEGlp{B#>Q6rWWH6j%- z5PPE5##HqD{%TviH%=1nKqvB5|~3^66#HIl{c%k zCaS@@m=On{7U@z)caAp!M#pEN8uaP z5Jj(O9)zP##s-)b`=F--s5d=>+6DJfi|{9^;`o)!+6hLzP;S(TSqnAi!?8S`HR-OC zqOw`ll~CKL4r-eW)oRK-kXAZo}9q1I34RF7XHgBrsb&t0{CJ&sU(_P2Ro(oY-wU;>Z=j|mUk&rT zF{3N@nNusgZNglPPJE4xZ$mAnW7q}1pms^S z#%5^$LUnjO2IGAkjPaV7=TlJU$$r#Yc!kB#zp43Z)@aK9*VnEu3HpI!4QeVL;5dxk z%w(L0O^6>xRT$LVG*APz2nS&woQaz21TDxc6wscL8x3u(f z8j(=2mFd6?)Lb6Kboc@_=kZ#bq0fa{^-Zu1_QrzvAL`sl-o|c2)Ci44bz~>%e0Ys| z(M)bzGk4W7Hwo>rC(g&^n5dmO$qu0B&DxtaQ3f0H{4}bg**loEPzSYWo1+e(zfmu+ z1ta54)cJ7_^PwB9qZz_5)Ew1C{lTC=mcf}A10P^?e2qG}zM`h$7ix`U>15VGeXL4+ z6smz+s70KhvsrYrQ0K==tWNvRUIG(Hh~LG$;ZoE{T*u-Vr>ps_R!6P+Ca57EiyG3C zsBPwSGb5241BsTxRM-kN_aiVSE=8@GO_)LZ|1<#|2%j(jf1ySopt~8$oT&7=s0urw z7VCJ_&>lez`3v;N_&vp}D*{tR`-f5EsIyO;S{G8O81PIUDKVFZ++CF)IkqZZ3( z)R0X?^?V*G{|3~XT}739k17|Xx0#ZpsJX9%I)H|uMrgXGayNh-zpkY7Xb37Ts=C#m`W0_z5*Ketpa$ONJVeET{&nq3Y>`TI3^99bVOk z{jcq_p9EF>4Ar4TeNDwVQO`@G=DrJRKTkyMf)tj`R zS)6%LBU;lXpa$AlC!i|cfg0MqHhvDZHZG&K;T=>1Pf=6!6_r0~e^YT{%t<^8YH>C~ z9azIqNA(<3JMJk0>d84&0}pJ5m#D>;e1IA1GS(WXwb8`JTcO^#8>%CHQQLGl`ru~N z4>H?PBXkQjmG6;1*tkwSra+4!Eoxg7LA^;8o8Ao7k$$Lsz7#cghfoz>L%rE+RQad_ zO?^pGyCb)aS4T}j2UJIgVJhwaNdzOk7Exqa~+J@K6y|L6h~Fq z47El&+w=*j5nYekt~*fmA4cWBj=r?-JSL#k{~lFw%)!Pa)*#gC&WjqElBf}@h1vz3 zQ624v8uD?-&^nV)Q?&@yffX2tn=uz&Mz=fx-yvqZ)kZDGF{q*1f?B<2ZTtlmARcw7 z=|E9yU28Y|!m9ckb%Opi!i?NP)Yt9+=EfJO4y7K+{?{tbI?}vh5!7NSkIK*)^}H|Y zO-G^Td@5=`uR`TNidyB*QTsk%lv(|SFobwV)V^PZnxZqPk$F3cMWckzHX+I1rl*0Z zldddkL^`8}b~@^PpGV=ZdvHd%L|%I`ys#AVc*-bXd~7PS`q#+hA}*;?A@IxPrj zdkw}woR8|jepCnUqqdRnc(WJ-Pz_{9H4uVYD|KwVIcm|ms1D6Ujqp+o#BHdNy@o}! z|9=tCTosvM-n0_tCEf|M<6_iWxQtow2NuFi6U`!PiGjqYqjt@9ER7d14?!8Jgi}mCWl-rI zQT5EkOt=NLsQ*LH_uqG_=~)g`LoHBK&=1w%98`n*P$%OP)SO0{W}c@-TU=XA3gYojXYhhaDqOW_Sv!)a!id|{{)usJHdKk5x< zpw`T0)HmZMs^igTnjcDYU>)K^QTcDpWdCa$d?i6cmtvNe(-148db|cz(LL0vk3HL* z;qft$cqUW_%Ap!+jT-WCsG;74G4U}*!4KB&s2BHf=a?bSh*~^hsES;?mPb*m)pcYL#8}EZU7lxxcx&-yn*?>A?kD(UfFVqOdUTR(- zKB{9`QLDZL>Um4lh_}}dlj_kR64K#t)V5lUS@9C;jUp{GLze^f<9A`y5SBu{VF%QU z3`5QNOq;$MHI+wE9eIGN_dBWsncU^(BNB@0Syxm=y{&&^5b=4aH#~-V^Q)+iyh4rC z7u1wQTVX0ri(145Q2DA_>!a3GOVo(CZ3*a&|3(e*M%0^~M-A;)RFAW-G;`e$)!=Yc z`c%{+JcL>!k1-H^R+)O!qB>k2wWgY)8t#KRwf|??2d7bQ`UusbIIB%X`B4qkL3L~x zYJaarE!LB$Bm50&1mdqT=SL3INESzRtQKl2y4vSsF|qdld;*%A9jFmFhpOleY6$(- znvSGLZL@Gx#g$NV*bGx*Z&XL7S$CouzJod+zM;M)>DQT#SH*iH+snS$!G8{EimLFAbY0Rko--LkXW)x~$%|XrW zdej^4$IbW%Tj}{R^Os9ej(a&bh<8G*q4Fop;v9fFkY-~6+>4r$uQ(htoHQf57L#iK zA0lv=2X|2wEj?xa35RQ_AxrtMd6R;u4zEc^Sc?&9gBtRE zXUy7picv^Ucb30Ta0z5N=jHrGhG-YOoB=o%S7NM-<_{V>P;>bSwRqxQGHW0lwQZZD zcFjoCqMe0WocB>3ig(#`un_8n8lqPJALte*FqHsjv2z_2k9EcD zC{za*VQIXA6)@FJGpC(UZ~hrWFzl9>(-B=PfiJN<=DKbEB6A>?B7WjF<6o43{~fb! zs$+NJ^H2ri-}UnR3jU%x~RpC60i7Qb@>NeEJ=BYLQLz5nc zo^u7$@O&<6ySoPnXjOm4Y?%C!nSu(a#q$>i;%d~{e;T!|USc5(dThRa%~ACXMXmN_ zs5d-^YS4?rAw8x;eJjc%BgVh~OF#{;MXky^s8#(FQ(@YtW|5Ubt$}W+3KpX}cn-Dw zzM?+E$)B10MUVr=X^R?>NvO532lWDxp6icz?Eeq~8k(-C9?nC(!4XtPUSk$a@WRY- zaa6o7>L^}{fp`eR@F8}^3@=Uo8K|i|huS4^Uzx>P0}If;Gn;@8l*{%(!q?_I-UziA zXW=9jd}CJaV$_?zK&^rJZ_SCB3Kh>`ErNREGN`E=gMqjT^OAOI7-Gy69S z>T_EX^|M=jo8A?*%12>BJb*f?uVWxSLp2ohy=fpbYJ{qwI@}Sp7N(#-Zhz1ISAkO` z=!AQY>PVCirUOY)2TD%V>MnYk`6-{uksC-B8u^s9L=0#)!BYB73!Gry3?gv#I0#uuaVT|;%)|2rQYtd7NS zC2DuQLUkzR4|9$*$7saeP6T`i^u}1&4`Uq7~WPZP)sY!uaoCQ$Zurg{& z`lIH45$b%{VSR);IpcYGd)7n>R6PaJ^YecV0{RK16Y3}(h#H#FsNFFIi{LiY8u^4F znAF?bGxv2-Z#EBgG#^6kiqohyavSx6?@+7W-^bf?a;C$q+W$=m=nclAhIk9=BjFW^ z444a>U=wVJ2e1LAj%+$Q5Vg2QpjP!w)RcWfjbzLy-k!CQ3AJ0=qw@7ZSAj_c^oFak zFg`~OamJ|Lp8Xq!+64`4d>G~;z7RFnS5S-4FPgXK*J~wF9h{3A(I2Q?5+k~|=bt00 zjDf^wM)x*<|F@F_jld<;zWs@*Fi8wEHHA?lQ33T)>5Ij2IjY=CRJjDcX5@0>dg9Ho zh!+Q2O!LMy{LB<~LXE^kKiAuHu*@ex6`VtT*I#0POc%@Bv#J-MhW-}T!y>W0J>QDy zsKvAwRqi_W@MezVczgbl&Efvuj<(?~)S5{Z&)f5_-!w*z_z{>cp3(_Vu6^5gxqB~Z=e^BLKqedWFBJ-x9n1}cP)ZA}Gop@hS+p}O|PrdAa z0y^PFp!WHC)Kr|XK0>{LPZCo>D%2Y^LA~)5)GpeKS`%SOy*>XJ&rsANy^hKkJDHiP z0;mpDN6&x%V;}(yg1+FVz7xm8g-th8o!)m`puSlhO=%7-~Bjbz zsZ2+Uq7J5ksCpM+6x@T6@i4l|aFT#drZ=d?7Adv2=Npg&brPmTO-&GLu8U$+tb;1o z1a;taM_(L)+Fp}UXtJHgC`8{w3-&?!G0U zub)?TZ_l4x{4pEx=BNW?5~|{TsGp9XqJ}nZ4l}1EP>ZTA#=s`n9@}FeUd3|w6^ml2 zoW|i;O5gwE1T>d%bD16%L(gJDAJRvlw$Er(z8$CrpJQ}f{`Z>iB%Df)_AcCrA1`W*>J%&FKKlkHb)FVJ~VmN6BkecL1v4K#Yr-P$N_r)v*?+ zk!X+lSoK2f_r<6VoJ1|sUzpsp|MPh}`$;H@+c8ppZ)XecL8i{>RlqdV57ogjsKqlC zi{N%t#h+2zG;=}Ia0%3!>4u)&gBroJs1w$^5c^*zR|*2MG-}SfqR#TUsG+}vdZS2% zy`9<^8#O|$QA0c*Rq+kfT>BL<-}yS2p7=u4fpr44{eGcFwonNBKP7=dA+{n^fg7lU z$tTpT_8?SxHPou^gX-`Y8{djr^(Rq7{Sq}o0b!VJPwTSPEC7R`EO3*`BAEIcmG2cFj60k9RQ&1{e2swkjX$qxBMXj-)AJ z4z_|W0WG4ss3C8Udcy_y7jD7f7*f(q#SzpLeX#M=rOaZijGC&ts1Y5GIv19rMq)2& z3hvqG3B%2cy7>sGU>($|9)>!2#-rwVHENC@p-#5crOnx27qupuqP~J1P}{ISCc<$x zz6`Z{cA{SFII5jn$W*w_W1AsL8E?-&-5P+E$eC_|d1hgv4qi5()pWmgZZF2!NLf=tCnyG@Z z80vtki;=M*YVkF<@sX$z9EZj681_ZKil##&Fe>dkvj}MWEJQ7ii>Q76998iL>o=@L z+^dp#!#b#g1cgxQ`D5TMqliP8bKE|(yLHY_@pZPUuXRn64awu)$Bop zF^P9Y?Ftw7;%1zKy{el7BtZ?+q54>f^!})QehM`bA5k4iUDM>tit12B48giJ+5hng zOeaANuED6d6V=0msMUG_RnaZf8hK*Vqt`MG#zRe6VN{1pqNc7N>cAO{TAcGx?Od|n za|vkwzs5M|UE8dIc&K~6;-h(E)Oq06u4fwh8}(+hQJ>3QHvI;w!WXEH`qnocOpY44+^BM8Q7239*WL3|A6!28G)xlV$HX3-VHTRdoss<2EW(?A>40pemO9F1CxKT!EHG&UU$$Lz#g zqSnAvRLA$)^jlbwcQ3#)iq3r zA5d@V*V?>!7-}1pMs;u)CdHW;h+9yL>vZ~|(?_M;kpgzDHgY>L6{%%5(@V<_;PG-ofqK@v4sB%-V0dBxRjN93) zg`Aj$csP3M?@mB-G#>S4hfqEC>tfzK1!_O1#?9Cd+hVS+W)aQ7dc;>?NsQXfym|YIS$B@oA`|^dxGP z`}|>sHZLlDAZEfXs73i77RGFS%!$|@_1T?`+C5iM?L_a({?||!A)tNS12x1OQ770D z%#IIGbC;l>`HqL8R&xhbg%eTR>i}wME~C!)cbE~=^*2X&CDi%S05x?z`?LSGeTI{u zZ7~+LeU_u%=pY8-D^v&K3@~$905xL8P;+0=S{qeQQ!Il0QM+OXYNYO=R(}$3WY zYgQCh&sdj0K?2jU175&jEH>Eu0MZ4uxCWs<%g0d-JwY8zzfg6=GIQA2KrbBqdqDlQByP*HN?kJyW}lu1cHW|21}#r zua2sx5$bc^3fT>=(}O@N5>}%+a0XSuHLQwXu>@B5)2#XlsNHb`)v(uJ_K$3+sVs-u zZdFlhp$V$Key9%2LM^_9m{S2{ zdY%KdhKixe)vz`~9Y}3Ze+C?cdg09&h4!5*1hk!Q+YFIMn4v9*+D0uNBlL` z!1`lMgX>Wz-y5ui0b{+LAJ`nV7MhMT9UX1mj8#a#jcG8)c=Hz(HBc|SY&`p44WA~V zBxajnzJfhaKWZJslo)NI8L}W$MP+e3cEoUWCYh75H0q@5izjdk>P3c3Hb?I(Oh7zn zirICcQ|$ikLxP5OJ%-|ORKqc*njy}FONeJjb>Is6;CIxUIMd9Cq{j+Gdtxa(h?*+j z>E`4ti`pf10cM{T5;=70&roWv`j zUSJ?<_3uS3y6dP03#nZZiUUgLbHo!g$n28RDe2;<^f z)B(01b<+JnjZmgJW>-{1?V3iYeLn^DZCQx?0OC6P324r4V?Ine*Zg2n4OO5q?!k_z zHw>Od|omn!Asvf@wCGp)Qa5>baN$7o!@wg8E2B-{|ek#{8HH zFJVXgjQRnj)h4rc7NQpSRUCkCurzkw%>FM@bUOHmc_ru?+g} zG;5$f>Iaj*Q77VJ?1kS^L*9Lt`6)Q+Zc|S)97Xy}9D*74n0i;Brus3eBkx@T>Uq|^ z=KEe1^%d)aI%0dHXO*L-%5R_9rUg*(4yZSqj;h#ezgZi87>Rg7)D$K|O<8eN!(Fi& zx+@513Vz`vWjJ6K-4*mF{s_zBR~&~W51OI7gyF>f51Cb77nOe&>V#W^#qa^Dqd|ww zzORm+4q%}6{|W+HR3}lZ^9Slju*^rykcXm9usW!1GzK|1oav}H+l--j6E#K2kD4jV zhuWsCP#v0Yy^J~;{f_A;DfV9w0Tm3vFszMQMAI=T?n0e(S5a^H47L4!qBLmr~eizH{vfmR+<5^shY!6B$Ao^po$uaCoW5_Evv zMIA&wXU!XDN6mFB)Eo~*?S_M>T@(GB`FI6mIpWnZ1I|OOnWLy(@B^cv_j&WvvoC52 zQ=NCs5M?Gob5s@su{-JJ8?hhHeqY#I2}uhfq`FTrv%2Mqi?NQ00nZ zEG%WMf!amQQ6ukmBEUz@S&UlED^YKJ6E%dNP`e?^Wi!W>Q9myXz_hr~rXNF{BcD+9 z6uM$Yv^{FAOhLWiA=J_P0a;7@^WRs^w&{k-umZJuucPMP`Tn74!A=-Q`@b6jEt;W9z|p8xJO|6*VXTUA zZkeBOnqf}j>o5@SqbiPk+q`LZEJeHq>IafpsE+MHEy7!vmpT80o`3%*_<@wIS3gcXELe-Gf`9X59(ywfLaR=P$LodndwM4>d5Yh8u}rq z{EJcN!4=et{fC;8cF0)?73dAG7F!`#X-qb~{fi0+Q_Y}2zf?t{u zXoz}&X4W>SHPQ*yu^Ffrc6Sj_PoARA=;*J^QJfJqgym2}+yw)1nsu8^zlLhq>$Q2q z9H<5gq1Hk}RJ|QA298Ee$u#67be#zO;iVdpr$I-7t>H_)Esxm{5T)={2D61*H`wx<|-Y5j941A zn7X1??Pk0q^P{Gq1(wFqSROB->Phq6j9dlO+UkdDXC~_Fw;NU8weReI z9SpI5n2IZ41LA$K1ztf-LC8TW{ z{V`D_AJ0f+#+bx&U}6kGjbLq5{q8gZQ3)JDoqVS;A>KnRvTvxxl034H=Oa}VwTQ~1 zj?gZsjtoInI0Ln2j-mGZebh(i6{_B7QG7gK&p@Pp=AVE*I*m|ounggei#%g2L&hGsab;6JD# zUW{732QeMqL%nhI7$!X_>KrJDS~DHc7rUe0e4tGqh1&NMP$Rt?HPweP3GF+V323pr zMGcYTYu+#sYOV@kRr~|>Mki6*=QgV1fS6{A!ceQcIqHC!i8`9Epx!u|pP8!iSdw@% zbn6gUMj$2n#4lY-B5I2|KnB?iD{Oq7jbBIYhPyUBejFdq2^Wg_NNyY9webd!pWG8EQ2jMZMW4)EmV1H$AU}dXpNck!g)V*blYX z7NOSECRF*;7z-bvei;2|)04XKd_3RfT&SKmw6;Ml#_p(X*c)}^&Omi=KkCQmyQn!% z9$-390X;8*YH%59uD7D{{X~sKaC|e;Zg~Q#s3&S}*Q3tpQ>bsi6D)^G6PS*)LVcV@ zpvrAQRs0UsaGHc>N@}9sbO@HkrKs)w4z*~rCi0A+>(n8jADP;tdNv4E(OgtV&S61( ziRw_s#KwB4IUbD~nN_GMxQH6bpO^-tCo%P8Mb%pdwO0ChbosRy0afrEi(x=gGi0?; zZ#ElM@hQ~Me?)E9_{n%vFWy)ZubkY+^ZD+NT2rf04W7mJ7%7FRrwi)Ho`J(@pZ~zP zkLT}xTc>0(G3i@yJ?SS>n?*Drjd_!4sE+JJ4ebNeMsKLtNsbK}*se2r{RS7&Kpf@X!-VAMR3?n`gHOD7V2TIfoX4{lNO<4=n{_cYs(ut^5 ze*(4m9$;*Ik2+5x1(_4j7qz?M1+o8iW)~wt1xus0OHC)C8e3*EQ+OJ6Uc}FAEQ2~<`eS8Wl9~Olq5NzgB+p`c7LJ;uo~T8+!+I6f zflsK#m?f(z-w?H3hoIhc80sV(W1p`;mWmS^iG`;(j<_`cjY!nhh#Xp2-+#+6(VG>^ zy_MRVcyh57ZT@)V8%#J8=_|;iE4%eQ&%WAv(o-*g)N}sexzZa2U+wd&n@pAGs;CVNm=^BP*sk}Skia3{NJ!t2- z=P73a;mXP%iSMsBwOpaXOZbC3Ed_G$u#4@OR&0CXLwOdTv^eC|Rg-+%X=nlA6ofgU z|95F_`7@`(^y~jn$#dl+?@{U~iREqG@%8s_Wy!e1CT!uMuBH@BZyQp)BI!vfe1^31 z+}}v^C0>s7w&dks|8lxhM-S3ZF_PPC*>Ii(kUpJwVT{AGTIBgjdTq6(`R}U$*H;oF zu0CXrOq_pv(sT8qu`7gfVKUw};%Y#Jr^(B|F6v~m>AOkmOoNm0AkVaO4qy;vtDvq9 zgjaF93CP&jHvEJK={%45V-$tGc=jjvbqf7K1MO_#f)t!a+=plJ$j2XKoS8i9O+BkI zgtQaft4VJ~+A-ww-~^NQh`SMSd%4aIA{n{)*EgL$Jk@yf^A9LwX0>QElBe#CzEK{vgj@@&=N2fV2zz`-jdo5|0JrmFvXqLw!u)+ z>XZK>>7PkENL>Z(v%7>7QO6?N)~Lv=|B__>lR_ow5g$Bfh|N5o3I>t!2x*ncQxEkS zje-lg>yd9S>CGuSL^t7bwqo@uBWYiVdy(%D`O8zkt^tIH^K32m1MR=|1a!6ft#EBJ z={if=WP044O4gG0gS527Bd$G!#}nCtEy#10a1-0mA;QyaofBze!*BJgd@Jq|n*X^x zTtMN~woyOA3YMUvT?BgC^iia@q@iw<(bd~_oFD1_cfE`V*~U`aJW5VZ`A^)s=2Ipm zVK+UM^`ug7BFV5U1viml0qF@T+>Ll0o~ zi}*e6!{qtD*CNUmH>2b_WvF-+2@%(B0(H2L*n-P>zKM#K(~0i5j|L-?{|wLflBO#W zm5n4lA!Z_NBWYuQYgj*k>Ka5^N}T<_XUu;k5+408fjvzle{%EVpyztcvnDjCKYX6F z4Mw4{x;Cs#(Fy1LEv__vigQYnPuE}6QGaB-=;VjDG-l43lEzU-^sI_6r4bXF))d3jASR64x}N^Kjdv;D_8nz@EjNKiboD3CP@aVmuY$VP+XfY$$Gwtgv26Z2E*1Dw z=pP>JvjvLr7E#DBo=#LF-G_J`o{iyNOS}#Ki8r~^QI=m3d#=Cv--9%EmU6o&U&wZD zxqTUBT1oyOJ4&6&>#il?Jr8nGU?SoDxP^ER3hlueq#eMBt1a6l&@ec~W`p^dN`rQChDB$8UOhQr#9+pKqqu%*KO;M>21e93z<^T z$T04`gzMQ+QGucqd`*F3G_=e%HkEu=s62tKG%5BZP1jb^Bd*4T^V!JXl-)$#VbslE zIXD-{ztJV3jP1=aTS0Cz1W>3FnUWCJ@ATp-AK?L1xSzWpd2iarRex^cDQv?5dVn~ z&wr9DhixzcAn==FE^Zlig4-IFwyN>6|_+umrm7BP4 zOgy(4p>;fZNOE49%Y*SLc9ZIklb!}g<5}`eBR$t|RTiY#OQdh&4kTY);_JDKkY_IS zJfmDQ?!+`ZkTfsb#UR34NpGbe#8=wH!xYrj3FlCut`NdYsA!FeIx#5dZ}XR+(p|() z;BC_QRfp%dKRbv=TuVuh%)Ogu5Ad3;w;AE$g!@KfB3_Vt92wS=IDo__g!^#oibiEw zXe2H1kG5j{Q+|0#3+K*4`hS!;OWHl2KepvoQg*uySF@_VQIx643+eZ4Z&aTa!UGb$ z82TD`%Qix?lY#gp3j2|^heERm$0IE*&&Hyz8<>*DBQE~Z@c+Ap6U)tWwUZ2&&{)Zy+tsfbB!rXkm+jdyd`_V-tZWMow}o>4R#7Yaran}Zj{72co=}GW zB8^j+_y@Jd)$+G8o5^#^Bzyk1q2^y#5CvayALaf^;Y0RKYGHcfA#_OB6YFjoFHFTP zY$x)WfM2*Wce%0;yTRu+)n{P24NkT%n9jVBaNlo|#c_Xg2 zl)XWGnEsD&Pf;)Uw&890a|0N=)Fy)WiI+XTGzleEH1;x2L*#}1{yo>lGG7RD#P5d6FB&`<>-?f!i zA#E72(+$VXSoQ6M={x9)U#B&fX#?4>$c&>yrwvonlJ?5@s(~lB% zgNdZ0^3k^Or(}+}s!^e?^JW(o@G~8c9KVTI!lcT7b>7%+|de|F#`z zLH-~7hrm?Ud1l|zk3?NfDOka#4W&RWTWF!uZSVgi+>UTD+sP<4|2~^n^ zNy|pweWYKuH3LozFaPO1X?w8k=-o zd$}jsu;K+Nn}%}zu@z2MJ%qQ%~ccnZOa{<{HYw#@xZAohM!$QxR`T$Et7_ zAbyftR|pO3DoVxS-1VrmDjmvCIO0l1I5Bqz%GBri1oS7*WHNjq-827LNW4en2X{F; z0=;SUBe$+wr0Y75)u|+(O;=iCI&p`zVz%5UOvC+}v`5?#R}Ipl)6Soi&B?95aonIE z#8cSHI!ENhATl_TSe^k_ncxejdr~uyN`3u|0=#+m=nywDq%L$jT z@$$q=QTG<=YK_VC7cq0FOjk@2^Vmw_*q)a&kDNdo@67YQRQ7_xD@iLt{ERIhg|v0H z)7NZ+$4D#62o)!uf$$;ZpGNRpFY%{Kfg@BjjmSG3%>A8AsmOfJW;{WjM}+HAY$DHf zRk3rga4(+avkh*r9jHcps!da#tlXjG3*(MN9Y0W)Xa4IGiALrDCe4{(N8zZgU<7er z@(jQadU*s7_n!n0&t>TVD-u!g*6V4*vaqj%o z*Mhv6xTERkznUbJwUu`zT%62@DV)qURDkdwgtzfbR|Ue+2#>SRmG+jqEfpT2183<> zKI*%|or?7Qqz@0#WRxSMiUB~LN#G~9ns*KzWsB!7IKHK*Q7lnWv)2G*g?m!!Knd9a;(H-&z` zX7O+gnG=$jjmip6qz+xFtdVX03Uu%=X;HZQP$oY0R@X1$SCCMedm)9d^B^wnr-G$a8gY%Luzps| zju~u+8e03>Oy?-Ki90cOD0dwD`~hX2*t-6q{_@1Vc>Y0kcH@CBk-FTv&XJ)Dow?7$ z)WqKro=u*P#82BwlrI)>UH@_SqKvL=)G^xxJ^#?&NII~G@(n3B*w*hy+A!h+N$2vM zKh9lSaR(kwrQ)t+j${k`WhL5KG;U=Wd;BHBLtu0rYx@MU7=a3+AG!K1A)OC=|`3bL~@N~j6sca5;S`yw) z`W-B6vO3#r<9EoLmpg>#`P8_*`VkMci?Fp#Pi{Nm4ks{^3QAC6ZVH?s!&3_AT0>YL zsI@qb`=l*&mAnoWmLa~1@DrYGq|8vIb4}#_gLo$Hv80Wq{_1qBBk5VV3lSc{-Bv&U z>H18ho^3QIE~CPDq|ZTbo+UzEKdJ1X%~zUmchc|Mw_k_1$g|saA}Zw;lQziazeV~x z`vRWI_@Aks_HBmYWDbmY@|!trI5`#Erh-5!Zb!qh$$!mO=*zRO)H9v5JcM;6!twU` zL-I$m=?QIn%5zu?EGu_;DqU+IB%qQ;O1A}ki2vU4>cn-$=YB+<`L^7@)Nz?|sfds9 zK}96ZaWpZ~@aDf)jZTSq0$SYTVoRLJ(cIStgdt9Tog z>>xgce9d`Yns~(Zmhc_!XVlq)XA{U%nD7PrB5iD2SxFzD^FQKBMDJqJKsMXknPkva zgaUqq^YN^KEgVkxm96j%X{&4p^4sShh&Lxsn5PEwKZWT`Mw_n$Nqtpb?T@jEM`$EI zncm<&Ix&yR(h`45yeXA!BHo0Z6}r1fN&-5 zq>6C;B;-O(x%8guik( z;%>)1iaQo%bZs^`9VmBEzyFE2{-kg=D$f;>fG_CbO)~0AXDe7^<4ViJ^JFym%ccz> zK9=+Yw$pzTA4$E*sW&}oNo~5yb|jo2V*cllu#Y>(ZOm zsBj=@zhCPkZ&*G1L|&h68Dnhdb|JBsSBwpVF1Fthyer(AhyStI2ljj0?dr<<~vS0oQX+r4|a7N*SSg{H3?-FI8G?G z!E87O3*i~O>P4Xo9cM7{2a6mh8Ma*PIB{?g#=yy_g6Crf+>WvEp7kG$PW%Vz{b)-Z zX9o2<=?K&%VK>&pBugD<2X@D-7_!W9Qep#4gZ(f!&cg(F1zX~C)W}p>ZW_`I2NCa& zY0+6hS&$CnV^xet{Z2~)YEd85NK8e4+=A-iRSdutUQQjE00tc6q36Y zV?KO=IWcf6I|J)rI4;LB_!L!ej%~({n1}dk%!LoIBqrT%8q^pyq6=ICdhiJKLKaqD zZfuUKa1Msz1+0KRJIx4H!I8v!V+^J5GWq;44e=tF5u0K@9A`a_>Ztc_v#s550?|q6 zYaM2tXq|%^q2=h0mr%RmJ!&z=+hc}46q6D!hgu^oPz{-k{wqQXQB$)iF)A<>V*4@TK%aGm;y^+F!AQ7=i@OAZb9X{X5+t54M=m) zY`<^}rhcaxfvh+VHD`NJJ$Z_H!RwGo_eZVzvZ#^Th57NNHT_|>DDft!HM9o9@Bx;> zG)K(hYlFpzuS8cFUK7yb%Y4*S*bKF(23yBlXIqz}3fPQl;Ad;%V`c<$qdHIz6JU26 zABCEV#h4Ix9%KBK@jMA?z%xvYX^z{22US67)Z%J|fj9_L;0jESM=%|}!gv_>gn2Ij z^AhV7MF}iM_4F~u$H=G6zD3=6)?|Z9K$MnEI^aB!G%$Z*fHAfRLAFjk4 z_`s$ozGy})8wQYG5i?>p8=r5VA4U!u=YiGhl8L9r#M=L11XNLV)FSC%GYm$}^+Jq| zdoTl@MlHe*7z2}EHl|0di5#f>YqAG|$Exy611~11-cm~U2s%wmYc>-++_~Lfd zR2)RLG}d*q4TDfU%8fa(IBKf;pc*n9)zcZ63s<40>~GYFB)eh1TcXxZWz;U|eS`7O zPGAZN+3*-D{uxVRrkkdvT~QV8!+dxeb6}KPrh@#a22?{$Sqqy!2$K({wLZtJ-fXGA%?RYVZ-#a-M(}(G=EonX?U(m~8KEYq zIq!&?^U0`&>_AQ7RU3bVnkv`(p*h*|q8d^G^+J10grhJuE=2Y0fQ?_Ve!x7WCwyc+ zEz6_wb;86r#5xE4iT{Zj*(=CeaGjq7ijffX*u2;l)gu=*q$^P`oW~sa1+`YPJTXJs z0M+mbs0!C(LOg~^@s9NqYK_EwYR-#vm`?k@6af{`4ol!@)Io9)wKjgBKW2JnMx-1j zAl?+yV=tS&0M&qPsI_#?#$R9%ai8br!zm+bk%wVI>UTO3(CQwB+Q*ai0JmTOoMx|Fp^|Y&XENbeOqblBu>fj@5q?cyo(xIyi)d{FY{jdH&=?qtcw+R$ zK#YwcsCUe;9u)ru1*j z(ATo|vCcv5+r2ja#v1Qma}edktUT|4nwq(o3lE_x_<~v^+1{GxwNMQofHiTlOCTD7 z7pS3mk9jfnJF|~VqSD)8v2WSEik5Y&jc zbqMI->4PzFGHOlCM=heG7#HtgJ0|lV%t5@~7p4s-pemk%YS2Pd&o*ENjP}*6p-|MW zsAl7xFuV5uWCHPda1^yjZen!2hpq4>ro-yr%=YY!nThX5rN2UrSlsWX!DUbmy=;5}YAtO-t+5-Zj=jY^_{H1H^~_1Ak13!Msv%u4KhDQecoY3G zT_n?>VyJD_3^fI_Z2BP^e}Edvn2}9K(xBE#UQC7cP*c!1vg_sfJRd=V9|?;wDQ-rM zz!}t>KeX|$_IcbWW+*eEdK`x8VRckR9Z(IJgeqq_s>gd#9s7tO80tnfFEmEY=}=UG zt1venL>;kTa3uah&H2b^rh+x73J##Q-*wE1Pf$~n!q>}bfg#u)r=jYJ6y3|SDBWNJ zI>Bn9R_`#>i8T(B;Z{^Z7f_4uA*ui;h8fC0YcW)MQ`G7ofqHKe`r}em!;hk-;2Bb% z>qLv`<=O9XP-lN~)QiEWAuVX*)lug{E7bPvidsxAYV{98&FNw+h#OFA=@o9pWU);C z3s{x-b&R3?pEpIj(Uq^K;Y8>99e#f6cB+QNKQ32FY7q#&Qs27`~3Y>zKa4%}4{NkFaON%<1Gont^ z2B>}B1+|9yqE5m;P`hU+y6V9$0@~-7P!+#JtpUGyW|ikb6<8Xz*y`K#Zm1C(W?g_4 zi0?#|=NsRQU@)p7B{2vqq1IN<`0Rfzib*7>!Y!zl-myMF&G|FboWDm+fs?>A)DKxi zPA1fpf`zy>itNG>5Ob0vvOK-(oNYO&=-6Ix&-fLbhpDa?r#j+(L#s5za5YUno9)Lg;~_!3p&-jrr!E~6Uw7{l=+rq=$? zlgd<36IDA|GtddCZQN{LMKKC9P>lAZoD} zz>L@cJwN{&NkEHbv(2yz)#JZV+v^Kzo5oLPKXg#(VW^R-iRx(!48VS<5nPCxx{Ii_ z5iP(BeKOP<%Yd$D@ez=DQFB}rRd9KmUJtd{TG;1ZtpiZ`M%w2yP(!>F)u1h?@=l>X z4X>gOtQV-M`x(IgSI?6NnnjonwR&ryTHF$Kl=enV$qdws`%$~#4r+1zLT#@YL0+C8 z!zVyBxDsly)khsXZ80lOLQTPeAlJ;vOA=I}UwU(Zq`~sU%VKVviE6-kRDqw-8>3_} zQ|F61@#1163`LDZZkt}hrnf*fv@L24b#n<6A@C>a?Ei>5qko`=&@0$XO=47mX;32& zifV8L)LLm|<9$)(jYSRhIn+qpN1ZSKpr#^LM*I1nmVj1wCDenK7>NB)Q?Uq(;bzqC z_>8JJK_>InD+tx2il`~6g&NvEsHs_s8j+1y7q?ivYH$YK zUmVrq(l)&UYIih3^|TFYq`KPl5vT$up;r4M)X1&1?zQRXP$%t8)S`}+je4oy$xJ{a zPzcrH5?CDvpcdO@)Th~f8;=rd3QB<5$0bqu%A*=u7q$PJqef~PYSnK?HQo70wLM`6+sF8Dh^P37%poYZXngO-iv)On))Z!|F8nLqWc}*K{gz8Z{ zYfn^pgKT`1jZd}CMH=8bO9`l@+fgmMfEuF5s1fllU@A;C!f6Uj#E?Mbtso z3pHZnQ77nREQ%{pQ~46pW6FY>D)wJ-0y-F~qZ-m0HKc>k^XZ2AxSfI89h*=MxPThk z8>r8S$5XFPs=+%@BeowkB7dVl`W7~8BO|HH|`BdA5If;M6I+!iO{5F0x79xHbwGHDJWB->_hGJgM zHSC4jPL+zAIU0=W>1u3*H&NTLKne33jRvS5uf-~O1`DHqNiWZzmNmj~;`31X?xH{b zLVarbmvX(F)&vTaGQVkDiowM1qqbYj(&pQ4Hmptj3TDBOGG@)x$9%*)V@6z!TBKJo z6W&7&b*!@H97v1vh^I$&S81jEpsV;|f^&B+^74`WrZ4M6RVrl?)e6SW8@q6%Jt zS~~|&JvxTkX3wz{Ca-8drkkPCH=-8xePkE8&PxK?X75ow_o-wWk_9z%Wl*cTA!^^Y zz-TxQH4@WNbGaEcb%PF>5(DanUIEexf8 zXF)wPHy3dz@u#Rc>QLXT@?oecxq@0;J`K$C*jR#i5Nf2_qt1^(s1Y59-Ec1IoQT)Z znAVydJ>UO}+Jthb#Z(VF;~3P?{zMIJ(njWdD302eJ#i2&Lp={}Y)-c7sI@Q%HIhp) z5TBwx&SN(*-#3ajVgG9`dXX>z7ojrdXzJxO#@eU@Y8R@4r>I4kpqZD`2eYE)dLfcPvPJ1A4Y0>I6;M+BBph>UgXQS)IPzS_{$~GgFwzUUd}39jXKF{w6#4$ zt%=*%2%EGs4LyWf3olWN_7i5r)a^|N%3x&TolxgT56pwJQ6qQ>HAU_#0{VI!r-PU0 zFOOtJ72FGbaWJx2ow2B?n1t%-KGYic2i4$I9ZdzDQ4L;+T67_u%=u9ms}Zk?lW+wx zb*@vOvl)sG7{PYXE9()Ik+A5aZzr)Y{mE+ASBcFut`VKnM@dJ+i2fv8o!95pwWQ2Y2JYDyyaFpDw{Dt|U>O^ii+0P2h% zgZeC3gmLgs`}_#11DEXcFX-yvh|$w57Jt;x2ccS+1NA})RL|O>3LcJnZzgKHtwSxY z`xpb0^)e$CggT<@p*|~mp{8OYY8R~T#s1gOA0k1&0l9~&C~+v5~|#F=#R%yBl-;0fbZ5ox1TAv0%~Zh+IVw}M!XGb z8+Jui&>uBLV^R5Mp$cAu*>N9galS<@%4Ge`HVs8}pb;v6b5!|mFPq^H)Z*KK8tU8D zrx=;|dmI0X>T#3-rXjIW+cY`qi%eA!laT#hYY(u_RxXyV3>d8a< z;3KLbeoT$_c>&bi)j}269@VqKNCD0)RDtVINA@ure}b9jS9mbsSZ}Rn!!GL>1`she;1a4QX-IcCCPFcx_bv4ycjsi(37| zF_!lKdvpG!<&jGoto$I4XZ#)GBvT`+hlU^`FH;=r!8x z`*740HARigP#Yg@<7-E=NYv8JB2whM@?0K z)Z!eEn$l&civL8drJbm$I)LiPMb`#CVgL!r#+sfMM)kaojdwylAC0PT18OmDN9DVY z>gj9L$ix|E%E^oREUAjBum>vtEL6wc4FvS!P1I0+M-`lIyg4u;P(3JRt$-?^8fqlk zpnBR9HAO>FYheLuSM9alvVKPGu7ndji_>*-5>NxGqZ-f?wT4M~R@+HB~LMNlKw1jBGRYKo4aI(Q9p>+}B;fovpXon+QPL(EKkC>Fp?sKxaf z{V~mCvs;Q{DdP1o7cRvtcnh`Ne5aTOhoL|5TGrmEhRwnx)bH#gpq^ewEuQzNIg2sX z%w<;8^BSmzb-_@ak1FVbP5+3>mu{N*E?5|~nA@Nh_heMVcA)Bcg|3D^(sWZ{5Nh$1 zM$d_en#*za`5ILIbErA|7jO<)`s{H#d0Ud>(tWoBfRh$rY0tTTf%#J!j>!3F_N6mFBRK-K=^NFa2&OuGp4%8Ih zLhY(AsD^mYH@m@2N}wnSnJ^=EK+V}q)JUvFRj?U7XEzoiejc-;-vU!`Ayh|7qPA-d zR8O0s${T=cz$8>TvytuSI;#ojg*~YKeadEdjB3C~)KGo5#$9OQL8zV;KsBf~>O`A? zCGa4YLf=JZ8&|>H#K)l;a0HWR|6d`XmcB++7;UjR`(vZd{&=XC2ckwOtF<<&XG2i= zW?&>-jT+(&sB(|l_&rodKBGUzTEbLm|7RuOgJn?_RYWzU7HTmyK%EE8F)EHgopcjW z6)i-K;C57lj-uAeP1G)Vgqo_DOU;@pfI2ryqUX>5+Y!)W8iJaF1?Z2vZ2E1~(0)c$ zn0A?2{rONQXA4wMr=uFa5!LW*s1ezVYS-pkFw5C^sTLr@t}xp%4r*8BUg4TEy8#K>&tp(S zw*!6gFlq?TqI&oN)f2y!X3o>0(sQG>T_sdQ+G7?Rf@;7f)Mv;sRKvfb%5mIPCXfI# z5YK?>VP#a$8>1T16E#wQpr&d9s^B%K6Y>Bm-%aa7)S7yY8j-iC9w%6BMz|oVV{Tmn z8rngq7H>z*^bX&v&4P@)W9JcTrRE)jm(W-b_(2 zYHA`-A3k+3x%Pi=0vf`p=#T3#DxO0Xd<`|!FEBMa8%#s|t;J9kw?dr{gHaz!>rf59 ziR$?;)LKcr(Uc#Gu~~mkJ_5>EYLl@&szH-bi*hwK#_Je}`8S)Nh%~~^#OI>E;rRXO z#b3Q+if|0^qg%}gRo!Mrq&e#SL8uW}fu5iLA0waw-eWn;zTISSQ9YT58iA8Geiy@u z$Jk+hW>gL}w9`;)XDw&IP;e@PP3?q=w)4J!Ts z^JAtx=ICsJtX5|#s)9YJsX32Yj6cvHlkPQ(H$Q3w8l#?1N9~@?)~l$+{>3GrmZ#rm z_G>}ZNfnM-#U)W|qZ!s?t&GG{#2@eX^86c)kOO8>^+nC?R8-G*p|;sojETSSFvdJ+ zeoJ-%wVT{1hs>O0#04Zopj!42OJKai#@f~e_>6`;!G%1(aMTQG*JI{GX+CPoHlXHu zKWa_fK#iQwakHxuA^BVt(RE3>T zYhf~K$ai5)M&ur9$n%{yYo`fDA$>01!X+2HoMAj4c*)BdfKe}dIcuoj8AhN0=D1?! zvLkBoj6|)0eW;3VqqdFrRkKJFpgz~@p&B$AJ&O$0p{uCX|1Ux1l$@oK9E<2jVWwhXrqXIsVuKHI>s*L;ef( zekj9{7rWnL|5qchjszWzKDSK^Q=(RRB`l9KQFHnPOJb)x<~!eZ>_Gez7Q+^QnFDM! zmLdKbwTL6`n!nI63d<5djomQG->!LK?B8CVe<*Mhl_BFj^Fj~IO?*3s;6JF5NqyhT zsf;yIyJaO##%mY@+deQo?unYBm8g-qjyhN3Jv5eg3FzDF2-F%lhC2Ct9+}Vc*r)=N zp!RV9>PQVmeb_XyjD#7Ii07N2a2tz&%1hi{~f$W6%?`y-K25 z+yd3G1*lKI+o*!RqgH#Gr>2KxP!;yZAe@Vt@Gxq`-k>VZz~P}qSqoXzuG52n7TFxs zBHN4E@dc`YRL@NV%b-?w7gR&0qVjJ+9WeJ%BNFq4Sqphk9q5NSa4TwLo}(I=TCUbjD)Vw53{(Uq2?q3md0RI z#;&NvI0!v+j2eN*m=n|dG*eOoHOCz>0LP)W<7ONG%Rcw{W%8v(&H>jcVggP>)ZF$* zeR@qpt&NSSZFw9uB_B|8pOT-0=zPdwZHVgeXw;gRhAL+hYHggsIQRr(;%D^y`~S#Z z-kxv28BmL(1s1|ls5w7@>XDzfw`UjR#Q4OEp?X{k_06Uy>ZBZnI%tlf8vGtLqA7g5 zJ)eRtP|s&zW9|Q=1R7w5NZw9;9FCf^N2ta08r6fMk-a@rR1bB8c1Ep*@u*dQ0hRBr z^$Ug(j~~U`^Czg4Q6oAIHI+-z)v7;e6JDYgpKnxe&)kNgwowt^jzo!N-p_-%iC4w`I106hqs4a3&_~4f_WbSCMW_#l zpQyzX=x1IG$L`+DF;*x2Ra|dJ+b$xWSu4Y^1@R-OAa~x zO<)#L5>$)wpoXXmYUrk*rf4_n#mA`K5Ivz;19?#K>Zt8F2-UD{s1f*zI!QAn^7edc zMxc)DrkEDpkpxu08q})1f#or3V)J5k)X=p@?TRIs3m>57K4}tf&q>x0wH@c93OgIEDzaJ2VM^`)Rs?hu4ny_eD5}TbP`e{AnOPG{u?F#Hs6`r{+~n(qnyPuI z2JApJ;1Oyhqowfn97GvWQ&AmN{&4jC{(mC@_3R9)fS4)G+~q}OEQLDBx}Zj4E*8Yg zs1b{s%2ZewHMC7o+iL`-#-*rjc?4DdU2BZgJXa6%5YYCjiR#%#497=U8iV}Jkat2g zbQ$VEdW0%CdKz!f?->IyGVx5P=b@;BsRnAXwZ=&3qRy8g=xT1p63`-9hEZ`Z>cyj| z&x9Ko17D-I*H=^l(bAfNKOiv?L)>degH3s5u;t6>$lwp!cW>GiNZ{uL5fEwL|rEII7_bFg_kaR=IP{`Tq0+qK2*qYO$=uD7X)!<56sf7tkLIg?f8_r_>OO5MOP5 zh5Eh_lHCk(4^#t}qh~Fl5AoN??s1*B1T+`^IZTC>(U*8F)FNzxTIJnQLpL6EQm(;N z_ypDPC^=0}^I=KiqfuX4FQFFe1I&vrQ3qFGE-hyEUt0oN-Mvv255>4R9yLS@Q6q5@ zH4+z4A6BoaHoT3VzyE)afLiztwRpax zK15RIGX>X2Ev^ZuidUl6%ysnap8RG6bEDQyOVq(N*t!-q=hsjNSfm2x;3|NwdeoXg zE$oIGqBE!=j#AJRTm;J!?}BA;F9xA+m^rYrp|)Q$)X*+K?eE9vDW{OhUj%h9wZe=z zwh;SY1#Krm+vP5*dilY$fKuQH;)`7Z`Vh%n+{{rORD3vUF>bN(eW-$8q0WU^B}@+k zQJ)#5P|y3JdO8PH&R$eGFHyVaBWjA{mo!u3mLs5(Z8%27eW*2Y47GhOqPF3EOoAV5 zJa#GbS&#Q>!%^C?sHLNbG0Ub~c9E3W+W}_D6M)Zsv>f<+7IkRi>VHWNG#soB^BYc;a=21@&dKm{VJN4XGd+H2B>{M*v3~|&tpE)KcHtyD%mf$sQimiyX7Qm5x+yv z_y4a1{7DF?Yh1Y!@wc%!@xIkegAQOt;`dQ4&tBb(L|s%vhNC}DLN#bJYTNEZ zt%0AY3KP^YQ<4U?#)46cHD3+(zY2;VL5rk3E8p;q}5)Z&a> z(^OQzS_-xQtD`=KTcXxLFB>0k;|p8@+7{ce2S%%9hTcUD={8J;?@$%Su5C`P%%~o; z!wuL2r(*g#<~-Pgs`y`2$Gq#BPs_BZ^dhM8+$sdr(oU!r4nhsxOw^0(u?U{S+8DQ< z8Hu*2hA+bE_zpv{bbT{LeNl^UIsS#`Q01*_V9Gy>vGn=>kU&QsyhSaNCJjx-F{sb? zHJA-gp{C?Js^x)=OnLqqfO()R1q(^mqyN;y0|1NjjRT z=z&@b(=juyLFK!FnxcqPT!*@iS@> zCGX+w`9r95*n)UF)Er*IGWZg;+Vk`@-v>&dwy}$9z))0!W}v2G32ISZxA7mCoBEy5 zUS^fILJjR~%#DvwLz$wtS(GKQAn_@v6Y&D-Gs3%%**%3&6?H%j^&-?ZzKLp3(!S=P z%8Yuy40`_lZ(joX9AAQ3%@GXa8#(bSFV`IS(~t%TaT`*}4Z+&@l|d`>0*vKfsJsDb(tB zu`I4ZHQ+O<=f6-LiN|)=TGDU(HA0zO0-F1#s0v5f2UAcZa2oY#_#L%s;|(-(oE=qR zUJS?PSRR+5%6X6Z@h7&&e1DkVx-CaP;#aX0K6VM{Q!ZqXsi*>Ke>Ouc!dBK!s1fRA zmW6TH~#jM1G z#(I1H>)F*&U)c_zs{36s;}1N6YVoo0=8S)9O+LZ=sHGU{E7vrviaSv~ zjy=&-oD+)^pMv@nyonJQJjqO5`$_D74cS-{RM2{yh?lS=HlJ)x#{F!FWM4%c_19d`n!0b32_1;dGfJWdcHo)k! z%u(AKb-)Zoy|4)j<0I7S51eflRXD1`?x+v1rKsI-9MysIsLzCtSPnDJu|E$)ElT$U z0j>6*sMQ~RuGvNjQA3#?)sQBr5gL#BINgleHHR@4e#4aLJI{OpNspScVyLMYh%s?H zD*qAOr~QA4fOv@9p_(d8ttc*&2*P{rqS2&4bRQtV9bOeo6OYJMSaSSK#lZ9)Q8?fbajBl z*la2aLmd51Ak2X?Xl_08m85_BZS*zN7~#Kx#0zkzkJ-5yiWaU4zD+3W53 zKcg6f8j(2r%v_g8HKaCbkxoLbg>9%0v8$-_$C@io*@9Os~!f@U~H&rypm?2tK_%3&GeZbJeS2&_WQQGvte z=ZEIe@o@rb#Frpb={kD} zXdAu56!;U>v*gFj92P~rFbFkgb5Ng(r%}5g%5h^s)XCTd6XICZdy6p~_n_9$PfU(! zPw1dy{}m#j9#%qazow{d*B)!&Jk%okfZ9e`PMQ<21_l#viCU}^Q9a#_N$@#pWPDDU zkxGL~FOLbZ1$w^!_a&f~Z$b^}8PsC=f;uXl(`L2DMvY7mYEhL(^{^dkIH4fWaJcix;IB~YIstx)MxQ4KzQp8cFp+;x|YKqpQKi)uX*RQCN%X7&!i>dM@(}2;ag3n`Iykg@| zP!+vIRqz4*@E2-M{VtnDl>s#Z#ZaG~wNOJo88zpJP$O|2RZnF1iW$1-sE@~#s24M$ zrlvWn!U?EzU>54dWvKnU+PV|9i%y`1_%iaD=ES&a7IR!wkBcJPj=wW%c7r>SfaZ7$ zYRDg80Qz1t=~*#CFQ9hC0@RRRK&_Q;s2*m#ZqAQ7sB>c)YS&yxJ&$w4EZ%U`+_%J% z+W$icX!W1A51ycU9_glOaR{oQ(x?&o1C@Uqs-Y`UtNbi#^*_c!7;wu>QB%}=T~WJd zAS(ZI^!)cf_Yu&xJB4c5CsYLqZkvoDsKrzgwVzv{=6nchO6H;(yb^uzGRDE{s5SG< z#^0hAvCkdzA(RQLaQ-;m36#gm=SWmaoxRKaafJ)Mdra3|^uiPv4zumDtpA}}|T zUJo@jlOLKXJBX!;zr$J>_Q;ILH1z!c|17o%TTn;pLDc^KjM@c$kIiCBgIXimP^-8G zYRCtprsx3X!!KAJb38GBW;_ygZhSf+xn}$?G9nl>y4UR)i;RaO4+^Yoq3H-38 z`o}ydjHHwOCs$c=?;5mdU_#$d5-l9HMW4$rEBpB7PlBj%LZG1AeA-)e;WBmR9 zf6cZig4(yOQ6sSewTk~no!NeG`Rj664$I;?R8PO6dY1m3`H5y}RK<%?AJ^wlC*o&R zc_HsjdIQX+&;Q{BH00Y+1--y@80&+HhoV+>Rm_iLQTdOfD*A?MVET{dc{8j^d_HPT zyhF`>z$ep?DyVWsVkPQ#4iiwt2|t^m%7bb^P1GFqMOCy2)#J067r)u(Ilq|vbx~8~ zqK@cAsH6KdYO%)oYNo0v>NB7|dj9>-Bmz2__F*Y}g5@yVH&al5)X*(Qt?sL+iawy` zJjr)cU{2I|&>Gdy@!;~`v)u3ZP?C1X%5*Cn<@26?;P1KjsRKLt>uY+2Q zjZkZ20%}f=V-Eaf<2g8hH8O25AudMk^BvaxsP~VdKmOwHzj{`uzn72a%nnDb?#k9i zHoYUpB7GogEsV4A>bUA+2Xg)7!PBj&ivG6N6qej^A_3@iJ` zo1ms@85YMqSQ~v}nMGY6HG=(79U5%oqfnoQ6VO$Qmk^NqQ2YBPs^wo$a~n6d8Huc@ zxzCU4NmbO8Oh#3-4E5d`RKpIV4x(H3d1OBmkAcdc%g@L4Y=;8&K}XcVF%$FPQPj}? z#MI~;$1K)h)SOnbc0hmPV^G^|Eov&yqdMdh*DU6=s0LO>b)a=z_P<)Pk_7c+J!)tU zqCPyXq88gP)S~i>X9@^LofAb+U(G7n^zNvS2RdIjRlx#rt^bVFm@5E+*mq#ty;iwVZjQXZ@6xFa>sB*rb zJ}WXO@$r26l|mZiI)hEX*@BwmC#a!`n$(Oy2x=&6p>{=6R6)a01usUem8;g+$;|sD zuqf#rusCi+jo2sD$fi%Ok$0Ip0@|+~F|!vvmc&=3@bP?pUqdabXemvFnXn!42B?Bg zp^ohLI0Eyf^6~t%`yeuF{CC2AJb!6DFs)fb*HImLi=LnVCrW3AwlL~Lq#2gOSy&gJ zppNK>0Q>2Nn%l*wq2G(u@i|t(@IbSsCZpzj6NckM)D#B>ne(JEy8a~0BcM6khuYtl zQA7F)wdw=Yo5fccwHqp+4wMF{6RaSrX^vYyLvI;7_C#u4Qs3|&+ zT9gSh8*^l4|EmF&NzhOYL#^`dsQr2e)zf>Zlklm19yyDT!&31KCwQ*$ys*=oLx?*X z4^Q%DD%e203+dIl%M<>?HsG6W zpz_uuUt$|yNj_aMiT5EKL}QxaO#S^k{&}90ga?(W_%klWLO4j3;x_Jq1p87+Z(9)m zLeKMe0_tIH(l{cVGlY-u?rJLLe@-RRZjx3+5w0$jqpK2m%Gw71pYi9x0y4y>u(-6Y zAMsk;!^k+D0u~X@PB@-zz#QUL$RA7vKBRHFdak90|NYv9&^_)LJYVp?RDSP3BVzNu z+ks!k*+L)U6(0CXDqTpJf9CnW>kXk03ffQF2=41VpGVqQ(w_3pdBQzy?twf@P1%!4 zPr;pl_+#?bqjPh3_bbnaM5g}-dEpI}d6P+35WXdTkqi@Tn$k-XzeWKoaV__s+}lb2 zMV=|-A4j+t&j%Bpj=FZCKX)whHsn6Sv)|VR(%4tiS6y)kr{dQ2O?kEdYLf63Bk|Hc z+lb3lzC>Z}h7ga!|9kDSk*2n=9TYZ;w4LP7Lf$<#JqhNr;q|1CBK(tj!foeNzcZBw zDY$EJC*+|nU;ENl;)@Aaqu};7P0tJ30{C+U&!^rl@?{~kO6Ph!uXE1M^*G0JF7{)+nl-#SlV$nPgOiOg5I?{e?3h5UXzlC=Be=jTVBt0CdN zg!tiy)0c*H;dvhl=Z724Wa7(hucOh3ilpoRL9H73%M#Yr-X%fT91?y=3T(^*dyD)- zN2fUcu`tIiW(5U!Sj5)A8L2VOVV!J z=i3RV=lK=t8AaLkDB~jk{#fOCu0S$QB9pEGWI91X`ZDqtcM)C;q)-=E^YRL1;u=l< zYZ#yO6SgB8iTB~%{rLOxd`%-yNAfqKY+dOUR{ejI@Fy?miom~U$T}Y0Cwz;Sbj>8s z3@RAUJ&F4n&)e97^t>1E)It9BzSENDrFnjfwD+j%0rwu_x{A<|tCYJ|@!$OqC-IUk z(1(ZpZRU0~Vhic~M#gDF!L?DBzOK;D*BKh)Pg)}G zf;Q2uOGa-pP3LY+2A7ArDpODfTNuAJ_}|ru=NJDIZ^JvYX~as>B9lLmoF{FsPY};U zxGV2`u;u=V{i*9u(&y^)zXJ&aC}1h>A+f5hDitG=nEM5p_j2nhO(o69n})ofxpiIT zzQaAi<|#p?DR}P;&-apdweoZ8I>kMOGICMR74o~Dzkg5S7+zY-y@&_DuZe`aaUbL5 zYZSJT7oyrqZ;{@?W<33$(fB}~apb>1S;fdZn|#56TOg^*vrPe?%CPgJ~y3LgQghpQ!9EMx*cu(q<7qPQDG?P03rDGJSY9ko4H(drJEM*?$C&@nA6-`|jjr>Gw5(3i{f{)UtV&<4W73tQ6)F<|j1&zpDymq$j;0 z9SkH-1^e#rOtnlMuG7X=mW|BSZK2_$_2Q){+=mDkwuM*!PbERNq}R6K>*RfApXcIP zAu7(#yGuzQMF;p38)qYVck=8UH-94ItnvK+ZxX3Tro&Y3izmpG8FeKlZ5bJt5WYlu zd(zL^(a`fwwnBZ3`*SZM{=}x0;JwPEy|-okp%?yhMUbA+<(KGW48YgCIG;-5@KPsk zUHVF|C2wSUxDFrN3i{DlT`h1L>0ad1b%C;a*=LG3qMQ;uzs&O{ zN?1r>H|8bNNPKT!oJV}LeUU#BaCQ@J%N@+ix?YekD)BNjg#U(#=ZZ!62%+3mdX$Ep zi#)mW%=nWB&h!lR-;{FM<{Zo0Hwd>SXBF=2($=h^_yZ|t7V(qR)|_V-2^U9Q%}HxS zyaw^8+*P^xQxs=2`Y;q=(X*l;O()5F$ z-&YFapSjQ2!j#^PO1km>1k(PZtWu;k=H1Gq#pPLCtVp`9;tYkZL8RySz16Pra4|1T zBQcc1bxq-=Km-G5#l&dYz0zXMj{*(ICr2=C_P z-Rl%Ok$VW~Il1fe?w{NTdH#fVbbYanKY*+FQHxWB7yo+|p@Jb~PR2{k$yAQ`?`t0M zg%muD=QRmGAWxqEyx)tA_eonzxzV_FjUnGY%E(B*#Q2J|xuofG=aX5Dm`kC((T@iS zxl3{vv@PyJ9xtA~um$SHvJ|$2JcG&eFFvx*3KQQ=d>?mnDr-Y}Z^FKM$zJ_Pn`O%8 z|LT-LF$x<;axvqtaP)>R(&H1JWju$K|J)PIev+ zBJ&**bWJ6V|B{X8@5q@H^J^y3XK?@b>SQB+RCJee_)qURpSgcuXDPE2WpBn{@)Rb# zf(HKJjvAHoCxn-Dg_2O$hR0AzEbi%~z2b%6*D4#XO$D2H7N7Vz-q}U?CYgTnP6QQY z;`tWa&=KUB%^gO14x82h|K`2uI)B4?Sc(F4WygMGTtr$vZig1@%142NNk7VqQMk8p zZ_#sm{mZjs#0ydAe9Fj4{te`5OSm%Wr7?_qCTWN5dm-3a-x72M@#1?MR{RJBZs7%8 zOL+GC%1(NJ(y!Sng(ii@dX`L{~QMO_VvCJH9PLMHc6mB{q+HKsmW~+l1b> z(rLU@jF<8=0@bMW_w|tH1$ma-j!a#iH6!1CypQoHCkNrvG%(ulmoN+Owc_4Sp3}S^ zhkJ?V|7x6v56S%AR{Yr-Kn7jcxvx;*d(6noN2s7A_bAe$*gQi?Z?DYu`e8fMi?WiF zR*lBCCx2DEL0MF_Xh1Z|Ps`n(=iPbMop2=5hw44*cXH9HwIt-`VPpy@Ls-`%G9)Fl zt{VTTQ1QVO_Q*af!21_?Co_4X+BD_SmC)e%wKLC>aSx}Cc;qif*e%MV`V{v2ib)_U z@up--PJ>#LaUFLBo2QYj;116U5>79uFg)h?lR?kgkL~QgLPqZADnudeU#&2Kp1$b(e~h^ZYjM zvuWmu`SmGj>GWIO`c(AAKB+-wUB?a1YM#}ivSl{jjY{s3Hj;uPp^vT98?W1U(-R)Z zvtwuyN*5?IkVl@AJPat*J|o>_|CRso?wn)#|duACSI>2DRqa^@2k3 zQs5k(6|iYF$+MEXAcg&b`MB3}hm!Xs`L@xxQiOH6OL?HHysbF}55jEPNAt)T#0#}~ z9>?Z+NqR-n^yh54n%Kfjj1L{#!&$$(k3DRj!DOmUBP!9@1N>DR=NSdv<deZ+UO_%;t zn@#`~HYTI4U|UcW+f$`wC)|YeBD@rpyl+Ws%KZ;%C3&v`4NOkq9c-b)^b*%HTb7A2 z4dltn`?`|Y#thK@KSajdRFa2+!YMG1eX%Cb4wLaB*5cV}?lgoeawnvqo>chJ7D$rk zicX$hr2pbxL3ljRvk^{*6{w>;%^%kaVH?@6HR3t+>9{#>s@M5L^#Ff68v=lZ& zCi4HjD$wW{R5F0)J8TE4D~${vsVIQ^xgBM_(}ld-HUDjG=HCTnpwMa*(u2(Hsk|q5 zZZa1j&9Md4wV5N4_L%St(l6U`3KM@xxE>WAw~aqWI5lOIQyKPp>IpLr^GT>l#`rd~ zp6@2}L0j2*3QNWPl|ss6AM&-r^~6hZ>&il5^9Xy<_}aWz3e%7;3*jl`{e6`p-(R*| zr9IdFUra(lUT$n#_uXbFPli?8rHCKa2-pU`!%~s^uJkpbL-{-x9+%ZYJfw9SVhwxEPUgrOStz-y=yy9MC z3#mrt*2KqCp{{(~NeM5o6`%B^veht*o|VKI-2LqH8}|7r8gZ05Zd0DF&G?WsT|4z# zuaWk_7L(@r=ZF(*qxRUeY*hRQjTuJX285SWNgMRHLu#`*{F%Qq%0|)>{=_>SDXS^@ zmXSX;HY7cWw3x)*RQytd#Iq#M=iXo|jzI+@c&5Lqplcu%2k`tLX)P&K*EHKxg`4x< z7~(g0zL@(A`MZ)oDS6-HMxGtFWh;Ml(l(oOh#wq~=>ae7An~2e)QPlY6jaVu#$#s~ z@v`^_k&om(L_EoVMqnFxQ`<)EBF~?c)!V+`Oto@N;Ev3@=3@TekntF?={D&e4-a!E zpx|k$m20cP`A%W|Z3Q;TnMWnVX^5`F-2J&H+D?3?oGd&`rH5SUDKo#VJSSz})6d9u zlc6Y)4BUN)Pp6WEq5@kGRRWhQT3+rXWKW7tOMSv>v1)rvbhd0z3n zi6@2kX@obo59zKK4@wZxmEGVJ<3SPbGxXvu6*ji%>!=_y>3?HS-urzuAzxkFfOl=4c;+Z$S-Nwt0xhE5^ zVDtD{b5Ti08*WBeS1_Ec0GEj!DdYFoGOXzd3DS?Sp_?66oJV;BpJ9j)< z_}b)mHu3C@$FPNhP+t`mn8ps(yLR(I80|Ny@e@lIU+v!c3>VwsNbof zR#8Z7?%7J@`ov2yXxLUN=wd6L#`99dH{oTQro0)+x0rh{&(`Db>p6kWE+Q+Y8pfU7huOG`K>6@1~&#XXgKw0Z1Q<5>eL*oY~~JB{?0JRe3{9nyyX zr*gfri3;+PFDB_nsB|3nRqjCIeR!Tw-~TgFz%^QSh=iOJqN^`%AkCMIAMrK?WuqWn zCrO)cd-4H`5zj=SIc%CQ`J$6=6z}K?rhHu)u^X18?E9F5e24Y>|Ev`7`+7+@ty;`I zmlr+|zt0PP*xOc6-WJ%%R*;pvk+{E8$TIS6v-y6PIi9pTG_Vil6y;eq)Rlqvv*?dH z_K;zpeaX)jzJ^TRqz&N3HDnCq9>Yt8Y^9zO>@WNOA8C0h=YlOO8Rb+VZ*%USl$(z` z2X|5K_TPATjs}z?k{K6qFW~+{d^82WqL9Xf50LhbcrwDe-tk^I&x(-Vh)$d)tv+eG z+L9iNa2||j)093|KlOIYkvj@crczRAQjbwWTx?9*C2FWkd?I%M`O=a8l6)~3hTPmi zr0c4KRmuC1(%a&2ll;G5JMz3Q<;~>&#ru_bQkcAPBeCLo@IqW$&^8_{Bc9sE=aFe4 zab4fIe^IHf5DNKe^Q0v0E%#{dzj^kC{L2Y{Rz|KZRH|zz`8V2kVq2f=tIm1Ux%q>T$jhZc2J#{CyoH&m_w5 zT)w`|J2cDhpP^~yR+%>^oVPpo=9`z}du{%5rSY!mGv9dU-Zp!p*O08yvt-X2nj=f6 zF3m%y2k-al9+o#tww(TyVyTs+V7szWwz9#^ny%XEQSCGj6}a#I)<}cA!<}wg3v6rN#gN diff --git a/po/ca.po b/po/ca.po index e3c80656..770a9a33 100644 --- a/po/ca.po +++ b/po/ca.po @@ -2,7 +2,7 @@ # Copyright © 2002, 2003, 2004, 2005 Free Software Foundation, Inc. # Antoni Bella Perez , 2002, 2003. # Jordi Mallach , 2004, 2005. -# Josep Puigdemont , 2005 +# Josep Puigdemont , 2005 # # Permission is granted to freely copy and distribute # this file and modified versions, provided that this @@ -11,11 +11,11 @@ # msgid "" msgstr "" -"Project-Id-Version: util-linux-2.13-pre1\n" +"Project-Id-Version: util-linux 2.13-pre3\n" "Report-Msgid-Bugs-To: Adrian Bunk \n" "POT-Creation-Date: 2005-08-14 18:14+0200\n" -"PO-Revision-Date: 2005-08-04 14:23+0200\n" -"Last-Translator: Jordi Mallach \n" +"PO-Revision-Date: 2005-09-17 13:40+0200\n" +"Last-Translator: Josep Puigdemont \n" "Language-Team: Catalan \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -168,9 +168,9 @@ msgstr "forma d'ús: %s [ -n ] dispositiu\n" #: disk-utils/mkfs.cramfs.c:778 disk-utils/mkfs.minix.c:626 #: disk-utils/mkswap.c:522 misc-utils/ddate.c:179 misc-utils/rename.c:79 #: misc-utils/script.c:142 sys-utils/readprofile.c:197 -#, fuzzy, c-format +#, c-format msgid "%s (%s)\n" -msgstr "%s: %s (%s)\n" +msgstr "%s (%s)\n" #: disk-utils/fdformat.c:130 #, c-format @@ -877,9 +877,9 @@ msgid "%s: Out of memory!\n" msgstr "%s: No hi ha prou memòria\n" #: disk-utils/mkfs.c:103 -#, fuzzy, c-format +#, c-format msgid "mkfs (%s)\n" -msgstr "%s: %s (%s)\n" +msgstr "mkfs (%s)\n" #: disk-utils/mkfs.cramfs.c:124 #, c-format @@ -7222,9 +7222,9 @@ msgid "%s: can't read temporary file.\n" msgstr "%s: no s'hapogut llegir el fitxer temporal.\n" #: misc-utils/cal.c:313 -#, fuzzy, c-format +#, c-format msgid "%s from %s\n" -msgstr "%s des de %s%s\n" +msgstr "%s de %s\n" #: misc-utils/cal.c:327 msgid "illegal month value: use 1-12" @@ -10198,13 +10198,6 @@ msgid "Out of memory when growing buffer.\n" msgstr "" "S'ha esgotat la memòria en augmentar la mida de la memòria intermèdia.\n" -#, fuzzy -#~ msgid "mkfs from %s\n" -#~ msgstr "%s des de %s%s\n" - -#~ msgid "mkfs version %s (%s)\n" -#~ msgstr "mkfs versió %s (%s)\n" - #~ msgid "flock: unknown option, aborting.\n" #~ msgstr "flock: es desconeix l'opció, s'està avortant.\n" -- 2.39.5