From: msweet Date: Wed, 31 Aug 2011 01:58:55 +0000 (+0000) Subject: Merge changes from CUPS 1.6svn-r9939. X-Git-Tag: release-1.6.3~39 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fcups.git;a=commitdiff_plain;h=a48458814a4c26a6430b27105c0ab747c907473f Merge changes from CUPS 1.6svn-r9939. git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@3392 a1ca3aef-8c08-0410-bb20-df032aa958be --- diff --git a/CHANGES-1.5.txt b/CHANGES-1.5.txt new file mode 100644 index 000000000..100312bab --- /dev/null +++ b/CHANGES-1.5.txt @@ -0,0 +1,182 @@ +CHANGES-1.5.txt +--------------- + +CHANGES IN CUPS V1.5.1 + + - Documentation updates (STR #3885) + - The scheduler now logs config file errors to stderr (STR #3936) + - The configure script incorrectly used bundle-based localizations on + Linux (STR #3938) + - The cups-driverd helper program did not cache .drv files properly, + sometimes leading to a crash (STR #3921) + - CUPS did not build on stock Mac OS X installations. + - Encryption was broken with OpenSSL. + - ipptool's XML output used date/time values with timezone offsets, + which are not supported by Mac OS X's NSDate class. + - Several programs did not support the cupsFilter2 keyword in PPD files. + - The IPP backend incorrectly reported spool-area-full states. + - cupsMarkOptions() did not protect against a bad PPD that was missing + one or more standard Duplex options. + - The PostScript filter did not mirror N-up output properly. + - The ipptool program did not validate UTF-8 strings in XML output. + - Fixed supply level reporting for some printers. + - The scheduler no longer automatically logs debug messages for jobs + that were held or canceled. + - The cupsSendRequest function did not flush remaining response data + from a previous request, leading to apparent chunking issues. + - The scheduler did not report the correct version in the Server: header + (STR #3903) + - The scheduler did not support 1284 device IDs reported by driver + interface programs longer than 127 characters (STR #3871) + - The image filters did not support loading images larger than the + RIPCache setting (STR #3901) + - "PAGE: total NNN" messages did not get logged properly (STR #3887) + - Updated the PWG Raster support to conform to the current draft of the + PWG Raster Format specification. + - The PWG Raster filter did not always write the correct number of + padding lines on the bottom of the page (STR #3904) + - When reporting a denial-of-service attack from the domain socket, the + address reported does not always contain the correct path (STR #3888) + - Badly formed GIF files could cause the image filters to crash + (STR #3914) + - Jobs canceled at the printer were retried by the IPP backend. + - "cupsfilter -u" deleted the input file instead of the PPD file. + - The scheduler did not compute the cost of PPD filters defined using + the cupsFilter2 keyword properly. + - The scheduler did not correctly support the maxsize() attribute for + PPD filters. + + +CHANGES IN CUPS V1.5.0 + + - Documentation updates. + - Localization update (STR #3865) + - Needed to limit TLS to v1.0 on some versions of Mac OS X. + - The snmp backend did not work with some printers. + + +CHANGES IN CUPS V1.5rc1 + + - Compile fixes (STR #3849, STR #3850) + - The scheduler didn't check for empty values for several configuration + directives (STR #3861) + - ipptool didn't generate valid XML when a test was skipped. + - Added additional error checking to the 1284 device ID code (STR #3858) + - Fixed some compatibility issues migrating from the old usblp backend + to the libusb backend (STR #3860) + - Fixed the wake-from-sleep printing behavior on Mac OS X. + - The scheduler incorrectly allowed jobs to be held from a terminating + state. + - The cups-driverd program could crash when a PPD was renamed. + - The dnssd backend took too long to discover printers on large or busy + networks with the new default timeout used by lpinfo and the web + interface. This resulted in "lost" printers. + + +CHANGES IN CUPS V1.5b2 + + - Documentation updates. + - Localization updates (STR #3845) + - Compiler warning cleanup. + - Fixed PIE support for Linux (STR #3846) + - Made httpSetTimeout API public and use it in the IPP backend to avoid + timeout errors. + - The scheduler incorrectly set the "authenticated" printer-type bit for + remote queues using authentication. + + +CHANGES IN CUPS V1.5b1 + + - The CUPS library now supports per-connection HTTP timeouts and + callbacks. + - The CUPS library now supports (limited) SSL/TLS X.509 certificate + validation and revocation (STR #1616) + - Updated the PostScript filter to support IncludeFeature in more + circumstances (STR #3417) + - The schedule did not correctly parse some IPv6 addresses and masks in + the cupsd.conf file (STR #3533) + - Fixed a case-insensitive string comparison issue for locales that do + not treat "I" and "i" as equivalent (STR #3800) + - The scheduler reported an incorrect job-printer-uri value when sharing + was not enabled (STR #3639) + - The scheduler now allows the ServerAlias directive to contain multiple + hostnames separated by spaces or commas (STR #3813) + - The scheduler now sets the process group for child processes and + manages the group (STR #2829) + - Fixed some minor issues discovered by a Coverity scan (STR #3838) + - The scheduler now more carefully creates and removes configuration, + cache, and state files (STR #3715) + - The lpadmin command now allows default option values to be deleted + (STR #2959) + - The lpadmin command now allows the cupsIPPSupplies and + cupsSNMPSupplies keywords to be set in a PPD file (STR #3825) + - Moving a held job no longer releases it (STR #3839) + - Restored support for GNU TLS and OpenSSL with threading enabled + (STR #3605) + - Fixed a confusing error message from cups-polld (STR #3806) + - Increased the default RIPCache value to 128MB (STR #3535) + - MIME errors are now routed to the error_log file (STR #2410) + - Updated PDF filter to support new Ghostscript ps2write device + (STR #3766) + - Updated PDF filter to support new Poppler option to preserve page + sizes in PDF files when the user has not selected a particular media + size (STR #3689) + - Added new PWG Raster filter for IPP Everywhere printer support. + - Added job-uuid, printer-uuid, and subscription-uuid attributes. + - Added support for the cupsSingleFile PPD keyword. + - Dropped support for the printer-state-history attribute (STR #3654) + - Added support for a new cupsIPPSupplies keyword in PPD files to allow + drivers to disable IPP supply level reporting. + - Added support for a new cupsFilter2 keyword in PPD files to allow for + the propagation of the actual MIME media type produced by a filter. + - The scheduler did not always get the correct Kerberos username when + authenticating (STR #3670) + - Added new cupsRasterOpenIO function and CUPS_RASTER_WRITE_PWG to the + CUPS imaging library to support printing to IPP Everywhere raster + printers. + - The scheduler now provides default values for the pages-per-minute and + pages-per-minute-color attributes for PPD files that lack a + Throughput keyword. + - Email notifications did not work on Mac OS X. + - The cupstestppd program now shows an error for files missing a + CloseGroup keyword (STR #3668) + - Name resolution errors no longer cause queues to stop (STR #3719, + STR #3753) + - Added a new cups-exec helper program that applies security profiles + to filters, port monitors, backends, CGI programs, and mini-daemons. + - The web interface can now be disabled using the WebInterface directive + in cupsd.conf (STR #2625) + - The scheduler now provides privacy controls for jobs and subscriptions + (STR #2969) + - Added new cupsArrayNew3 API which offers memory management of array + elements. + - Added several new color spaces to the CUPS raster format (STR #3419) + - The Validate-Job operation now uses the same policy as Print-Job by + default. + - CUPS now uses iconv to implement all of its character encoding + support (STR #3097) + - The scheduler now implements the Cancel-Jobs, Cancel-My-Jobs, and + Close-Job operations along with the job-ids operation attribute from + PWG 5100.11. + - The main CUPS header () no longer includes the PPD header + (). + - The scheduler and CUPS API now support the print-quality job template + attribute. + - The scheduler no longer supports the old Mac OS X Server quota + plugin. + - The scheduler now allows writing to /Users/Shared from print filters + on Mac OS X. + - CUPS no longer supports the old ~/.cupsrc or ~/.lpoptions files from + CUPS 1.1.x. The ~/.cups/client.conf and ~/.cups/lpoptions files that + were introduced in CUPS 1.2 must now be used. + - The ipptest tool is now a first-class user program and has several + improvements along with new documentation (STR #3484) + - The cupstestppd tool now warns about non-unique filenames and + provides a way to ignore all filename warnings. + - Dropped support for the recoverable: and recovered: message prefixes. + - The scheduler now requires that filters and backends have group write + permissions disabled. + - The PPD compiler now checks for overlapping filenames when writing + PPD files. + - The HP-GL/2 filter is no longer included with CUPS (STR #3322) + - The SCSI backend is no longer included with CUPS (STR #3500) diff --git a/CHANGES.txt b/CHANGES.txt index 3de675517..58b9973db 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,162 +1,10 @@ -CHANGES.txt - 2011-08-06 ------------------------- +CHANGES.txt - 1.6b1 - 2011-08-27 +-------------------------------- -CHANGES IN CUPS V1.5.1 +CHANGES IN CUPS V1.6b1 - - Documentation updates (STR #3885) - - The scheduler did not report the correct version in the Server: header - (STR #3903) - - The scheduler did not support 1284 device IDs reported by driver - interface programs longer than 127 characters (STR #3871) - - The image filters did not support loading images larger than the - RIPCache setting (STR #3901) - - "PAGE: total NNN" messages did not get logged properly (STR #3887) - - Updated the PWG Raster support to conform to the current draft of the - PWG Raster Format specification. - - The PWG Raster filter did not always write the correct number of - padding lines on the bottom of the page (STR #3904) - - When reporting a denial-of-service attack from the domain socket, the - address reported does not always contain the correct path (STR #3888) - - Badly formed GIF files could cause the image filters to crash - (STR #3914) - - Jobs canceled at the printer were retried by the IPP backend. - - "cupsfilter -u" deleted the input file instead of the PPD file. - - The scheduler did not compute the cost of PPD filters defined using - the cupsFilter2 keyword properly. - - The scheduler did not correctly support the maxsize() attribute for - PPD filters. - - -CHANGES IN CUPS V1.5.0 - - - Documentation updates. - - Localization update (STR #3865) - - Needed to limit TLS to v1.0 on some versions of Mac OS X. - - The snmp backend did not work with some printers. - - -CHANGES IN CUPS V1.5rc1 - - - Compile fixes (STR #3849, STR #3850) - - The scheduler didn't check for empty values for several configuration - directives (STR #3861) - - ipptool didn't generate valid XML when a test was skipped. - - Added additional error checking to the 1284 device ID code (STR #3858) - - Fixed some compatibility issues migrating from the old usblp backend - to the libusb backend (STR #3860) - - Fixed the wake-from-sleep printing behavior on Mac OS X. - - The scheduler incorrectly allowed jobs to be held from a terminating - state. - - The cups-driverd program could crash when a PPD was renamed. - - The dnssd backend took too long to discover printers on large or busy - networks with the new default timeout used by lpinfo and the web - interface. This resulted in "lost" printers. - - -CHANGES IN CUPS V1.5b2 - - - Documentation updates. - - Localization updates (STR #3845) - - Compiler warning cleanup. - - Fixed PIE support for Linux (STR #3846) - - Made httpSetTimeout API public and use it in the IPP backend to avoid - timeout errors. - - The scheduler incorrectly set the "authenticated" printer-type bit for - remote queues using authentication. - - -CHANGES IN CUPS V1.5b1 - - - The CUPS library now supports per-connection HTTP timeouts and - callbacks. - - The CUPS library now supports (limited) SSL/TLS X.509 certificate - validation and revocation (STR #1616) - - Updated the PostScript filter to support IncludeFeature in more - circumstances (STR #3417) - - The schedule did not correctly parse some IPv6 addresses and masks in - the cupsd.conf file (STR #3533) - - Fixed a case-insensitive string comparison issue for locales that do - not treat "I" and "i" as equivalent (STR #3800) - - The scheduler reported an incorrect job-printer-uri value when sharing - was not enabled (STR #3639) - - The scheduler now allows the ServerAlias directive to contain multiple - hostnames separated by spaces or commas (STR #3813) - - The scheduler now sets the process group for child processes and - manages the group (STR #2829) - - Fixed some minor issues discovered by a Coverity scan (STR #3838) - - The scheduler now more carefully creates and removes configuration, - cache, and state files (STR #3715) - - The lpadmin command now allows default option values to be deleted - (STR #2959) - - The lpadmin command now allows the cupsIPPSupplies and - cupsSNMPSupplies keywords to be set in a PPD file (STR #3825) - - Moving a held job no longer releases it (STR #3839) - - Restored support for GNU TLS and OpenSSL with threading enabled - (STR #3605) - - Fixed a confusing error message from cups-polld (STR #3806) - - Increased the default RIPCache value to 128MB (STR #3535) - - MIME errors are now routed to the error_log file (STR #2410) - - Updated PDF filter to support new Ghostscript ps2write device - (STR #3766) - - Updated PDF filter to support new Poppler option to preserve page - sizes in PDF files when the user has not selected a particular media - size (STR #3689) - - Added new PWG Raster filter for IPP Everywhere printer support. - - Added job-uuid, printer-uuid, and subscription-uuid attributes. - - Added support for the cupsSingleFile PPD keyword. - - Dropped support for the printer-state-history attribute (STR #3654) - - Added support for a new cupsIPPSupplies keyword in PPD files to allow - drivers to disable IPP supply level reporting. - - Added support for a new cupsFilter2 keyword in PPD files to allow for - the propagation of the actual MIME media type produced by a filter. - - The scheduler did not always get the correct Kerberos username when - authenticating (STR #3670) - - Added new cupsRasterOpenIO function and CUPS_RASTER_WRITE_PWG to the - CUPS imaging library to support printing to IPP Everywhere raster - printers. - - The scheduler now provides default values for the pages-per-minute and - pages-per-minute-color attributes for PPD files that lack a - Throughput keyword. - - Email notifications did not work on Mac OS X. - - The cupstestppd program now shows an error for files missing a - CloseGroup keyword (STR #3668) - - Name resolution errors no longer cause queues to stop (STR #3719, - STR #3753) - - Added a new cups-exec helper program that applies security profiles - to filters, port monitors, backends, CGI programs, and mini-daemons. - - The web interface can now be disabled using the WebInterface directive - in cupsd.conf (STR #2625) - - The scheduler now provides privacy controls for jobs and subscriptions - (STR #2969) - - Added new cupsArrayNew3 API which offers memory management of array - elements. - - Added several new color spaces to the CUPS raster format (STR #3419) - - The Validate-Job operation now uses the same policy as Print-Job by - default. - - CUPS now uses iconv to implement all of its character encoding - support (STR #3097) - - The scheduler now implements the Cancel-Jobs, Cancel-My-Jobs, and - Close-Job operations along with the job-ids operation attribute from - PWG 5100.11. - - The main CUPS header () no longer includes the PPD header - (). - - The scheduler and CUPS API now support the print-quality job template - attribute. - - The scheduler no longer supports the old Mac OS X Server quota - plugin. - - The scheduler now allows writing to /Users/Shared from print filters - on Mac OS X. - - CUPS no longer supports the old ~/.cupsrc or ~/.lpoptions files from - CUPS 1.1.x. The ~/.cups/client.conf and ~/.cups/lpoptions files that - were introduced in CUPS 1.2 must now be used. - - The ipptest tool is now a first-class user program and has several - improvements along with new documentation (STR #3484) - - The cupstestppd tool now warns about non-unique filenames and - provides a way to ignore all filename warnings. - - Dropped support for the recoverable: and recovered: message prefixes. - - The scheduler now requires that filters and backends have group write - permissions disabled. - - The PPD compiler now checks for overlapping filenames when writing - PPD files. - - The HP-GL/2 filter is no longer included with CUPS (STR #3322) - - The SCSI backend is no longer included with CUPS (STR #3500) + - The PHP module has been removed (STR #3932) + - The bannertops, commandtoescpx, commandtopclx, imagetops, + imagetoraster, pdftops, rastertoescpx, rastertopclx, and texttops + filters have been removed (STR #3930) + - The serial and parallel backends have been removed (STR 3935) diff --git a/Makedefs.in b/Makedefs.in index 0d4397f5b..b9a97a3b1 100644 --- a/Makedefs.in +++ b/Makedefs.in @@ -30,7 +30,6 @@ LD = @LD@ LIBTOOL = @LIBTOOL@ LN = @LN@ -sf MV = @MV@ -PHPCONFIG = @PHPCONFIG@ RANLIB = @RANLIB@ RM = @RM@ -f RMDIR = @RMDIR@ @@ -79,19 +78,15 @@ UNINSTALL_LANGUAGES = @UNINSTALL_LANGUAGES@ LIBCUPS = @LIBCUPS@ LIBCUPSCGI = @LIBCUPSCGI@ -LIBCUPSDRIVER = @LIBCUPSDRIVER@ LIBCUPSIMAGE = @LIBCUPSIMAGE@ LIBCUPSMIME = @LIBCUPSMIME@ LIBCUPSPPDC = @LIBCUPSPPDC@ LIBCUPSSTATIC = @LIBCUPSSTATIC@ -LIBJPEG = @LIBJPEG@ LIBLDAP = @LIBLDAP@ LIBMALLOC = @LIBMALLOC@ LIBPAPER = @LIBPAPER@ -LIBPNG = @LIBPNG@ LIBSLP = @LIBSLP@ LIBGSSAPI = @LIBGSSAPI@ -LIBTIFF = @LIBTIFF@ LIBUSB = @LIBUSB@ LIBWRAP = @LIBWRAP@ LIBZ = @LIBZ@ @@ -135,7 +130,6 @@ ALL_CXXFLAGS = -I.. -D_CUPS_SOURCE $(CXXFLAGS) $(SSLFLAGS) \ ARCHFLAGS = @ARCHFLAGS@ ARFLAGS = @ARFLAGS@ BACKLIBS = @BACKLIBS@ -BANNERTOPS = @BANNERTOPS@ BUILDDIRS = @BUILDDIRS@ CFLAGS = @CPPFLAGS@ @CFLAGS@ COMMONLIBS = @LIBS@ @@ -147,28 +141,19 @@ DNSSD_BACKEND = @DNSSD_BACKEND@ DSOFLAGS = -L../cups @DSOFLAGS@ DSOLIBS = @DSOLIBS@ $(COMMONLIBS) DNSSDLIBS = @DNSSDLIBS@ -FONTS = @FONTS@ -IMGLIBS = @IMGLIBS@ -IMGFILTERS = @IMGFILTERS@ LAUNCHDLIBS = @LAUNCHDLIBS@ LDFLAGS = -L../cgi-bin -L../cups -L../filter -L../ppdc \ -L../scheduler @LDARCHFLAGS@ \ @LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM) -LEGACY_BACKENDS = @LEGACY_BACKENDS@ LINKCUPS = @LINKCUPS@ $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(LIBZ) LINKCUPSIMAGE = @LINKCUPSIMAGE@ LIBS = $(LINKCUPS) $(COMMONLIBS) OPTIM = @OPTIM@ OPTIONS = PAMLIBS = @PAMLIBS@ -PAP = @PAP@ -PDFTOPS = @PDFTOPS@ -PHPDIR = @PHPDIR@ -PHPOPTIONS = @PHPOPTIONS@ -I../.. `$(PHPCONFIG) --includes` SERVERLIBS = @SERVERLIBS@ SSLFLAGS = @SSLFLAGS@ SSLLIBS = @SSLLIBS@ -TEXTTOPS = @TEXTTOPS@ UNITTESTS = @UNITTESTS@ diff --git a/Makefile b/Makefile index 747955d75..96c73aba8 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ include Makedefs # Directories to make... # -DIRS = cups test $(BUILDDIRS) $(PHPDIR) $(FONTS) +DIRS = cups test $(BUILDDIRS) # @@ -285,7 +285,7 @@ docset: apihelp # sloc: - for dir in cups cupslite scheduler; do \ + for dir in cups scheduler; do \ (cd $$dir; $(MAKE) $(MFLAGS) sloc) || exit 1;\ done diff --git a/backend/Dependencies b/backend/Dependencies index 4f99c17ef..291418160 100644 --- a/backend/Dependencies +++ b/backend/Dependencies @@ -28,24 +28,6 @@ dnssd.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h dnssd.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h dnssd.o: ../cups/transcode.h ../cups/thread-private.h ../cups/snmp-private.h dnssd.o: ../cups/backend.h ../cups/sidechannel.h ../cups/array.h -parallel.o: backend-private.h ../cups/cups-private.h ../cups/cups.h -parallel.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -parallel.o: ../cups/array.h ../cups/language.h ../cups/string-private.h -parallel.o: ../config.h ../cups/debug-private.h ../cups/ppd-private.h -parallel.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h -parallel.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h -parallel.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h -parallel.o: ../cups/transcode.h ../cups/thread-private.h -parallel.o: ../cups/snmp-private.h ../cups/backend.h ../cups/sidechannel.h -serial.o: backend-private.h ../cups/cups-private.h ../cups/cups.h -serial.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -serial.o: ../cups/array.h ../cups/language.h ../cups/string-private.h -serial.o: ../config.h ../cups/debug-private.h ../cups/ppd-private.h -serial.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h -serial.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h -serial.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h -serial.o: ../cups/transcode.h ../cups/thread-private.h ../cups/snmp-private.h -serial.o: ../cups/backend.h ../cups/sidechannel.h snmp.o: backend-private.h ../cups/cups-private.h ../cups/cups.h snmp.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h snmp.o: ../cups/array.h ../cups/language.h ../cups/string-private.h diff --git a/backend/Makefile b/backend/Makefile index 5a0521cff..27f4e6859 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -21,13 +21,37 @@ include ../Makedefs # Object files... # -RBACKENDS = ipp lpd $(DNSSD_BACKEND) -UBACKENDS = $(LEGACY_BACKENDS) serial snmp socket usb -UNITTESTS = test1284 testbackend testsupplies -TARGETS = libbackend.a $(RBACKENDS) $(UBACKENDS) -LIBOBJS = ieee1284.o network.o runloop.o snmp-supplies.o -OBJS = ipp.o lpd.o dnssd.o parallel.o serial.o snmp.o \ - socket.o test1284.o testbackend.o testsupplies.o usb.o +RBACKENDS = \ + ipp \ + lpd \ + $(DNSSD_BACKEND) +UBACKENDS = \ + snmp \ + socket \ + usb +UNITTESTS = \ + test1284 \ + testbackend \ + testsupplies +TARGETS = \ + libbackend.a \ + $(RBACKENDS) \ + $(UBACKENDS) +LIBOBJS = \ + ieee1284.o \ + network.o \ + runloop.o \ + snmp-supplies.o +OBJS = \ + ipp.o \ + lpd.o \ + dnssd.o \ + snmp.o \ + socket.o \ + test1284.o \ + testbackend.o \ + testsupplies.o \ + usb.o # @@ -56,7 +80,7 @@ unittests: $(UNITTESTS) # clean: - $(RM) $(OBJS) $(TARGETS) $(UNITTESTS) $(LIBOBJS) http mdns + $(RM) $(OBJS) $(TARGETS) $(UNITTESTS) $(LIBOBJS) http https ipps mdns # @@ -226,24 +250,6 @@ lpd: lpd.o ../cups/$(LIBCUPS) libbackend.a $(CC) $(LDFLAGS) -o lpd lpd.o libbackend.a $(LIBS) -# -# parallel -# - -parallel: parallel.o ../cups/$(LIBCUPS) libbackend.a - echo Linking $@... - $(CC) $(LDFLAGS) -o parallel parallel.o libbackend.a $(LIBS) - - -# -# serial -# - -serial: serial.o ../cups/$(LIBCUPS) libbackend.a - echo Linking $@... - $(CC) $(LDFLAGS) -o serial serial.o libbackend.a $(BACKLIBS) $(LIBS) - - # # snmp # diff --git a/backend/easysw-firewire-design.txt b/backend/easysw-firewire-design.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/backend/easysw-firewire-linux.txt b/backend/easysw-firewire-linux.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/backend/ipp.c b/backend/ipp.c index d5e18fefc..67d05cfd9 100644 --- a/backend/ipp.c +++ b/backend/ipp.c @@ -111,7 +111,7 @@ static const char * const pattrs[] = /* Printer attributes we want */ "printer-is-accepting-jobs", "printer-state", "printer-state-message", - "printer-state-reasons", + "printer-state-reasons" }; static const char * const remote_job_states[] = { /* Remote job state keywords */ @@ -2824,6 +2824,7 @@ update_reasons(ipp_attribute_t *attr, /* I - printer-state-reasons or NULL */ if (strcmp(reason, "none") && strcmp(reason, "none-report") && strcmp(reason, "paused") && + strncmp(reason, "spool-area-full", 15) && strcmp(reason, "com.apple.print.recoverable-warning") && strncmp(reason, "cups-", 5)) cupsArrayAdd(new_reasons, reason); diff --git a/backend/parallel.c b/backend/parallel.c deleted file mode 100644 index 125aa8141..000000000 --- a/backend/parallel.c +++ /dev/null @@ -1,676 +0,0 @@ -/* - * "$Id: parallel.c 7810 2008-07-29 01:11:15Z mike $" - * - * Parallel port backend for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * "LICENSE" which should have been included with this file. If this - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * main() - Send a file to the specified parallel port. - * list_devices() - List all parallel devices. - * side_cb() - Handle side-channel requests... - */ - -/* - * Include necessary headers. - */ - -#include "backend-private.h" - -#ifdef __hpux -# include -#else -# include -#endif /* __hpux */ - -#ifdef WIN32 -# include -#else -# include -# include -# include -# include -#endif /* WIN32 */ - -#ifdef __sgi -# include -# ifndef INV_EPP_ECP_PLP -# define INV_EPP_ECP_PLP 6 /* From 6.3/6.4/6.5 sys/invent.h */ -# define INV_ASO_SERIAL 14 /* serial portion of SGI ASO board */ -# define INV_IOC3_DMA 16 /* DMA mode IOC3 serial */ -# define INV_IOC3_PIO 17 /* PIO mode IOC3 serial */ -# define INV_ISA_DMA 19 /* DMA mode ISA serial -- O2 */ -# endif /* !INV_EPP_ECP_PLP */ -#endif /* __sgi */ - - -/* - * Local functions... - */ - -static void list_devices(void); -static int side_cb(int print_fd, int device_fd, int snmp_fd, - http_addr_t *addr, int use_bc); - - -/* - * 'main()' - Send a file to the specified parallel port. - * - * Usage: - * - * printer-uri job-id user title copies options [file] - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments (6 or 7) */ - char *argv[]) /* I - Command-line arguments */ -{ - char method[255], /* Method in URI */ - hostname[1024], /* Hostname */ - username[255], /* Username info (not used) */ - resource[1024], /* Resource info (device and options) */ - *options; /* Pointer to options */ - int port; /* Port number (not used) */ - int print_fd, /* Print file */ - device_fd, /* Parallel device */ - use_bc; /* Read back-channel data? */ - int copies; /* Number of copies to print */ - ssize_t tbytes; /* Total number of bytes written */ - struct termios opts; /* Parallel port options */ -#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) - struct sigaction action; /* Actions for POSIX signals */ -#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ - - - /* - * Make sure status messages are not buffered... - */ - - setbuf(stderr, NULL); - - /* - * Ignore SIGPIPE signals... - */ - -#ifdef HAVE_SIGSET - sigset(SIGPIPE, SIG_IGN); -#elif defined(HAVE_SIGACTION) - memset(&action, 0, sizeof(action)); - action.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &action, NULL); -#else - signal(SIGPIPE, SIG_IGN); -#endif /* HAVE_SIGSET */ - - /* - * Check command-line... - */ - - if (argc == 1) - { - list_devices(); - return (CUPS_BACKEND_OK); - } - else if (argc < 6 || argc > 7) - { - _cupsLangPrintf(stderr, - _("Usage: %s job-id user title copies options [file]"), - argv[0]); - return (CUPS_BACKEND_FAILED); - } - - /* - * If we have 7 arguments, print the file named on the command-line. - * Otherwise, send stdin instead... - */ - - if (argc == 6) - { - print_fd = 0; - copies = 1; - } - else - { - /* - * Try to open the print file... - */ - - if ((print_fd = open(argv[6], O_RDONLY)) < 0) - { - _cupsLangPrintError("ERROR", _("Unable to open print file")); - return (CUPS_BACKEND_FAILED); - } - - copies = atoi(argv[4]); - } - - /* - * Extract the device name and options from the URI... - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, cupsBackendDeviceURI(argv), - method, sizeof(method), username, sizeof(username), - hostname, sizeof(hostname), &port, - resource, sizeof(resource)); - - /* - * See if there are any options... - */ - - if ((options = strchr(resource, '?')) != NULL) - { - /* - * Yup, terminate the device name string and move to the first - * character of the options... - */ - - *options++ = '\0'; - } - - /* - * Open the parallel port device... - */ - - fputs("STATE: +connecting-to-device\n", stderr); - - do - { -#if defined(__linux) || defined(__FreeBSD__) - /* - * The Linux and FreeBSD parallel port drivers currently are broken WRT - * select() and bidirection I/O... - */ - - device_fd = open(resource, O_WRONLY | O_EXCL); - use_bc = 0; - -#else - if ((device_fd = open(resource, O_RDWR | O_EXCL)) < 0) - { - device_fd = open(resource, O_WRONLY | O_EXCL); - use_bc = 0; - } - else - use_bc = 1; -#endif /* __linux || __FreeBSD__ */ - - if (device_fd == -1) - { - if (getenv("CLASS") != NULL) - { - /* - * If the CLASS environment variable is set, the job was submitted - * to a class and not to a specific queue. In this case, we want - * to abort immediately so that the job can be requeued on the next - * available printer in the class. - */ - - _cupsLangPrintFilter(stderr, "INFO", - _("Unable to contact printer, queuing on next " - "printer in class.")); - - /* - * Sleep 5 seconds to keep the job from requeuing too rapidly... - */ - - sleep(5); - - return (CUPS_BACKEND_FAILED); - } - - if (errno == EBUSY) - { - _cupsLangPrintFilter(stderr, "INFO", - _("Printer busy; will retry in 30 seconds.")); - sleep(30); - } - else if (errno == ENXIO || errno == EIO || errno == ENOENT) - { - _cupsLangPrintFilter(stderr, "INFO", - _("Printer not connected; will retry in 30 " - "seconds.")); - sleep(30); - } - else - { - _cupsLangPrintError("ERROR", _("Unable to open device file")); - return (CUPS_BACKEND_FAILED); - } - } - } - while (device_fd < 0); - - fputs("STATE: -connecting-to-device\n", stderr); - - /* - * Set any options provided... - */ - - tcgetattr(device_fd, &opts); - - opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */ - - /**** No options supported yet ****/ - - tcsetattr(device_fd, TCSANOW, &opts); - - /* - * Finally, send the print file... - */ - - tbytes = 0; - - while (copies > 0 && tbytes >= 0) - { - copies --; - - if (print_fd != 0) - { - fputs("PAGE: 1 1\n", stderr); - lseek(print_fd, 0, SEEK_SET); - } - - tbytes = backendRunLoop(print_fd, device_fd, -1, NULL, use_bc, 1, side_cb); - - if (print_fd != 0 && tbytes >= 0) - _cupsLangPrintFilter(stderr, "INFO", _("Print file sent.")); - } - - /* - * Close the socket connection and input file and return... - */ - - close(device_fd); - - if (print_fd != 0) - close(print_fd); - - return (CUPS_BACKEND_OK); -} - - -/* - * 'list_devices()' - List all parallel devices. - */ - -static void -list_devices(void) -{ -#if defined(__hpux) || defined(__sgi) || defined(__sun) - static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz"; - /* Funky hex numbering used for some devices */ -#endif /* __hpux || __sgi || __sun */ - -#ifdef __linux - int i; /* Looping var */ - int fd; /* File descriptor */ - char device[255], /* Device filename */ - basedevice[255], /* Base device filename for ports */ - device_id[1024], /* Device ID string */ - make_model[1024], /* Make and model */ - info[1024], /* Info string */ - uri[1024]; /* Device URI */ - - - if (!access("/dev/parallel/", 0)) - strcpy(basedevice, "/dev/parallel/"); - else if (!access("/dev/printers/", 0)) - strcpy(basedevice, "/dev/printers/"); - else - strcpy(basedevice, "/dev/lp"); - - for (i = 0; i < 4; i ++) - { - /* - * Open the port, if available... - */ - - sprintf(device, "%s%d", basedevice, i); - if ((fd = open(device, O_RDWR | O_EXCL)) < 0) - fd = open(device, O_WRONLY); - - if (fd >= 0) - { - /* - * Now grab the IEEE 1284 device ID string... - */ - - snprintf(uri, sizeof(uri), "parallel:%s", device); - - if (!backendGetDeviceID(fd, device_id, sizeof(device_id), - make_model, sizeof(make_model), - NULL, uri, sizeof(uri))) - { - snprintf(info, sizeof(info), "%s LPT #%d", make_model, i + 1); - cupsBackendReport("direct", uri, make_model, info, device_id, NULL); - } - else - { - snprintf(info, sizeof(info), "LPT #%d", i + 1); - cupsBackendReport("direct", uri, NULL, info, NULL, NULL); - } - - close(fd); - } - } -#elif defined(__sgi) - int i, j, n; /* Looping vars */ - char device[255]; /* Device filename */ - inventory_t *inv; /* Hardware inventory info */ - - - /* - * IRIX maintains a hardware inventory of most devices... - */ - - setinvent(); - - while ((inv = getinvent()) != NULL) - { - if (inv->inv_class == INV_PARALLEL && - (inv->inv_type == INV_ONBOARD_PLP || - inv->inv_type == INV_EPP_ECP_PLP)) - { - /* - * Standard parallel port... - */ - - puts("direct parallel:/dev/plp \"Unknown\" \"Onboard Parallel Port\""); - } - else if (inv->inv_class == INV_PARALLEL && - inv->inv_type == INV_EPC_PLP) - { - /* - * EPC parallel port... - */ - - printf("direct parallel:/dev/plp%d \"Unknown\" \"Integral EPC parallel port, Ebus slot %d\"\n", - inv->inv_controller, inv->inv_controller); - } - } - - endinvent(); - - /* - * Central Data makes serial and parallel "servers" that can be - * connected in a number of ways. Look for ports... - */ - - for (i = 0; i < 10; i ++) - for (j = 0; j < 8; j ++) - for (n = 0; n < 32; n ++) - { - if (i == 8) /* EtherLite */ - sprintf(device, "/dev/lpn%d%c", j, funky_hex[n]); - else if (i == 9) /* PCI */ - sprintf(device, "/dev/lpp%d%c", j, funky_hex[n]); - else /* SCSI */ - sprintf(device, "/dev/lp%d%d%c", i, j, funky_hex[n]); - - if (access(device, 0) == 0) - { - if (i == 8) - printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n", - device, j, n); - else if (i == 9) - printf("direct parallel:%s \"Unknown\" \"Central Data PCI Parallel Port, ID %d, port %d\"\n", - device, j, n); - else - printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n", - device, i, j, n); - } - } -#elif defined(__sun) - int i, j, n; /* Looping vars */ - char device[255]; /* Device filename */ - - - /* - * Standard parallel ports... - */ - - for (i = 0; i < 10; i ++) - { - sprintf(device, "/dev/ecpp%d", i); - if (access(device, 0) == 0) - printf("direct parallel:%s \"Unknown\" \"Sun IEEE-1284 Parallel Port #%d\"\n", - device, i + 1); - } - - for (i = 0; i < 10; i ++) - { - sprintf(device, "/dev/bpp%d", i); - if (access(device, 0) == 0) - printf("direct parallel:%s \"Unknown\" \"Sun Standard Parallel Port #%d\"\n", - device, i + 1); - } - - for (i = 0; i < 3; i ++) - { - sprintf(device, "/dev/lp%d", i); - - if (access(device, 0) == 0) - printf("direct parallel:%s \"Unknown\" \"PC Parallel Port #%d\"\n", - device, i + 1); - } - - /* - * MAGMA parallel ports... - */ - - for (i = 0; i < 40; i ++) - { - sprintf(device, "/dev/pm%02d", i); - if (access(device, 0) == 0) - printf("direct parallel:%s \"Unknown\" \"MAGMA Parallel Board #%d Port #%d\"\n", - device, (i / 10) + 1, (i % 10) + 1); - } - - /* - * Central Data parallel ports... - */ - - for (i = 0; i < 9; i ++) - for (j = 0; j < 8; j ++) - for (n = 0; n < 32; n ++) - { - if (i == 8) /* EtherLite */ - sprintf(device, "/dev/sts/lpN%d%c", j, funky_hex[n]); - else - sprintf(device, "/dev/sts/lp%c%d%c", i + 'C', j, - funky_hex[n]); - - if (access(device, 0) == 0) - { - if (i == 8) - printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n", - device, j, n); - else - printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n", - device, i, j, n); - } - } -#elif defined(__hpux) - int i, j, n; /* Looping vars */ - char device[255]; /* Device filename */ - - - /* - * Standard parallel ports... - */ - - if (access("/dev/rlp", 0) == 0) - puts("direct parallel:/dev/rlp \"Unknown\" \"Standard Parallel Port (/dev/rlp)\""); - - for (i = 0; i < 7; i ++) - for (j = 0; j < 7; j ++) - { - sprintf(device, "/dev/c%dt%dd0_lp", i, j); - if (access(device, 0) == 0) - printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d,%d\"\n", - device, i, j); - } - - /* - * Central Data parallel ports... - */ - - for (i = 0; i < 9; i ++) - for (j = 0; j < 8; j ++) - for (n = 0; n < 32; n ++) - { - if (i == 8) /* EtherLite */ - sprintf(device, "/dev/lpN%d%c", j, funky_hex[n]); - else - sprintf(device, "/dev/lp%c%d%c", i + 'C', j, - funky_hex[n]); - - if (access(device, 0) == 0) - { - if (i == 8) - printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n", - device, j, n); - else - printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n", - device, i, j, n); - } - } -#elif defined(__osf__) - int i; /* Looping var */ - int fd; /* File descriptor */ - char device[255]; /* Device filename */ - - - for (i = 0; i < 3; i ++) - { - sprintf(device, "/dev/lp%d", i); - if ((fd = open(device, O_WRONLY)) >= 0) - { - close(fd); - printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1); - } - } -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) - int i; /* Looping var */ - int fd; /* File descriptor */ - char device[255]; /* Device filename */ - - - for (i = 0; i < 3; i ++) - { - sprintf(device, "/dev/lpt%d", i); - if ((fd = open(device, O_WRONLY)) >= 0) - { - close(fd); - printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d (interrupt-driven)\"\n", device, i + 1); - } - - sprintf(device, "/dev/lpa%d", i); - if ((fd = open(device, O_WRONLY)) >= 0) - { - close(fd); - printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d (polled)\"\n", device, i + 1); - } - } -#elif defined(_AIX) - int i; /* Looping var */ - int fd; /* File descriptor */ - char device[255]; /* Device filename */ - - - for (i = 0; i < 8; i ++) - { - sprintf(device, "/dev/lp%d", i); - if ((fd = open(device, O_WRONLY)) >= 0) - { - close(fd); - printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1); - } - } -#endif -} - - -/* - * 'side_cb()' - Handle side-channel requests... - */ - -static int /* O - 0 on success, -1 on error */ -side_cb(int print_fd, /* I - Print file */ - int device_fd, /* I - Device file */ - int snmp_fd, /* I - SNMP socket (unused) */ - http_addr_t *addr, /* I - Device address (unused) */ - int use_bc) /* I - Using back-channel? */ -{ - cups_sc_command_t command; /* Request command */ - cups_sc_status_t status; /* Request/response status */ - char data[2048]; /* Request/response data */ - int datalen; /* Request/response data size */ - - - (void)snmp_fd; - (void)addr; - - datalen = sizeof(data); - - if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0)) - return (-1); - - switch (command) - { - case CUPS_SC_CMD_DRAIN_OUTPUT : - if (backendDrainOutput(print_fd, device_fd)) - status = CUPS_SC_STATUS_IO_ERROR; - else if (tcdrain(device_fd)) - status = CUPS_SC_STATUS_IO_ERROR; - else - status = CUPS_SC_STATUS_OK; - - datalen = 0; - break; - - case CUPS_SC_CMD_GET_BIDI : - status = CUPS_SC_STATUS_OK; - data[0] = use_bc; - datalen = 1; - break; - - case CUPS_SC_CMD_GET_DEVICE_ID : - memset(data, 0, sizeof(data)); - - if (backendGetDeviceID(device_fd, data, sizeof(data) - 1, - NULL, 0, NULL, NULL, 0)) - { - status = CUPS_SC_STATUS_NOT_IMPLEMENTED; - datalen = 0; - } - else - { - status = CUPS_SC_STATUS_OK; - datalen = strlen(data); - } - break; - - default : - status = CUPS_SC_STATUS_NOT_IMPLEMENTED; - datalen = 0; - break; - } - - return (cupsSideChannelWrite(command, status, data, datalen, 1.0)); -} - - -/* - * End of "$Id: parallel.c 7810 2008-07-29 01:11:15Z mike $". - */ diff --git a/backend/serial.c b/backend/serial.c deleted file mode 100644 index def68cb85..000000000 --- a/backend/serial.c +++ /dev/null @@ -1,1327 +0,0 @@ -/* - * "$Id: serial.c 7647 2008-06-16 17:39:40Z mike $" - * - * Serial port backend for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * "LICENSE" which should have been included with this file. If this - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * main() - Send a file to the printer or server. - * list_devices() - List all serial devices. - * side_cb() - Handle side-channel requests... - */ - -/* - * Include necessary headers. - */ - -#include "backend-private.h" -#include - -#ifdef __hpux -# include -#endif /* __hpux */ - -#ifdef WIN32 -# include -#else -# include -# include -# include -# ifdef __hpux -# include -# else -# include -# endif /* __hpux */ -# ifdef HAVE_SYS_IOCTL_H -# include -# endif /* HAVE_SYS_IOCTL_H */ -#endif /* WIN32 */ - -#ifdef __sgi -# include -# ifndef INV_EPP_ECP_PLP -# define INV_EPP_ECP_PLP 6 /* From 6.3/6.4/6.5 sys/invent.h */ -# define INV_ASO_SERIAL 14 /* serial portion of SGI ASO board */ -# define INV_IOC3_DMA 16 /* DMA mode IOC3 serial */ -# define INV_IOC3_PIO 17 /* PIO mode IOC3 serial */ -# define INV_ISA_DMA 19 /* DMA mode ISA serial -- O2 */ -# endif /* !INV_EPP_ECP_PLP */ -#endif /* __sgi */ - -#ifndef CRTSCTS -# ifdef CNEW_RTSCTS -# define CRTSCTS CNEW_RTSCTS -# else -# define CRTSCTS 0 -# endif /* CNEW_RTSCTS */ -#endif /* !CRTSCTS */ - -#if defined(__APPLE__) -# include -# include -# include -# include -#endif /* __APPLE__ */ - -#if defined(__linux) && defined(TIOCGSERIAL) -# include -# include -#endif /* __linux && TIOCGSERIAL */ - - -/* - * Local functions... - */ - -static void list_devices(void); -static int side_cb(int print_fd, int device_fd, int use_bc); - - -/* - * 'main()' - Send a file to the printer or server. - * - * Usage: - * - * printer-uri job-id user title copies options [file] - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments (6 or 7) */ - char *argv[]) /* I - Command-line arguments */ -{ - char method[255], /* Method in URI */ - hostname[1024], /* Hostname */ - username[255], /* Username info (not used) */ - resource[1024], /* Resource info (device and options) */ - *options, /* Pointer to options */ - *name, /* Name of option */ - *value, /* Value of option */ - sep; /* Option separator */ - int port; /* Port number (not used) */ - int copies; /* Number of copies to print */ - int side_eof = 0, /* Saw EOF on side-channel? */ - print_fd, /* Print file */ - device_fd; /* Serial device */ - int nfds; /* Maximum file descriptor value + 1 */ - fd_set input, /* Input set for reading */ - output; /* Output set for writing */ - ssize_t print_bytes, /* Print bytes read */ - bc_bytes, /* Backchannel bytes read */ - total_bytes, /* Total bytes written */ - bytes; /* Bytes written */ - int dtrdsr; /* Do dtr/dsr flow control? */ - int print_size; /* Size of output buffer for writes */ - char print_buffer[8192], /* Print data buffer */ - *print_ptr, /* Pointer into print data buffer */ - bc_buffer[1024]; /* Back-channel data buffer */ - struct termios opts; /* Serial port options */ - struct termios origopts; /* Original port options */ -#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) - struct sigaction action; /* Actions for POSIX signals */ -#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ - - - /* - * Make sure status messages are not buffered... - */ - - setbuf(stderr, NULL); - - /* - * Ignore SIGPIPE signals... - */ - -#ifdef HAVE_SIGSET - sigset(SIGPIPE, SIG_IGN); -#elif defined(HAVE_SIGACTION) - memset(&action, 0, sizeof(action)); - action.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &action, NULL); -#else - signal(SIGPIPE, SIG_IGN); -#endif /* HAVE_SIGSET */ - - /* - * Check command-line... - */ - - if (argc == 1) - { - list_devices(); - return (CUPS_BACKEND_OK); - } - else if (argc < 6 || argc > 7) - { - _cupsLangPrintf(stderr, - _("Usage: %s job-id user title copies options [file]"), - argv[0]); - return (CUPS_BACKEND_FAILED); - } - - /* - * If we have 7 arguments, print the file named on the command-line. - * Otherwise, send stdin instead... - */ - - if (argc == 6) - { - print_fd = 0; - copies = 1; - } - else - { - /* - * Try to open the print file... - */ - - if ((print_fd = open(argv[6], O_RDONLY)) < 0) - { - _cupsLangPrintError("ERROR", _("Unable to open print file")); - return (CUPS_BACKEND_FAILED); - } - - copies = atoi(argv[4]); - } - - /* - * Extract the device name and options from the URI... - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, cupsBackendDeviceURI(argv), - method, sizeof(method), username, sizeof(username), - hostname, sizeof(hostname), &port, - resource, sizeof(resource)); - - /* - * See if there are any options... - */ - - if ((options = strchr(resource, '?')) != NULL) - { - /* - * Yup, terminate the device name string and move to the first - * character of the options... - */ - - *options++ = '\0'; - } - - /* - * Open the serial port device... - */ - - fputs("STATE: +connecting-to-device\n", stderr); - - do - { - if ((device_fd = open(resource, O_RDWR | O_NOCTTY | O_EXCL | - O_NDELAY)) == -1) - { - if (getenv("CLASS") != NULL) - { - /* - * If the CLASS environment variable is set, the job was submitted - * to a class and not to a specific queue. In this case, we want - * to abort immediately so that the job can be requeued on the next - * available printer in the class. - */ - - _cupsLangPrintFilter(stderr, "INFO", - _("Unable to contact printer, queuing on next " - "printer in class.")); - - /* - * Sleep 5 seconds to keep the job from requeuing too rapidly... - */ - - sleep(5); - - return (CUPS_BACKEND_FAILED); - } - - if (errno == EBUSY) - { - _cupsLangPrintFilter(stderr, "INFO", - _("Printer busy; will retry in 30 seconds.")); - sleep(30); - } - else - { - _cupsLangPrintError("ERROR", _("Unable to open device file")); - return (CUPS_BACKEND_FAILED); - } - } - } - while (device_fd < 0); - - fputs("STATE: -connecting-to-device\n", stderr); - - /* - * Set any options provided... - */ - - tcgetattr(device_fd, &origopts); - tcgetattr(device_fd, &opts); - - opts.c_lflag &= ~(ICANON | ECHO | ISIG); - /* Raw mode */ - opts.c_oflag &= ~OPOST; /* Don't post-process */ - - print_size = 96; /* 9600 baud / 10 bits/char / 10Hz */ - dtrdsr = 0; /* No dtr/dsr flow control */ - - if (options) - { - while (*options) - { - /* - * Get the name... - */ - - name = options; - - while (*options && *options != '=' && *options != '+' && *options != '&') - options ++; - - if ((sep = *options) != '\0') - *options++ = '\0'; - - if (sep == '=') - { - /* - * Get the value... - */ - - value = options; - - while (*options && *options != '+' && *options != '&') - options ++; - - if (*options) - *options++ = '\0'; - } - else - value = (char *)""; - - /* - * Process the option... - */ - - if (!_cups_strcasecmp(name, "baud")) - { - /* - * Set the baud rate... - */ - - print_size = atoi(value) / 100; - -#if B19200 == 19200 - cfsetispeed(&opts, atoi(value)); - cfsetospeed(&opts, atoi(value)); -#else - switch (atoi(value)) - { - case 1200 : - cfsetispeed(&opts, B1200); - cfsetospeed(&opts, B1200); - break; - case 2400 : - cfsetispeed(&opts, B2400); - cfsetospeed(&opts, B2400); - break; - case 4800 : - cfsetispeed(&opts, B4800); - cfsetospeed(&opts, B4800); - break; - case 9600 : - cfsetispeed(&opts, B9600); - cfsetospeed(&opts, B9600); - break; - case 19200 : - cfsetispeed(&opts, B19200); - cfsetospeed(&opts, B19200); - break; - case 38400 : - cfsetispeed(&opts, B38400); - cfsetospeed(&opts, B38400); - break; -# ifdef B57600 - case 57600 : - cfsetispeed(&opts, B57600); - cfsetospeed(&opts, B57600); - break; -# endif /* B57600 */ -# ifdef B115200 - case 115200 : - cfsetispeed(&opts, B115200); - cfsetospeed(&opts, B115200); - break; -# endif /* B115200 */ -# ifdef B230400 - case 230400 : - cfsetispeed(&opts, B230400); - cfsetospeed(&opts, B230400); - break; -# endif /* B230400 */ - default : - _cupsLangPrintFilter(stderr, "WARNING", - _("Unsupported baud rate: %s"), value); - break; - } -#endif /* B19200 == 19200 */ - } - else if (!_cups_strcasecmp(name, "bits")) - { - /* - * Set number of data bits... - */ - - switch (atoi(value)) - { - case 7 : - opts.c_cflag &= ~CSIZE; - opts.c_cflag |= CS7; - opts.c_cflag |= PARENB; - opts.c_cflag &= ~PARODD; - break; - case 8 : - opts.c_cflag &= ~CSIZE; - opts.c_cflag |= CS8; - opts.c_cflag &= ~PARENB; - break; - } - } - else if (!_cups_strcasecmp(name, "parity")) - { - /* - * Set parity checking... - */ - - if (!_cups_strcasecmp(value, "even")) - { - opts.c_cflag |= PARENB; - opts.c_cflag &= ~PARODD; - } - else if (!_cups_strcasecmp(value, "odd")) - { - opts.c_cflag |= PARENB; - opts.c_cflag |= PARODD; - } - else if (!_cups_strcasecmp(value, "none")) - opts.c_cflag &= ~PARENB; - else if (!_cups_strcasecmp(value, "space")) - { - /* - * Note: we only support space parity with 7 bits per character... - */ - - opts.c_cflag &= ~CSIZE; - opts.c_cflag |= CS8; - opts.c_cflag &= ~PARENB; - } - else if (!_cups_strcasecmp(value, "mark")) - { - /* - * Note: we only support mark parity with 7 bits per character - * and 1 stop bit... - */ - - opts.c_cflag &= ~CSIZE; - opts.c_cflag |= CS7; - opts.c_cflag &= ~PARENB; - opts.c_cflag |= CSTOPB; - } - } - else if (!_cups_strcasecmp(name, "flow")) - { - /* - * Set flow control... - */ - - if (!_cups_strcasecmp(value, "none")) - { - opts.c_iflag &= ~(IXON | IXOFF); - opts.c_cflag &= ~CRTSCTS; - } - else if (!_cups_strcasecmp(value, "soft")) - { - opts.c_iflag |= IXON | IXOFF; - opts.c_cflag &= ~CRTSCTS; - } - else if (!_cups_strcasecmp(value, "hard") || - !_cups_strcasecmp(value, "rtscts")) - { - opts.c_iflag &= ~(IXON | IXOFF); - opts.c_cflag |= CRTSCTS; - } - else if (!_cups_strcasecmp(value, "dtrdsr")) - { - opts.c_iflag &= ~(IXON | IXOFF); - opts.c_cflag &= ~CRTSCTS; - - dtrdsr = 1; - } - } - else if (!_cups_strcasecmp(name, "stop")) - { - switch (atoi(value)) - { - case 1 : - opts.c_cflag &= ~CSTOPB; - break; - - case 2 : - opts.c_cflag |= CSTOPB; - break; - } - } - } - } - - tcsetattr(device_fd, TCSANOW, &opts); - fcntl(device_fd, F_SETFL, 0); - - /* - * Now that we are "connected" to the port, ignore SIGTERM so that we - * can finish out any page data the driver sends (e.g. to eject the - * current page... Only ignore SIGTERM if we are printing data from - * stdin (otherwise you can't cancel raw jobs...) - */ - - if (!print_fd) - { -#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ - sigset(SIGTERM, SIG_IGN); -#elif defined(HAVE_SIGACTION) - memset(&action, 0, sizeof(action)); - - sigemptyset(&action.sa_mask); - action.sa_handler = SIG_IGN; - sigaction(SIGTERM, &action, NULL); -#else - signal(SIGTERM, SIG_IGN); -#endif /* HAVE_SIGSET */ - } - - /* - * Figure out the maximum file descriptor value to use with select()... - */ - - nfds = (print_fd > device_fd ? print_fd : device_fd) + 1; - - /* - * Finally, send the print file. Ordinarily we would just use the - * backendRunLoop() function, however since we need to use smaller - * writes and may need to do DSR/DTR flow control, we duplicate much - * of the code here instead... - */ - - if (print_size > sizeof(print_buffer)) - print_size = sizeof(print_buffer); - - total_bytes = 0; - - while (copies > 0) - { - copies --; - - if (print_fd != 0) - { - fputs("PAGE: 1 1\n", stderr); - lseek(print_fd, 0, SEEK_SET); - } - - /* - * Now loop until we are out of data from print_fd... - */ - - for (print_bytes = 0, print_ptr = print_buffer;;) - { - /* - * Use select() to determine whether we have data to copy around... - */ - - FD_ZERO(&input); - if (!print_bytes) - FD_SET(print_fd, &input); - FD_SET(device_fd, &input); - if (!print_bytes && !side_eof) - FD_SET(CUPS_SC_FD, &input); - - FD_ZERO(&output); - if (print_bytes) - FD_SET(device_fd, &output); - - if (select(nfds, &input, &output, NULL, NULL) < 0) - continue; /* Ignore errors here */ - - /* - * Check if we have a side-channel request ready... - */ - - if (FD_ISSET(CUPS_SC_FD, &input)) - { - /* - * Do the side-channel request, then start back over in the select - * loop since it may have read from print_fd... - */ - - if (side_cb(print_fd, device_fd, 1)) - side_eof = 1; - continue; - } - - /* - * Check if we have back-channel data ready... - */ - - if (FD_ISSET(device_fd, &input)) - { - if ((bc_bytes = read(device_fd, bc_buffer, sizeof(bc_buffer))) > 0) - { - fprintf(stderr, - "DEBUG: Received " CUPS_LLFMT " bytes of back-channel data\n", - CUPS_LLCAST bc_bytes); - cupsBackChannelWrite(bc_buffer, bc_bytes, 1.0); - } - } - - /* - * Check if we have print data ready... - */ - - if (FD_ISSET(print_fd, &input)) - { - if ((print_bytes = read(print_fd, print_buffer, print_size)) < 0) - { - /* - * Read error - bail if we don't see EAGAIN or EINTR... - */ - - if (errno != EAGAIN || errno != EINTR) - { - perror("DEBUG: Unable to read print data"); - - tcsetattr(device_fd, TCSADRAIN, &origopts); - - close(device_fd); - - if (print_fd != 0) - close(print_fd); - - return (CUPS_BACKEND_FAILED); - } - - print_bytes = 0; - } - else if (print_bytes == 0) - { - /* - * End of file, break out of the loop... - */ - - break; - } - - print_ptr = print_buffer; - } - - /* - * Check if the device is ready to receive data and we have data to - * send... - */ - - if (print_bytes && FD_ISSET(device_fd, &output)) - { - if (dtrdsr) - { - /* - * Check the port and sleep until DSR is set... - */ - - int status; - - - if (!ioctl(device_fd, TIOCMGET, &status)) - if (!(status & TIOCM_DSR)) - { - /* - * Wait for DSR to go high... - */ - - fputs("DEBUG: DSR is low; waiting for device...\n", stderr); - - do - { - /* - * Poll every 100ms... - */ - - usleep(100000); - - if (ioctl(device_fd, TIOCMGET, &status)) - break; - } - while (!(status & TIOCM_DSR)); - - fputs("DEBUG: DSR is high; writing to device...\n", stderr); - } - } - - if ((bytes = write(device_fd, print_ptr, print_bytes)) < 0) - { - /* - * Write error - bail if we don't see an error we can retry... - */ - - if (errno != EAGAIN && errno != EINTR && errno != ENOTTY) - { - perror("DEBUG: Unable to write print data"); - - tcsetattr(device_fd, TCSADRAIN, &origopts); - - close(device_fd); - - if (print_fd != 0) - close(print_fd); - - return (CUPS_BACKEND_FAILED); - } - } - else - { - fprintf(stderr, "DEBUG: Wrote %d bytes...\n", (int)bytes); - - print_bytes -= bytes; - print_ptr += bytes; - total_bytes += bytes; - } - } - } - } - - /* - * Close the serial port and input file and return... - */ - - tcsetattr(device_fd, TCSADRAIN, &origopts); - - close(device_fd); - - if (print_fd != 0) - close(print_fd); - - return (CUPS_BACKEND_OK); -} - - -/* - * 'list_devices()' - List all serial devices. - */ - -static void -list_devices(void) -{ -#if defined(__hpux) || defined(__sgi) || defined(__sun) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) - static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz"; - /* Funky hex numbering used for some * - * devices */ -#endif /* __hpux || __sgi || __sun || __FreeBSD__ || __OpenBSD__ || __FreeBSD_kernel__ */ - - -#ifdef __linux - int i, j; /* Looping vars */ - int fd; /* File descriptor */ - char device[255]; /* Device filename */ - char info[255]; /* Device info/description */ -# ifdef TIOCGSERIAL - struct serial_struct serinfo; /* serial port info */ -# endif /* TIOCGSERIAL */ - - - for (i = 0; i < 100; i ++) - { - sprintf(device, "/dev/ttyS%d", i); - - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { -# ifdef TIOCGSERIAL - /* - * See if this port exists... - */ - - serinfo.reserved_char[0] = 0; - - if (!ioctl(fd, TIOCGSERIAL, &serinfo)) - { - if (serinfo.type == PORT_UNKNOWN) - { - /* - * Nope... - */ - - close(fd); - continue; - } - } -# endif /* TIOCGSERIAL */ - - close(fd); - - snprintf(info, sizeof(info), - _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1); - -# if defined(_ARCH_PPC) || defined(powerpc) || defined(__powerpc) - printf("serial serial:%s?baud=230400 \"Unknown\" \"%s\"\n", device, info); -# else - printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info); -# endif /* _ARCH_PPC || powerpc || __powerpc */ - } - } - - for (i = 0; i < 16; i ++) - { - snprintf(info, sizeof(info), - _cupsLangString(cupsLangDefault(), _("USB Serial Port #%d")), - i + 1); - - sprintf(device, "/dev/usb/ttyUSB%d", i); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=230400 \"Unknown\" \"%s\"\n", device, info); - } - - sprintf(device, "/dev/ttyUSB%d", i); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=230400 \"Unknown\" \"%s\"\n", device, info); - } - } - - for (i = 0; i < 64; i ++) - { - for (j = 0; j < 8; j ++) - { - sprintf(device, "/dev/ttyQ%02de%d", i, j); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - - printf("serial serial:%s?baud=115200 \"Unknown\" " - "\"Equinox ESP %d Port #%d\"\n", device, i, j + 1); - } - } - } -#elif defined(__sgi) - int i, j, n; /* Looping vars */ - char device[255]; /* Device filename */ - inventory_t *inv; /* Hardware inventory info */ - - - /* - * IRIX maintains a hardware inventory of most devices... - */ - - setinvent(); - - while ((inv = getinvent()) != NULL) - { - if (inv->inv_class == INV_SERIAL) - { - /* - * Some sort of serial port... - */ - - if (inv->inv_type == INV_CDSIO || inv->inv_type == INV_CDSIO_E) - { - /* - * CDSIO port... - */ - - for (n = 0; n < 6; n ++) - printf("serial serial:/dev/ttyd%d?baud=38400 \"Unknown\" \"CDSIO Board %d Serial Port #%d\"\n", - n + 5 + 8 * inv->inv_controller, inv->inv_controller, n + 1); - } - else if (inv->inv_type == INV_EPC_SERIAL) - { - /* - * Everest serial port... - */ - - if (inv->inv_unit == 0) - i = 1; - else - i = 41 + 4 * (int)inv->inv_controller; - - for (n = 0; n < (int)inv->inv_state; n ++) - printf("serial serial:/dev/ttyd%d?baud=38400 \"Unknown\" \"EPC Serial Port %d, Ebus slot %d\"\n", - n + i, n + 1, (int)inv->inv_controller); - } - else if (inv->inv_state > 1) - { - /* - * Standard serial port under IRIX 6.4 and earlier... - */ - - for (n = 0; n < (int)inv->inv_state; n ++) - printf("serial serial:/dev/ttyd%d?baud=38400 \"Unknown\" \"Onboard Serial Port %d\"\n", - n + (int)inv->inv_unit + 1, n + (int)inv->inv_unit + 1); - } - else - { - /* - * Standard serial port under IRIX 6.5 and beyond... - */ - - printf("serial serial:/dev/ttyd%d?baud=115200 \"Unknown\" \"Onboard Serial Port %d\"\n", - (int)inv->inv_controller, (int)inv->inv_controller); - } - } - } - - endinvent(); - - /* - * Central Data makes serial and parallel "servers" that can be - * connected in a number of ways. Look for ports... - */ - - for (i = 0; i < 10; i ++) - for (j = 0; j < 8; j ++) - for (n = 0; n < 32; n ++) - { - if (i == 8) /* EtherLite */ - sprintf(device, "/dev/ttydn%d%c", j, funky_hex[n]); - else if (i == 9) /* PCI */ - sprintf(device, "/dev/ttydp%d%c", j, funky_hex[n]); - else /* SCSI */ - sprintf(device, "/dev/ttyd%d%d%c", i, j, funky_hex[n]); - - if (access(device, 0) == 0) - { - if (i == 8) - printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n", - device, j, n); - else if (i == 9) - printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data PCI Serial Port, ID %d, port %d\"\n", - device, j, n); - else - printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n", - device, i, j, n); - } - } -#elif defined(__sun) - int i, j, n; /* Looping vars */ - char device[255]; /* Device filename */ - char info[255]; /* Device info/description */ - - - /* - * Standard serial ports... - */ - - for (i = 0; i < 26; i ++) - { - sprintf(device, "/dev/cua/%c", 'a' + i); - if (!access(device, 0)) - { - snprintf(info, sizeof(info), - _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1); - -# ifdef B115200 - printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info); -# else - printf("serial serial:%s?baud=38400 \"Unknown\" \"%s\"\n", device, info); -# endif /* B115200 */ - } - } - - /* - * MAGMA serial ports... - */ - - for (i = 0; i < 40; i ++) - { - sprintf(device, "/dev/term/%02d", i); - if (access(device, 0) == 0) - printf("serial serial:%s?baud=38400 \"Unknown\" \"MAGMA Serial Board #%d Port #%d\"\n", - device, (i / 10) + 1, (i % 10) + 1); - } - - /* - * Central Data serial ports... - */ - - for (i = 0; i < 9; i ++) - for (j = 0; j < 8; j ++) - for (n = 0; n < 32; n ++) - { - if (i == 8) /* EtherLite */ - sprintf(device, "/dev/sts/ttyN%d%c", j, funky_hex[n]); - else - sprintf(device, "/dev/sts/tty%c%d%c", i + 'C', j, - funky_hex[n]); - - if (access(device, 0) == 0) - { - if (i == 8) - printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n", - device, j, n); - else - printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n", - device, i, j, n); - } - } -#elif defined(__hpux) - int i, j, n; /* Looping vars */ - char device[255]; /* Device filename */ - - - /* - * Standard serial ports... - */ - - for (i = 0; i < 10; i ++) - { - sprintf(device, "/dev/tty%dp0", i); - if (access(device, 0) == 0) - printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n", - device, i + 1); - } - - /* - * Central Data serial ports... - */ - - for (i = 0; i < 9; i ++) - for (j = 0; j < 8; j ++) - for (n = 0; n < 32; n ++) - { - if (i == 8) /* EtherLite */ - sprintf(device, "/dev/ttyN%d%c", j, funky_hex[n]); - else - sprintf(device, "/dev/tty%c%d%c", i + 'C', j, - funky_hex[n]); - - if (access(device, 0) == 0) - { - if (i == 8) - printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n", - device, j, n); - else - printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n", - device, i, j, n); - } - } -#elif defined(__osf__) - int i; /* Looping var */ - char device[255]; /* Device filename */ - - - /* - * Standard serial ports... - */ - - for (i = 0; i < 100; i ++) - { - sprintf(device, "/dev/tty%02d", i); - if (access(device, 0) == 0) - printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n", - device, i + 1); - } -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) - int i, j; /* Looping vars */ - int fd; /* File descriptor */ - char device[255]; /* Device filename */ - char info[255]; /* Device info/description */ - - - /* - * SIO ports... - */ - - for (i = 0; i < 32; i ++) - { - sprintf(device, "/dev/ttyd%c", funky_hex[i]); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - - snprintf(info, sizeof(info), - _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1); - - printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info); - } - } - - /* - * Cyclades ports... - */ - - for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */ - for (j = 0; j < 32; j ++) - { - sprintf(device, "/dev/ttyc%d%c", i, funky_hex[j]); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=115200 \"Unknown\" \"Cyclades #%d Serial Port #%d\"\n", - device, i, j + 1); - } - - sprintf(device, "/dev/ttyC%d%c", i, funky_hex[j]); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=115200 \"Unknown\" \"Cyclades #%d Serial Port #%d\"\n", - device, i, j + 1); - } - } - - /* - * Digiboard ports... - */ - - for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */ - for (j = 0; j < 32; j ++) - { - sprintf(device, "/dev/ttyD%d%c", i, funky_hex[j]); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=115200 \"Unknown\" \"Digiboard #%d Serial Port #%d\"\n", - device, i, j + 1); - } - } - - /* - * Stallion ports... - */ - - for (i = 0; i < 32; i ++) - { - sprintf(device, "/dev/ttyE%c", funky_hex[i]); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=115200 \"Unknown\" \"Stallion Serial Port #%d\"\n", - device, i + 1); - } - } - - /* - * SX ports... - */ - - for (i = 0; i < 128; i ++) - { - sprintf(device, "/dev/ttyA%d", i + 1); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=115200 \"Unknown\" \"SX Serial Port #%d\"\n", - device, i + 1); - } - } -#elif defined(__NetBSD__) - int i, j; /* Looping vars */ - int fd; /* File descriptor */ - char device[255]; /* Device filename */ - char info[255]; /* Device info/description */ - - - /* - * Standard serial ports... - */ - - for (i = 0; i < 4; i ++) - { - sprintf(device, "/dev/tty%02d", i); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - - snprintf(info, sizeof(info), - _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1); - - printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info); - } - } - - /* - * Cyclades-Z ports... - */ - - for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */ - for (j = 0; j < 64; j ++) - { - sprintf(device, "/dev/ttyCZ%02d%02d", i, j); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=115200 \"Unknown\" \"Cyclades #%d Serial Prt #%d\"\n", - device, i, j + 1); - } - } -#elif defined(__APPLE__) - /* - * Standard serial ports on MacOS X... - */ - - kern_return_t kernResult; - mach_port_t masterPort; - io_iterator_t serialPortIterator; - CFMutableDictionaryRef classesToMatch; - io_object_t serialService; - - - kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort); - if (KERN_SUCCESS != kernResult) - return; - - /* - * Serial devices are instances of class IOSerialBSDClient. - */ - - classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); - if (classesToMatch != NULL) - { - CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), - CFSTR(kIOSerialBSDRS232Type)); - - kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch, - &serialPortIterator); - if (kernResult == KERN_SUCCESS) - { - while ((serialService = IOIteratorNext(serialPortIterator))) - { - CFTypeRef serialNameAsCFString; - CFTypeRef bsdPathAsCFString; - CFTypeRef hiddenVal; - char serialName[128]; - char bsdPath[1024]; - Boolean result; - - - /* Check if hidden... */ - hiddenVal = IORegistryEntrySearchCFProperty(serialService, - kIOServicePlane, - CFSTR("HiddenPort"), - kCFAllocatorDefault, - kIORegistryIterateRecursively | - kIORegistryIterateParents); - if (hiddenVal) - CFRelease(hiddenVal); /* This interface should not be used */ - else - { - serialNameAsCFString = - IORegistryEntryCreateCFProperty(serialService, - CFSTR(kIOTTYDeviceKey), - kCFAllocatorDefault, 0); - if (serialNameAsCFString) - { - result = CFStringGetCString(serialNameAsCFString, serialName, - sizeof(serialName), - kCFStringEncodingASCII); - CFRelease(serialNameAsCFString); - - if (result) - { - bsdPathAsCFString = - IORegistryEntryCreateCFProperty(serialService, - CFSTR(kIOCalloutDeviceKey), - kCFAllocatorDefault, 0); - if (bsdPathAsCFString) - { - result = CFStringGetCString(bsdPathAsCFString, bsdPath, - sizeof(bsdPath), - kCFStringEncodingASCII); - CFRelease(bsdPathAsCFString); - - if (result) - printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", - bsdPath, serialName); - } - } - } - } - - IOObjectRelease(serialService); - } - - /* - * Release the iterator. - */ - - IOObjectRelease(serialPortIterator); - } - } -#endif -} - - -/* - * 'side_cb()' - Handle side-channel requests... - */ - -static int /* O - 0 on success, -1 on error */ -side_cb(int print_fd, /* I - Print file */ - int device_fd, /* I - Device file */ - int use_bc) /* I - Using back-channel? */ -{ - cups_sc_command_t command; /* Request command */ - cups_sc_status_t status; /* Request/response status */ - char data[2048]; /* Request/response data */ - int datalen; /* Request/response data size */ - - - datalen = sizeof(data); - - if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0)) - return (-1); - - switch (command) - { - case CUPS_SC_CMD_DRAIN_OUTPUT : - if (backendDrainOutput(print_fd, device_fd)) - status = CUPS_SC_STATUS_IO_ERROR; - else if (tcdrain(device_fd)) - status = CUPS_SC_STATUS_IO_ERROR; - else - status = CUPS_SC_STATUS_OK; - - datalen = 0; - break; - - case CUPS_SC_CMD_GET_BIDI : - status = CUPS_SC_STATUS_OK; - data[0] = use_bc; - datalen = 1; - break; - - default : - status = CUPS_SC_STATUS_NOT_IMPLEMENTED; - datalen = 0; - break; - } - - return (cupsSideChannelWrite(command, status, data, datalen, 1.0)); -} - - -/* - * End of "$Id: serial.c 7647 2008-06-16 17:39:40Z mike $". - */ diff --git a/backend/snmp-supplies.c b/backend/snmp-supplies.c index 1bd8b7fa5..92febb602 100644 --- a/backend/snmp-supplies.c +++ b/backend/snmp-supplies.c @@ -229,12 +229,12 @@ backendSNMPSupplies( for (i = 0, ptr = value; i < num_supplies; i ++, ptr += strlen(ptr)) { - if (supplies[i].max_capacity > 0) + if (supplies[i].max_capacity > 0 && supplies[i].level >= 0) percent = 100 * supplies[i].level / supplies[i].max_capacity; else percent = 50; - if (percent <= 10) + if (percent <= 5) { switch (supplies[i].type) { @@ -279,7 +279,7 @@ backendSNMPSupplies( if (i) *ptr++ = ','; - if (supplies[i].max_capacity > 0) + if (supplies[i].max_capacity > 0 && supplies[i].level >= 0) sprintf(ptr, "%d", percent); else strcpy(ptr, "-1"); diff --git a/backend/usb-darwin.c b/backend/usb-darwin.c index 2576ac64c..44a14ba0b 100644 --- a/backend/usb-darwin.c +++ b/backend/usb-darwin.c @@ -761,24 +761,8 @@ print_device(const char *uri, /* I - Device URI */ fprintf(stderr, "DEBUG: Sent %lld bytes...\n", (off_t)total_bytes); - if (!print_fd) - { - /* - * Re-enable the SIGTERM handler so pthread_kill() will work... - */ - - struct sigaction action; /* POSIX signal action */ - - memset(&action, 0, sizeof(action)); - - sigemptyset(&action.sa_mask); - sigaddset(&action.sa_mask, SIGTERM); - action.sa_handler = sigterm_handler; - sigaction(SIGTERM, &action, NULL); - } - /* - * Wait for the side channel thread to exit... + * Signal the side channel thread to exit... */ if (have_sidechannel) @@ -805,44 +789,23 @@ print_device(const char *uri, /* I - Device URI */ &cond_timeout) != 0) break; } - - if (!g.sidechannel_thread_done) - { - /* - * Force the side-channel thread to exit... - */ - - fputs("DEBUG: Force the side-channel thread to exit...\n", stderr); - pthread_kill(sidechannel_thread_id, SIGTERM); - } } pthread_mutex_unlock(&g.sidechannel_thread_mutex); - - pthread_join(sidechannel_thread_id, NULL); - - pthread_cond_destroy(&g.sidechannel_thread_cond); - pthread_mutex_destroy(&g.sidechannel_thread_mutex); } - pthread_cond_destroy(&g.readwrite_lock_cond); - pthread_mutex_destroy(&g.readwrite_lock_mutex); - /* - * Signal the read thread to stop... + * Signal the read thread to exit then wait 7 seconds for it to complete... */ g.read_thread_stop = 1; - /* - * Give the read thread WAIT_EOF_DELAY seconds to complete all the data. If - * we are not signaled in that time then force the thread to exit. - */ - pthread_mutex_lock(&g.read_thread_mutex); if (!g.read_thread_done) { + fputs("DEBUG: Waiting for read thread to exit...\n", stderr); + gettimeofday(&tv, NULL); cond_timeout.tv_sec = tv.tv_sec + WAIT_EOF_DELAY; cond_timeout.tv_nsec = tv.tv_usec * 1000; @@ -854,25 +817,34 @@ print_device(const char *uri, /* I - Device URI */ break; } + /* + * If it didn't exit abort the pending read and wait an additional second... + */ + if (!g.read_thread_done) { - /* - * Force the read thread to exit... - */ + fputs("DEBUG: Read thread still active, aborting the pending read...\n", + stderr); g.wait_eof = 0; - fputs("DEBUG: Force the read thread to exit...\n", stderr); - pthread_kill(read_thread_id, SIGTERM); + + (*g.classdriver)->Abort(g.classdriver); + + gettimeofday(&tv, NULL); + cond_timeout.tv_sec = tv.tv_sec + 1; + cond_timeout.tv_nsec = tv.tv_usec * 1000; + + while (!g.read_thread_done) + { + if (pthread_cond_timedwait(&g.read_thread_cond, &g.read_thread_mutex, + &cond_timeout) != 0) + break; + } } } pthread_mutex_unlock(&g.read_thread_mutex); - pthread_join(read_thread_id, NULL); /* wait for the read thread to return */ - - pthread_cond_destroy(&g.read_thread_cond); - pthread_mutex_destroy(&g.read_thread_mutex); - /* * Close the connection and input file and general clean up... */ diff --git a/conf/mime.convs.in b/conf/mime.convs.in index 83e7301ec..533fd955a 100644 --- a/conf/mime.convs.in +++ b/conf/mime.convs.in @@ -38,51 +38,13 @@ # PostScript filters # -@DEFAULT_PDFTOPS@application/pdf application/vnd.cups-postscript 66 pdftops application/postscript application/vnd.cups-postscript 66 pstops -@DEFAULT_TEXTTOPS@application/x-cshell application/postscript 33 texttops -@DEFAULT_TEXTTOPS@application/x-csource application/postscript 33 texttops -@DEFAULT_TEXTTOPS@application/x-perl application/postscript 33 texttops -@DEFAULT_TEXTTOPS@application/x-shell application/postscript 33 texttops -@DEFAULT_TEXTTOPS@text/plain application/postscript 33 texttops -@DEFAULT_TEXTTOPS@text/css application/postscript 33 texttops -@DEFAULT_TEXTTOPS@text/html application/postscript 33 texttops -@DEFAULT_IMAGEFILTERS@image/gif application/vnd.cups-postscript 66 imagetops -@DEFAULT_IMAGEFILTERS@image/png application/vnd.cups-postscript 66 imagetops -@DEFAULT_IMAGEFILTERS@image/jpeg application/vnd.cups-postscript 66 imagetops -@DEFAULT_IMAGEFILTERS@image/tiff application/vnd.cups-postscript 66 imagetops -@DEFAULT_IMAGEFILTERS@image/x-bitmap application/vnd.cups-postscript 66 imagetops -@DEFAULT_IMAGEFILTERS@image/x-photocd application/vnd.cups-postscript 66 imagetops -@DEFAULT_IMAGEFILTERS@image/x-portable-anymap application/vnd.cups-postscript 66 imagetops -@DEFAULT_IMAGEFILTERS@image/x-portable-bitmap application/vnd.cups-postscript 66 imagetops -@DEFAULT_IMAGEFILTERS@image/x-portable-graymap application/vnd.cups-postscript 66 imagetops -@DEFAULT_IMAGEFILTERS@image/x-portable-pixmap application/vnd.cups-postscript 66 imagetops -@DEFAULT_IMAGEFILTERS@image/x-sgi-rgb application/vnd.cups-postscript 66 imagetops -@DEFAULT_IMAGEFILTERS@image/x-xbitmap application/vnd.cups-postscript 66 imagetops -@DEFAULT_IMAGEFILTERS@image/x-xpixmap application/vnd.cups-postscript 66 imagetops -@DEFAULT_IMAGEFILTERS@image/x-sun-raster application/vnd.cups-postscript 66 imagetops -@DEFAULT_BANNERTOPS@application/vnd.cups-banner application/postscript 33 bannertops ######################################################################## # # Raster filters... # -@DEFAULT_IMAGEFILTERS@image/gif application/vnd.cups-raster 100 imagetoraster -@DEFAULT_IMAGEFILTERS@image/png application/vnd.cups-raster 100 imagetoraster -@DEFAULT_IMAGEFILTERS@image/jpeg application/vnd.cups-raster 100 imagetoraster -@DEFAULT_IMAGEFILTERS@image/tiff application/vnd.cups-raster 100 imagetoraster -@DEFAULT_IMAGEFILTERS@image/x-bitmap application/vnd.cups-raster 100 imagetoraster -@DEFAULT_IMAGEFILTERS@image/x-photocd application/vnd.cups-raster 100 imagetoraster -@DEFAULT_IMAGEFILTERS@image/x-portable-anymap application/vnd.cups-raster 100 imagetoraster -@DEFAULT_IMAGEFILTERS@image/x-portable-bitmap application/vnd.cups-raster 100 imagetoraster -@DEFAULT_IMAGEFILTERS@image/x-portable-graymap application/vnd.cups-raster 100 imagetoraster -@DEFAULT_IMAGEFILTERS@image/x-portable-pixmap application/vnd.cups-raster 100 imagetoraster -@DEFAULT_IMAGEFILTERS@image/x-sgi-rgb application/vnd.cups-raster 100 imagetoraster -@DEFAULT_IMAGEFILTERS@image/x-xbitmap application/vnd.cups-raster 100 imagetoraster -@DEFAULT_IMAGEFILTERS@image/x-xpixmap application/vnd.cups-raster 100 imagetoraster -@DEFAULT_IMAGEFILTERS@image/x-sun-raster application/vnd.cups-raster 100 imagetoraster - # PWG Raster filter for IPP Everywhere... application/vnd.cups-raster image/pwg-raster 100 rastertopwg diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4 index 7e6d84b30..245d6f6e6 100644 --- a/config-scripts/cups-common.m4 +++ b/config-scripts/cups-common.m4 @@ -20,11 +20,11 @@ dnl Set the name of the config header file... AC_CONFIG_HEADER(config.h) dnl Version number information... -CUPS_VERSION="1.5.1" +CUPS_VERSION="1.6svn" CUPS_REVISION="" -#if test -z "$CUPS_REVISION" -a -d .svn; then -# CUPS_REVISION="-r`svnversion . | awk -F: '{print $NF}' | sed -e '1,$s/[[a-zA-Z]]*//g'`" -#fi +if test -z "$CUPS_REVISION" -a -d .svn; then + CUPS_REVISION="-r`svnversion . | awk -F: '{print $NF}' | sed -e '1,$s/[[a-zA-Z]]*//g'`" +fi CUPS_BUILD="cups-$CUPS_VERSION" AC_ARG_WITH(cups_build, [ --with-cups-build set "cups-config --build" string ], @@ -123,6 +123,7 @@ AC_SUBST(LIBPAPER) dnl Checks for header files. AC_HEADER_STDC +AC_CHECK_HEADER(stdlib.h,AC_DEFINE(HAVE_STDLIB_H)) AC_CHECK_HEADER(crypt.h,AC_DEFINE(HAVE_CRYPT_H)) AC_CHECK_HEADER(langinfo.h,AC_DEFINE(HAVE_LANGINFO_H)) AC_CHECK_HEADER(malloc.h,AC_DEFINE(HAVE_MALLOC_H)) @@ -241,6 +242,15 @@ if test x$enable_tcp_wrappers = xyes; then LIBWRAP="-lwrap")]) fi +dnl ZLIB +LIBZ="" +AC_CHECK_HEADER(zlib.h, + AC_CHECK_LIB(z, gzgets, + AC_DEFINE(HAVE_LIBZ) + LIBZ="-lz" + LIBS="$LIBS -lz")) +AC_SUBST(LIBZ) + dnl Flags for "ar" command... case $uname in Darwin* | *BSD*) @@ -310,11 +320,9 @@ dnl Extra platform-specific libraries... CUPS_DEFAULT_PRINTOPERATOR_AUTH="@SYSTEM" CUPS_SYSTEM_AUTHKEY="" INSTALLXPC="" -LEGACY_BACKENDS="parallel" case $uname in Darwin*) - LEGACY_BACKENDS="" BACKLIBS="$BACKLIBS -framework IOKit" SERVERLIBS="$SERVERLIBS -framework IOKit -weak_framework ApplicationServices" LIBS="-framework SystemConfiguration -framework CoreFoundation -framework Security $LIBS" @@ -394,7 +402,6 @@ AC_SUBST(CUPS_DEFAULT_PRINTOPERATOR_AUTH) AC_DEFINE_UNQUOTED(CUPS_DEFAULT_PRINTOPERATOR_AUTH, "$CUPS_DEFAULT_PRINTOPERATOR_AUTH") AC_SUBST(CUPS_SYSTEM_AUTHKEY) AC_SUBST(INSTALLXPC) -AC_SUBST(LEGACY_BACKENDS) dnl Check for build components COMPONENTS="all" @@ -406,7 +413,7 @@ AC_ARG_WITH(components, [ --with-components set components to build: case "$COMPONENTS" in all) - BUILDDIRS="filter backend berkeley cgi-bin driver monitor notifier ppdc scheduler systemv conf data desktop locale man doc examples templates" + BUILDDIRS="filter backend berkeley cgi-bin monitor notifier ppdc scheduler systemv conf data desktop locale man doc examples templates" ;; core) diff --git a/config-scripts/cups-defaults.m4 b/config-scripts/cups-defaults.m4 index a568edb21..eebbb29bb 100644 --- a/config-scripts/cups-defaults.m4 +++ b/config-scripts/cups-defaults.m4 @@ -434,52 +434,6 @@ AC_ARG_WITH(ipp-port, [ --with-ipp-port set port number for IPP, defaul AC_SUBST(DEFAULT_IPP_PORT) AC_DEFINE_UNQUOTED(CUPS_DEFAULT_IPP_PORT,$DEFAULT_IPP_PORT) -dnl Filters -AC_ARG_ENABLE(bannertops, [ --enable-bannertops always build the banner filter ]) -AC_ARG_ENABLE(texttops, [ --enable-texttops always build the text filter ]) - -if test "x$enable_bannertops" = xno; then - BANNERTOPS="" - DEFAULT_BANNERTOPS="#" -elif test "x$enable_bannertops" = xyes; then - BANNERTOPS="bannertops" - DEFAULT_BANNERTOPS="" -elif test $uname = Darwin; then - BANNERTOPS="" - DEFAULT_BANNERTOPS="#" -else - BANNERTOPS="bannertops" - DEFAULT_BANNERTOPS="" -fi - -if test "x$enable_texttops" = xno; then - TEXTTOPS="" - DEFAULT_TEXTTOPS="#" -elif test "x$enable_texttops" = xyes; then - TEXTTOPS="texttops" - DEFAULT_TEXTTOPS="" -elif test $uname = Darwin; then - TEXTTOPS="" - DEFAULT_TEXTTOPS="#" -else - TEXTTOPS="texttops" - DEFAULT_TEXTTOPS="" -fi - -AC_SUBST(BANNERTOPS) -AC_SUBST(DEFAULT_BANNERTOPS) -AC_SUBST(DEFAULT_TEXTTOPS) -AC_SUBST(TEXTTOPS) - -dnl Fonts -if test "x$BANNERTOPS" = x -a "x$TEXTTOPS" = x; then - FONTS="" -else - FONTS="fonts" -fi - -AC_SUBST(FONTS) - dnl Web interface... AC_ARG_ENABLE(webif, [ --enable-webif enable the web interface by default, default=no for Mac OS X]) case "x$enable_webif" in diff --git a/config-scripts/cups-image.m4 b/config-scripts/cups-image.m4 deleted file mode 100644 index 6df7befe2..000000000 --- a/config-scripts/cups-image.m4 +++ /dev/null @@ -1,112 +0,0 @@ -dnl -dnl "$Id: cups-image.m4 6649 2007-07-11 21:46:42Z mike $" -dnl -dnl Image library/filter stuff for CUPS. -dnl -dnl Copyright 2007-2011 by Apple Inc. -dnl Copyright 1997-2006 by Easy Software Products, all rights reserved. -dnl -dnl These coded instructions, statements, and computer programs are the -dnl property of Apple Inc. and are protected by Federal copyright -dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" -dnl which should have been included with this file. If this file is -dnl file is missing or damaged, see the license at "http://www.cups.org/". -dnl - -dnl See if we want the image filters included at all... -AC_ARG_ENABLE(image, [ --enable-image always build the image filters]) - -DEFAULT_IMAGEFILTERS="#" -IMGFILTERS="" -if test "x$enable_image" != xno; then - AC_MSG_CHECKING(whether to build image filters) - if test "x$enable_image" = xyes -o $uname != Darwin; then - IMGFILTERS="imagetops imagetoraster" - DEFAULT_IMAGEFILTERS="" - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi -fi - -AC_SUBST(DEFAULT_IMAGEFILTERS) -AC_SUBST(IMGFILTERS) - -dnl Check for image libraries... -AC_ARG_ENABLE(jpeg, [ --disable-jpeg disable JPEG support]) -AC_ARG_ENABLE(png, [ --disable-png disable PNG support]) -AC_ARG_ENABLE(tiff, [ --disable-tiff disable TIFF support]) - -LIBJPEG="" -LIBPNG="" -LIBTIFF="" -LIBZ="" - -AC_SUBST(LIBJPEG) -AC_SUBST(LIBPNG) -AC_SUBST(LIBTIFF) -AC_SUBST(LIBZ) - -dnl Image libraries use math library functions... -AC_SEARCH_LIBS(pow, m) - -dnl Save the current libraries since we don't want the image libraries -dnl included with every program... -SAVELIBS="$LIBS" - -dnl JPEG library... -if test x$enable_jpeg != xno; then - AC_CHECK_HEADER(jpeglib.h, - AC_CHECK_LIB(jpeg, jpeg_destroy_decompress, - AC_DEFINE(HAVE_LIBJPEG) - LIBJPEG="-ljpeg" - LIBS="$LIBS -ljpeg")) -else - AC_MSG_NOTICE([JPEG support disabled with --disable-jpeg.]) -fi - -dnl ZLIB library... -AC_CHECK_HEADER(zlib.h, - AC_CHECK_LIB(z, gzgets, - AC_DEFINE(HAVE_LIBZ) - LIBZ="-lz" - LIBS="$LIBS -lz")) - -dnl PNG library... -if test x$enable_png != xno; then - AC_CHECK_HEADER(png.h, - AC_CHECK_LIB(png, png_create_read_struct, - AC_DEFINE(HAVE_LIBPNG) - LIBPNG="-lpng")) -else - AC_MSG_NOTICE([PNG support disabled with --disable-png.]) -fi - -dnl TIFF library... -if test x$enable_tiff != xno; then - AC_CHECK_HEADER(tiff.h, - AC_CHECK_LIB(tiff, TIFFReadScanline, - AC_DEFINE(HAVE_LIBTIFF) - LIBTIFF="-ltiff")) -else - AC_MSG_NOTICE([TIFF support disabled with --disable-tiff.]) -fi - -dnl Restore original LIBS settings... -LIBS="$SAVELIBS" - -EXPORT_LIBJPEG="$LIBJPEG" -EXPORT_LIBPNG="$LIBPNG" -EXPORT_LIBTIFF="$LIBTIFF" -EXPORT_LIBZ="$LIBZ" - -AC_SUBST(EXPORT_LIBJPEG) -AC_SUBST(EXPORT_LIBPNG) -AC_SUBST(EXPORT_LIBTIFF) -AC_SUBST(EXPORT_LIBZ) - -AC_CHECK_HEADER(stdlib.h,AC_DEFINE(HAVE_STDLIB_H)) - -dnl -dnl End of "$Id: cups-image.m4 6649 2007-07-11 21:46:42Z mike $". -dnl diff --git a/config-scripts/cups-pap.m4 b/config-scripts/cups-pap.m4 deleted file mode 100644 index e69de29bb..000000000 diff --git a/config-scripts/cups-pdf.m4 b/config-scripts/cups-pdf.m4 deleted file mode 100644 index 575a5bac1..000000000 --- a/config-scripts/cups-pdf.m4 +++ /dev/null @@ -1,113 +0,0 @@ -dnl -dnl "$Id: cups-pdf.m4 7449 2008-04-14 18:27:53Z mike $" -dnl -dnl PDF filter configuration stuff for CUPS. -dnl -dnl Copyright 2007-2011 by Apple Inc. -dnl Copyright 2006 by Easy Software Products, all rights reserved. -dnl -dnl These coded instructions, statements, and computer programs are the -dnl property of Apple Inc. and are protected by Federal copyright -dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" -dnl which should have been included with this file. If this file is -dnl file is missing or damaged, see the license at "http://www.cups.org/". -dnl - -AC_ARG_WITH(pdftops, [ --with-pdftops set pdftops filter (gs,/path/to/gs,pdftops,/path/to/pdftops,none), default=pdftops ]) - -PDFTOPS="" -CUPS_PDFTOPS="" -CUPS_GHOSTSCRIPT="" - -case "x$with_pdftops" in - x) # Default/auto - if test $uname != Darwin; then - AC_PATH_PROG(CUPS_PDFTOPS, pdftops) - if test "x$CUPS_PDFTOPS" != x; then - AC_DEFINE(HAVE_PDFTOPS) - PDFTOPS="pdftops" - else - AC_PATH_PROG(CUPS_GHOSTSCRIPT, gs) - if test "x$CUPS_GHOSTSCRIPT" != x; then - AC_DEFINE(HAVE_GHOSTSCRIPT) - PDFTOPS="pdftops" - fi - fi - fi - ;; - - xgs) - AC_PATH_PROG(CUPS_GHOSTSCRIPT, gs) - if test "x$CUPS_GHOSTSCRIPT" != x; then - AC_DEFINE(HAVE_GHOSTSCRIPT) - PDFTOPS="pdftops" - else - AC_MSG_ERROR(Unable to find gs program!) - exit 1 - fi - ;; - - x/*/gs) # Use /path/to/gs without any check: - CUPS_GHOSTSCRIPT="$with_pdftops" - AC_DEFINE(HAVE_GHOSTSCRIPT) - PDFTOPS="pdftops" - ;; - - xpdftops) - AC_PATH_PROG(CUPS_PDFTOPS, pdftops) - if test "x$CUPS_PDFTOPS" != x; then - AC_DEFINE(HAVE_PDFTOPS) - PDFTOPS="pdftops" - else - AC_MSG_ERROR(Unable to find pdftops program!) - exit 1 - fi - ;; - - x/*/pdftops) # Use /path/to/pdftops without any check: - CUPS_PDFTOPS="$with_pdftops" - AC_DEFINE(HAVE_PDFTOPS) - PDFTOPS="pdftops" - ;; - - xnone) # Make no pdftops filter if with_pdftops=none: - ;; - - *) # Invalid with_pdftops value: - AC_MSG_ERROR(Invalid with_pdftops value!) - exit 1 - ;; -esac - -if test "x$CUPS_PDFTOPS" != x; then - AC_MSG_CHECKING(whether pdftops supports -origpagesizes) - if ($CUPS_PDFTOPS -h 2>&1 | grep -q -- -origpagesizes); then - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_PDFTOPS_WITH_ORIGPAGESIZES) - else - AC_MSG_RESULT(no) - fi - - DEFAULT_PDFTOPS="" -elif test "x$CUPS_GHOSTSCRIPT" != x; then - AC_MSG_CHECKING(whether gs supports the ps2write device) - if ($CUPS_GHOSTSCRIPT -h 2>&1 | grep -q ps2write); then - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_GHOSTSCRIPT_PS2WRITE) - else - AC_MSG_RESULT(no) - fi - - DEFAULT_PDFTOPS="" -else - DEFAULT_PDFTOPS="#" -fi - -AC_DEFINE_UNQUOTED(CUPS_PDFTOPS, "$CUPS_PDFTOPS") -AC_DEFINE_UNQUOTED(CUPS_GHOSTSCRIPT, "$CUPS_GHOSTSCRIPT") -AC_SUBST(DEFAULT_PDFTOPS) -AC_SUBST(PDFTOPS) - -dnl -dnl End of "$Id: cups-pdf.m4 7449 2008-04-14 18:27:53Z mike $". -dnl diff --git a/config-scripts/cups-scripting.m4 b/config-scripts/cups-scripting.m4 index 4bfb4e15a..d4ed98850 100644 --- a/config-scripts/cups-scripting.m4 +++ b/config-scripts/cups-scripting.m4 @@ -68,17 +68,6 @@ else AC_DEFINE(HAVE_PHP) fi -PHPDIR="" -if test "x$CUPS_PHP" != xno; then - AC_PATH_PROG(PHPCONFIG, php-config) - - if test "x$PHPCONFIG" != x; then - PHPDIR="scripting/php" - fi -fi - -AC_SUBST(PHPDIR) - dnl Do we have Python? AC_ARG_WITH(python, [ --with-python set Python interpreter for web interfaces ], CUPS_PYTHON="$withval", diff --git a/config-scripts/cups-sharedlibs.m4 b/config-scripts/cups-sharedlibs.m4 index 2e255b763..f126f3604 100644 --- a/config-scripts/cups-sharedlibs.m4 +++ b/config-scripts/cups-sharedlibs.m4 @@ -27,7 +27,6 @@ if test x$enable_shared != xno; then SunOS*) LIBCUPS="lib$cupsbase.so.2" LIBCUPSCGI="libcupscgi.so.1" - LIBCUPSDRIVER="libcupsdriver.so.1" LIBCUPSIMAGE="libcupsimage.so.2" LIBCUPSMIME="libcupsmime.so.1" LIBCUPSPPDC="libcupsppdc.so.1" @@ -38,7 +37,6 @@ if test x$enable_shared != xno; then UNIX_S*) LIBCUPS="lib$cupsbase.so.2" LIBCUPSCGI="libcupscgi.so.1" - LIBCUPSDRIVER="libcupsdriver.so.1" LIBCUPSIMAGE="libcupsimage.so.2" LIBCUPSMIME="libcupsmime.so.1" LIBCUPSPPDC="libcupsppdc.so.1" @@ -51,7 +49,6 @@ if test x$enable_shared != xno; then ia64) LIBCUPS="lib$cupsbase.so.2" LIBCUPSCGI="libcupscgi.so.1" - LIBCUPSDRIVER="libcupsdriver.so.1" LIBCUPSIMAGE="libcupsimage.so.2" LIBCUPSMIME="libcupsmime.so.1" LIBCUPSPPDC="libcupsppdc.so.1" @@ -62,7 +59,6 @@ if test x$enable_shared != xno; then *) LIBCUPS="lib$cupsbase.sl.2" LIBCUPSCGI="libcupscgi.sl.1" - LIBCUPSDRIVER="libcupsdriver.sl.1" LIBCUPSIMAGE="libcupsimage.sl.2" LIBCUPSMIME="libcupsmime.sl.1" LIBCUPSPPDC="libcupsppdc.sl.1" @@ -75,7 +71,6 @@ if test x$enable_shared != xno; then IRIX) LIBCUPS="lib$cupsbase.so.2" LIBCUPSCGI="libcupscgi.so.1" - LIBCUPSDRIVER="libcupsdriver.so.1" LIBCUPSIMAGE="libcupsimage.so.2" LIBCUPSMIME="libcupsmime.so.1" LIBCUPSPPDC="libcupsppdc.so.1" @@ -86,7 +81,6 @@ if test x$enable_shared != xno; then OSF1* | Linux | GNU | *BSD*) LIBCUPS="lib$cupsbase.so.2" LIBCUPSCGI="libcupscgi.so.1" - LIBCUPSDRIVER="libcupsdriver.so.1" LIBCUPSIMAGE="libcupsimage.so.2" LIBCUPSMIME="libcupsmime.so.1" LIBCUPSPPDC="libcupsppdc.so.1" @@ -97,7 +91,6 @@ if test x$enable_shared != xno; then Darwin*) LIBCUPS="lib$cupsbase.2.dylib" LIBCUPSCGI="libcupscgi.1.dylib" - LIBCUPSDRIVER="libcupsdriver.1.dylib" LIBCUPSIMAGE="libcupsimage.2.dylib" LIBCUPSMIME="libcupsmime.1.dylib" LIBCUPSPPDC="libcupsppdc.1.dylib" @@ -109,7 +102,6 @@ if test x$enable_shared != xno; then LIBCUPS="lib${cupsbase}_s.a" LIBCUPSBASE="${cupsbase}_s" LIBCUPSCGI="libcupscgi_s.a" - LIBCUPSDRIVER="libcupsdriver_s.a" LIBCUPSIMAGE="libcupsimage_s.a" LIBCUPSMIME="libcupsmime_s.a" LIBCUPSPPDC="libcupsppdc_s.a" @@ -122,7 +114,6 @@ if test x$enable_shared != xno; then echo " option with compiler." LIBCUPS="lib$cupsbase.so.2" LIBCUPSCGI="libcupscgi.so.1" - LIBCUPSDRIVER="libcupsdriver.so.1" LIBCUPSIMAGE="libcupsimage.so.2" LIBCUPSMIME="libcupsmime.so.1" LIBCUPSPPDC="libcupsppdc.so.1" @@ -135,7 +126,6 @@ else PICFLAG=0 LIBCUPS="lib$cupsbase.a" LIBCUPSCGI="libcupscgi.a" - LIBCUPSDRIVER="libcupsdriver.a" LIBCUPSIMAGE="libcupsimage.a" LIBCUPSMIME="libcupsmime.a" LIBCUPSPPDC="libcupsppdc.a" @@ -156,7 +146,6 @@ AC_SUBST(DSO64FLAGS) AC_SUBST(LIBCUPS) AC_SUBST(LIBCUPSBASE) AC_SUBST(LIBCUPSCGI) -AC_SUBST(LIBCUPSDRIVER) AC_SUBST(LIBCUPSIMAGE) AC_SUBST(LIBCUPSMIME) AC_SUBST(LIBCUPSPPDC) @@ -167,7 +156,6 @@ if test x$enable_shared = xno; then LINKCUPSIMAGE="../filter/libcupsimage.a" EXTLINKCUPS="-lcups" - EXTLINKCUPSDRIVER="-lcupsdriver" EXTLINKCUPSIMAGE="-lcupsimage" else if test $uname = AIX; then @@ -175,20 +163,17 @@ else LINKCUPSIMAGE="-lcupsimage_s" EXTLINKCUPS="-lcups_s" - EXTLINKCUPSDRIVER="-lcupsdriver_s" EXTLINKCUPSIMAGE="-lcupsimage_s" else LINKCUPS="-l${cupsbase}" LINKCUPSIMAGE="-lcupsimage" EXTLINKCUPS="-lcups" - EXTLINKCUPSDRIVER="-lcupsdriver" EXTLINKCUPSIMAGE="-lcupsimage" fi fi AC_SUBST(EXTLINKCUPS) -AC_SUBST(EXTLINKCUPSDRIVER) AC_SUBST(EXTLINKCUPSIMAGE) AC_SUBST(LINKCUPS) AC_SUBST(LINKCUPSIMAGE) @@ -201,7 +186,7 @@ if test "$DSO" != ":"; then # rather than to the executables. This makes things smaller if you # are using any static libraries, and it also allows us to distribute # a single DSO rather than a bunch... - DSOLIBS="\$(LIBTIFF) \$(LIBPNG) \$(LIBJPEG) \$(LIBZ)" + DSOLIBS="\$(LIBZ)" IMGLIBS="" # Tell the run-time linkers where to find a DSO. Some platforms @@ -258,7 +243,7 @@ if test "$DSO" != ":"; then esac else DSOLIBS="" - IMGLIBS="\$(LIBTIFF) \$(LIBPNG) \$(LIBJPEG) \$(LIBZ)" + IMGLIBS="\$(LIBZ)" fi AC_SUBST(DSOLIBS) diff --git a/configure.in b/configure.in index d219d56fe..60702956a 100644 --- a/configure.in +++ b/configure.in @@ -25,7 +25,6 @@ sinclude(config-scripts/cups-sharedlibs.m4) sinclude(config-scripts/cups-libtool.m4) sinclude(config-scripts/cups-compiler.m4) -sinclude(config-scripts/cups-image.m4) sinclude(config-scripts/cups-network.m4) sinclude(config-scripts/cups-poll.m4) sinclude(config-scripts/cups-slp.m4) @@ -38,7 +37,6 @@ sinclude(config-scripts/cups-largefile.m4) sinclude(config-scripts/cups-dnssd.m4) sinclude(config-scripts/cups-launchd.m4) sinclude(config-scripts/cups-defaults.m4) -sinclude(config-scripts/cups-pdf.m4) sinclude(config-scripts/cups-scripting.m4) INSTALL_LANGUAGES="" @@ -56,7 +54,7 @@ if test "x$LANGUAGES" != x; then LANGFILES="$LANGFILES templates/$lang/header.tmpl" fi done -elif test "x$CUPS_BUNDLEDIR" != ""; then +elif test "x$CUPS_BUNDLEDIR" != x; then INSTALL_LANGUAGES="install-langbundle" UNINSTALL_LANGUAGES="uninstall-langbundle" fi diff --git a/cups-config.in b/cups-config.in index f59abe0bb..7ba104477 100755 --- a/cups-config.in +++ b/cups-config.in @@ -1,10 +1,10 @@ #! /bin/sh # -# "$Id: cups-config.in 7394 2008-03-21 23:41:43Z mike $" -# +# "$Id: cups-config.in 9926 2011-08-27 09:23:01Z mike $" +# # CUPS configuration utility. # -# Copyright 2007-2010 by Apple Inc. +# Copyright 2007-2011 by Apple Inc. # Copyright 2001-2006 by Easy Software Products, all rights reserved. # # These coded instructions, statements, and computer programs are the @@ -15,7 +15,7 @@ # VERSION="@CUPS_VERSION@" -APIVERSION="1.5" +APIVERSION="1.6" BUILD="@CUPS_BUILD@" prefix=@prefix@ @@ -35,8 +35,7 @@ INSTALLSTATIC=@INSTALLSTATIC@ # flags for C++ compiler: CFLAGS="" LDFLAGS="@EXPORT_LDFLAGS@" -LIBS="@LIBGSSAPI@ @EXPORT_SSLLIBS@ @EXPORT_LIBZ@ @LIBS@" -IMGLIBS="@EXPORT_LIBTIFF@ @EXPORT_LIBJPEG@ @EXPORT_LIBPNG@" +LIBS="@LIBGSSAPI@ @EXPORT_SSLLIBS@ @LIBZ@ @LIBS@" # Check for local invocation... selfdir=`dirname $0` @@ -46,9 +45,6 @@ if test -f "$selfdir/cups/cups.h"; then LDFLAGS="-L$selfdir/cups -L$selfdir/filter $LDFLAGS" libdir="$selfdir/cups" imagelibdir="$selfdir/filter" - if test ! -f "$selfdir/cups/raster.h"; then - ln -s ../filter/raster.h "$selfdir/cups" - fi else if test $includedir != /usr/include; then CFLAGS="$CFLAGS -I$includedir" @@ -68,7 +64,7 @@ usage () echo " cups-config --datadir" echo " cups-config --help" echo " cups-config --ldflags" - echo " cups-config [--driver] [--image] [--static] --libs" + echo " cups-config [--image] [--static] --libs" echo " cups-config --serverbin" echo " cups-config --serverroot" echo " cups-config --version" @@ -83,7 +79,6 @@ fi # Parse command line options static=no image=no -driver=no while test $# -gt 0; do case $1 in @@ -99,9 +94,6 @@ while test $# -gt 0; do --datadir) echo $cups_datadir ;; - --driver) - driver=yes - ;; --help) usage 0 ;; @@ -117,16 +109,10 @@ while test $# -gt 0; do if test $image = yes; then libs="@EXTLINKCUPSIMAGE@ $libs" fi - if test $driver = yes; then - libs="@EXTLINKCUPSDRIVER@ $libs" - fi else libs="$libdir/libcups.a $LIBS"; if test $image = yes; then - libs="$libdir/libcupsimage.a $IMGLIBS $libs" - fi - if test $driver = yes; then - libs="$libdir/libcupsdriver.a $libs" + libs="$libdir/libcupsimage.a $libs" fi fi echo $libs @@ -156,5 +142,5 @@ while test $# -gt 0; do done # -# End of "$Id: cups-config.in 7394 2008-03-21 23:41:43Z mike $". +# End of "$Id: cups-config.in 9926 2011-08-27 09:23:01Z mike $". # diff --git a/cups/Makefile b/cups/Makefile index 6052bec01..113f8f645 100644 --- a/cups/Makefile +++ b/cups/Makefile @@ -120,6 +120,7 @@ HEADERSPRIV = \ md5-private.h \ ppd-private.h \ pwg-private.h \ + raster-private.h \ snmp-private.h \ string-private.h \ thread-private.h diff --git a/cups/cups.h b/cups/cups.h index 14cb02bba..857f17fbe 100644 --- a/cups/cups.h +++ b/cups/cups.h @@ -60,10 +60,10 @@ extern "C" { * Constants... */ -# define CUPS_VERSION 1.0501 +# define CUPS_VERSION 1.0599 # define CUPS_VERSION_MAJOR 1 -# define CUPS_VERSION_MINOR 5 -# define CUPS_VERSION_PATCH 1 +# define CUPS_VERSION_MINOR 6 +# define CUPS_VERSION_PATCH -1 # define CUPS_BC_FD 3 /* Back-channel file descriptor for select/poll */ # define CUPS_DATE_ANY (time_t)-1 diff --git a/cups/http.c b/cups/http.c index 037efd32e..8aab65a1d 100644 --- a/cups/http.c +++ b/cups/http.c @@ -2186,7 +2186,10 @@ _httpReadGNUTLS( size_t length) /* I - Number of bytes to read */ { http_t *http; /* HTTP connection */ + ssize_t bytes; /* Bytes read */ + + DEBUG_printf(("6_httpReadGNUTLS(ptr=%p, data=%p, length=%d)", ptr, data, (int)length)); http = (http_t *)ptr; @@ -2206,7 +2209,9 @@ _httpReadGNUTLS( } } - return (recv(http->fd, data, length, 0)); + bytes = recv(http->fd, data, length, 0); + DEBUG_printf(("6_httpReadGNUTLS: bytes=%d", (int)bytes)); + return (bytes); } #endif /* HAVE_SSL && HAVE_GNUTLS */ @@ -3189,7 +3194,16 @@ _httpWriteGNUTLS( const void *data, /* I - Data buffer */ size_t length) /* I - Number of bytes to write */ { - return (send(((http_t *)ptr)->fd, data, length, 0)); + ssize_t bytes; /* Bytes written */ + + + DEBUG_printf(("6_httpWriteGNUTLS(ptr=%p, data=%p, length=%d)", ptr, data, + (int)length)); + http_debug_hex("_httpWriteGNUTLS", data, (int)length); + + bytes = send(((http_t *)ptr)->fd, data, length, 0); + DEBUG_printf(("_httpWriteGNUTLS: bytes=%d", (int)bytes)); + return (bytes); } #endif /* HAVE_SSL && HAVE_GNUTLS */ @@ -3760,7 +3774,7 @@ http_set_credentials(http_t *http) /* I - Connection to server */ * 'http_setup_ssl()' - Set up SSL/TLS support on a connection. */ -static int /* O - Status of connection */ +static int /* O - 0 on success, -1 on failure */ http_setup_ssl(http_t *http) /* I - Connection to server */ { _cups_globals_t *cg = _cupsGlobals(); @@ -3768,29 +3782,30 @@ http_setup_ssl(http_t *http) /* I - Connection to server */ int any_root; /* Allow any root */ # ifdef HAVE_LIBSSL - SSL_CTX *context; /* Context for encryption */ - BIO *bio; /* BIO data */ + SSL_CTX *context; /* Context for encryption */ + BIO *bio; /* BIO data */ + const char *message = NULL;/* Error message */ # elif defined(HAVE_GNUTLS) + int status; /* Status of handshake */ gnutls_certificate_client_credentials *credentials; /* TLS credentials */ # elif defined(HAVE_CDSASSL) - OSStatus error; /* Error code */ - const char *message = NULL; /* Error message */ - char *hostname; /* Hostname */ + OSStatus error; /* Error code */ + char *hostname; /* Hostname */ + const char *message = NULL;/* Error message */ # ifdef HAVE_SECCERTIFICATECOPYDATA - cups_array_t *credentials; /* Credentials array */ - cups_array_t *names; /* CUPS distinguished names */ - CFArrayRef dn_array; /* CF distinguished names array */ - CFIndex count; /* Number of credentials */ - CFDataRef data; /* Certificate data */ - int i; /* Looping var */ - http_credential_t - *credential; /* Credential data */ + cups_array_t *credentials; /* Credentials array */ + cups_array_t *names; /* CUPS distinguished names */ + CFArrayRef dn_array; /* CF distinguished names array */ + CFIndex count; /* Number of credentials */ + CFDataRef data; /* Certificate data */ + int i; /* Looping var */ + http_credential_t *credential; /* Credential data */ # endif /* HAVE_SECCERTIFICATECOPYDATA */ # elif defined(HAVE_SSPISSL) - TCHAR username[256]; /* Username returned from GetUserName() */ - TCHAR commonName[256]; /* Common name for certificate */ - DWORD dwSize; /* 32 bit size */ + TCHAR username[256]; /* Username returned from GetUserName() */ + TCHAR commonName[256];/* Common name for certificate */ + DWORD dwSize; /* 32 bit size */ # endif /* HAVE_LIBSSL */ @@ -3806,6 +3821,8 @@ http_setup_ssl(http_t *http) /* I - Connection to server */ any_root = cg->any_root; # ifdef HAVE_LIBSSL + (void)any_root; + context = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */ @@ -3814,16 +3831,17 @@ http_setup_ssl(http_t *http) /* I - Connection to server */ BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http); http->tls = SSL_new(context); - SSL_set_bio(http->tls_credentials, bio, bio); + SSL_set_bio(http->tls, bio, bio); if (SSL_connect(http->tls) != 1) { -# ifdef DEBUG unsigned long error; /* Error code */ while ((error = ERR_get_error()) != 0) - DEBUG_printf(("8http_setup_ssl: %s", ERR_error_string(error, NULL))); -# endif /* DEBUG */ + { + message = ERR_error_string(error, NULL); + DEBUG_printf(("8http_setup_ssl: %s", message)); + } SSL_CTX_free(context); SSL_free(http->tls); @@ -3836,7 +3854,12 @@ http_setup_ssl(http_t *http) /* I - Connection to server */ # endif /* WIN32 */ http->status = HTTP_ERROR; - return (HTTP_ERROR); + if (!message) + message = _("Unable to establish a secure connection to host."); + + _cupsSetError(IPP_PKI_ERROR, message, 1); + + return (-1); } # elif defined(HAVE_GNUTLS) @@ -3844,8 +3867,11 @@ http_setup_ssl(http_t *http) /* I - Connection to server */ malloc(sizeof(gnutls_certificate_client_credentials)); if (credentials == NULL) { - http->error = errno; + DEBUG_printf(("8http_setup_ssl: Unable to allocate credentials: %s", + strerror(errno))); + http->error = errno; http->status = HTTP_ERROR; + _cupsSetHTTPError(HTTP_ERROR); return (-1); } @@ -3854,22 +3880,31 @@ http_setup_ssl(http_t *http) /* I - Connection to server */ gnutls_init(&http->tls, GNUTLS_CLIENT); gnutls_set_default_priority(http->tls); + gnutls_server_name_set(http->tls, GNUTLS_NAME_DNS, http->hostname, strlen(http->hostname)); gnutls_credentials_set(http->tls, GNUTLS_CRD_CERTIFICATE, *credentials); gnutls_transport_set_ptr(http->tls, (gnutls_transport_ptr)http); gnutls_transport_set_pull_function(http->tls, _httpReadGNUTLS); gnutls_transport_set_push_function(http->tls, _httpWriteGNUTLS); - if ((gnutls_handshake(http->tls)) != GNUTLS_E_SUCCESS) + while ((status = gnutls_handshake(http->tls)) != GNUTLS_E_SUCCESS) { - http->error = errno; - http->status = HTTP_ERROR; + DEBUG_printf(("8http_setup_ssl: gnutls_handshake returned %d (%s)", + status, gnutls_strerror(status))); - gnutls_deinit(http->tls); - gnutls_certificate_free_credentials(*credentials); - free(credentials); - http->tls = NULL; + if (gnutls_error_is_fatal(status)) + { + http->error = EIO; + http->status = HTTP_ERROR; - return (-1); + _cupsSetError(IPP_PKI_ERROR, gnutls_strerror(status), 0); + + gnutls_deinit(http->tls); + gnutls_certificate_free_credentials(*credentials); + free(credentials); + http->tls = NULL; + + return (-1); + } } http->tls_credentials = credentials; @@ -3877,8 +3912,9 @@ http_setup_ssl(http_t *http) /* I - Connection to server */ # elif defined(HAVE_CDSASSL) if ((error = SSLNewContext(false, &http->tls))) { - http->error = error; + http->error = errno; http->status = HTTP_ERROR; + _cupsSetHTTPError(HTTP_ERROR); return (-1); } @@ -3892,13 +3928,6 @@ http_setup_ssl(http_t *http) /* I - Connection to server */ DEBUG_printf(("4http_setup_ssl: SSLSetIOFuncs, error=%d", (int)error)); } - if (!error) - { - error = SSLSetProtocolVersionEnabled(http->tls, kSSLProtocol2, false); - DEBUG_printf(("4http_setup_ssl: SSLSetProtocolVersionEnabled, error=%d", - (int)error)); - } - if (!error) { error = SSLSetAllowsAnyRoot(http->tls, any_root); @@ -4130,6 +4159,7 @@ http_setup_ssl(http_t *http) /* I - Connection to server */ http->tls = _sspiAlloc(); if (!http->tls) + { return (-1); http->tls->sock = http->fd; @@ -4143,6 +4173,13 @@ http_setup_ssl(http_t *http) /* I - Connection to server */ { _sspiFree(http->tls_credentials); http->tls_credentials = NULL; + + http->error = EIO; + http->status = HTTP_ERROR; + + _cupsSetError(IPP_PKI_ERROR, + _("Unable to establish a secure connection to host."), 1); + return (-1); } @@ -4153,6 +4190,13 @@ http_setup_ssl(http_t *http) /* I - Connection to server */ { _sspiFree(http->tls_credentials); http->tls_credentials = NULL; + + http->error = EIO; + http->status = HTTP_ERROR; + + _cupsSetError(IPP_PKI_ERROR, + _("Unable to establish a secure connection to host."), 1); + return (-1); } # endif /* HAVE_CDSASSL */ @@ -4173,11 +4217,11 @@ http_shutdown_ssl(http_t *http) /* I - Connection to server */ # ifdef HAVE_LIBSSL SSL_CTX *context; /* Context for encryption */ - context = SSL_get_SSL_CTX(http->tls_credentials); + context = SSL_get_SSL_CTX(http->tls); - SSL_shutdown(http->tls_credentials); + SSL_shutdown(http->tls); SSL_CTX_free(context); - SSL_free(http->tls_credentials); + SSL_free(http->tls); # elif defined(HAVE_GNUTLS) gnutls_certificate_client_credentials *credentials; diff --git a/cups/libcups.exp b/cups/libcups.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/cups/libcups.order b/cups/libcups.order deleted file mode 100755 index e69de29bb..000000000 diff --git a/cups/mark.c b/cups/mark.c index 113220071..44fc54d68 100644 --- a/cups/mark.c +++ b/cups/mark.c @@ -257,11 +257,13 @@ cupsMarkOptions( * Map sides to duplex option... */ - if (!strcmp(sides, "one-sided")) + if (!strcmp(sides, "one-sided") && cache->sides_1sided) ppd_mark_option(ppd, cache->sides_option, cache->sides_1sided); - else if (!strcmp(sides, "two-sided-long-edge")) + else if (!strcmp(sides, "two-sided-long-edge") && + cache->sides_2sided_long) ppd_mark_option(ppd, cache->sides_option, cache->sides_2sided_long); - else if (!strcmp(sides, "two-sided-short-edge")) + else if (!strcmp(sides, "two-sided-short-edge") && + cache->sides_2sided_short) ppd_mark_option(ppd, cache->sides_option, cache->sides_2sided_short); } } diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c index b19610981..e161d057a 100644 --- a/cups/ppd-cache.c +++ b/cups/ppd-cache.c @@ -873,11 +873,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ pwg_name = "top"; else if (!_cups_strncasecmp(choice->choice, "Side", 4)) pwg_name = "side"; - else if (!_cups_strcasecmp(choice->choice, "Roll") || - !_cups_strcasecmp(choice->choice, "Roll1")) + else if (!_cups_strcasecmp(choice->choice, "Roll")) pwg_name = "main-roll"; - else if (!_cups_strcasecmp(choice->choice, "Roll2")) - pwg_name = "alternate-roll"; else { /* @@ -938,6 +935,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ pwg_name = "stationery-letterhead"; else if (!_cups_strncasecmp(choice->choice, "Preprint", 8)) pwg_name = "stationery-preprinted"; + else if (!_cups_strcasecmp(choice->choice, "Recycled")) + pwg_name = "stationery-recycled"; else if (!_cups_strncasecmp(choice->choice, "Transparen", 10)) pwg_name = "transparency"; else diff --git a/cups/ppd.c b/cups/ppd.c index 53e9fbf5a..325c4de5a 100644 --- a/cups/ppd.c +++ b/cups/ppd.c @@ -1,5 +1,5 @@ /* - * "$Id: ppd.c 7906 2008-09-03 20:19:43Z mike $" + * "$Id: ppd.c 9900 2011-08-17 20:59:46Z mike $" * * PPD file routines for CUPS. * @@ -43,6 +43,7 @@ * ppd_compare_coptions() - Compare two custom options. * ppd_compare_options() - Compare two options. * ppd_decode() - Decode a string value... + * ppd_free_filters() - Free the filters array. * ppd_free_group() - Free a single UI group. * ppd_free_option() - Free a single option. * ppd_get_coption() - Get a custom option record. @@ -52,6 +53,7 @@ * ppd_hash_option() - Generate a hash of the option name... * ppd_read() - Read a line from a PPD file, skipping comment * lines as necessary. + * ppd_update_filters() - Update the filters array as needed. */ /* @@ -110,6 +112,7 @@ static int ppd_compare_coptions(ppd_coption_t *a, ppd_coption_t *b); static int ppd_compare_options(ppd_option_t *a, ppd_option_t *b); static int ppd_decode(char *string); +static void ppd_free_filters(ppd_file_t *ppd); static void ppd_free_group(ppd_group_t *group); static void ppd_free_option(ppd_option_t *option); static ppd_coption_t *ppd_get_coption(ppd_file_t *ppd, const char *name); @@ -125,6 +128,8 @@ static int ppd_read(cups_file_t *fp, _ppd_line_t *line, char *keyword, char *option, char *text, char **string, int ignoreblank, _cups_globals_t *cg); +static int ppd_update_filters(ppd_file_t *ppd, + _cups_globals_t *cg); /* @@ -138,7 +143,6 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ ppd_emul_t *emul; /* Current emulation */ ppd_group_t *group; /* Current group */ char **font; /* Current font */ - char **filter; /* Current filter */ ppd_attr_t **attr; /* Current attribute */ ppd_coption_t *coption; /* Current custom option */ ppd_cparam_t *cparam; /* Current custom parameter */ @@ -211,13 +215,7 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ * Free any filters... */ - if (ppd->num_filters > 0) - { - for (i = ppd->num_filters, filter = ppd->filters; i > 0; i --, filter ++) - _cupsStrFree(*filter); - - ppd_free(ppd->filters); - } + ppd_free_filters(ppd); /* * Free any fonts... @@ -880,11 +878,10 @@ ppdOpen2(cups_file_t *fp) /* I - File to read from */ ppd->num_filters ++; /* - * Copy filter string and prevent it from being freed below... + * Retain a copy of the filter string... */ - *filter = string; - string = NULL; + *filter = _cupsStrRetain(string); } else if (!strcmp(keyword, "Throughput")) ppd->throughput = atoi(string); @@ -1961,6 +1958,17 @@ ppdOpen2(cups_file_t *fp) /* I - File to read from */ return (NULL); } + /* + * Update the filters array as needed... + */ + + if (!ppd_update_filters(ppd, cg)) + { + ppdClose(ppd); + + return (NULL); + } + /* * Create the sorted options array and set the option back-pointer for * each choice and custom option... @@ -2376,6 +2384,30 @@ ppd_decode(char *string) /* I - String to decode */ } +/* + * 'ppd_free_filters()' - Free the filters array. + */ + +static void +ppd_free_filters(ppd_file_t *ppd) /* I - PPD file */ +{ + int i; /* Looping var */ + char **filter; /* Current filter */ + + + if (ppd->num_filters > 0) + { + for (i = ppd->num_filters, filter = ppd->filters; i > 0; i --, filter ++) + _cupsStrFree(*filter); + + ppd_free(ppd->filters); + + ppd->num_filters = 0; + ppd->filters = NULL; + } +} + + /* * 'ppd_free_group()' - Free a single UI group. */ @@ -3140,5 +3172,125 @@ ppd_read(cups_file_t *fp, /* I - File to read from */ /* - * End of "$Id: ppd.c 7906 2008-09-03 20:19:43Z mike $". + * 'ppd_update_filters()' - Update the filters array as needed. + * + * This function re-populates the filters array with cupsFilter2 entries that + * have been stripped of the destination MIME media types and any maxsize hints. + * + * (All for backwards-compatibility) + */ + +static int /* O - 1 on success, 0 on failure */ +ppd_update_filters(ppd_file_t *ppd,/* I - PPD file */ + _cups_globals_t *cg) /* I - Global data */ +{ + ppd_attr_t *attr; /* Current cupsFilter2 value */ + char srcsuper[16], /* Source MIME media type */ + srctype[256], + dstsuper[16], /* Destination MIME media type */ + dsttype[256], + program[1024], /* Command to run */ + *ptr, /* Pointer into command to run */ + buffer[1024], /* Re-written cupsFilter value */ + **filter; /* Current filter */ + int cost; /* Cost of filter */ + + + DEBUG_printf(("4ppd_update_filters(ppd=%p, cg=%p)", ppd, cg)); + + /* + * See if we have any cupsFilter2 lines... + */ + + if ((attr = ppdFindAttr(ppd, "cupsFilter2", NULL)) == NULL) + { + DEBUG_puts("5ppd_update_filters: No cupsFilter2 keywords present."); + return (1); + } + + /* + * Yes, free the cupsFilter-defined filters and re-build... + */ + + ppd_free_filters(ppd); + + do + { + /* + * Parse the cupsFilter2 string: + * + * src/type dst/type cost program + * src/type dst/type cost maxsize(n) program + */ + + DEBUG_printf(("5ppd_update_filters: cupsFilter2=\"%s\"", attr->value)); + + if (sscanf(attr->value, "%15[^/]/%255s%*[ \t]%15[^/]/%255s%d%*[ \t]%1023[^\n]", + srcsuper, srctype, dstsuper, dsttype, &cost, program) != 6) + { + DEBUG_puts("5ppd_update_filters: Bad cupsFilter2 line."); + cg->ppd_status = PPD_BAD_VALUE; + + return (0); + } + + DEBUG_printf(("5ppd_update_filters: srcsuper=\"%s\", srctype=\"%s\", " + "dstsuper=\"%s\", dsttype=\"%s\", cost=%d, program=\"%s\"", + srcsuper, srctype, dstsuper, dsttype, cost, program)); + + if (!strncmp(program, "maxsize(", 8) && + (ptr = strchr(program + 8, ')')) != NULL) + { + DEBUG_puts("5ppd_update_filters: Found maxsize(nnn)."); + + ptr ++; + while (_cups_isspace(*ptr)) + ptr ++; + + _cups_strcpy(program, ptr); + DEBUG_printf(("5ppd_update_filters: New program=\"%s\"", program)); + } + + /* + * Convert to cupsFilter format: + * + * src/type cost program + */ + + snprintf(buffer, sizeof(buffer), "%s/%s %d %s", srcsuper, srctype, cost, + program); + DEBUG_printf(("5ppd_update_filters: Adding \"%s\".", buffer)); + + /* + * Add a cupsFilter-compatible string to the filters array. + */ + + if (ppd->num_filters == 0) + filter = malloc(sizeof(char *)); + else + filter = realloc(ppd->filters, sizeof(char *) * (ppd->num_filters + 1)); + + if (filter == NULL) + { + DEBUG_puts("5ppd_update_filters: Out of memory."); + cg->ppd_status = PPD_ALLOC_ERROR; + + return (0); + } + + ppd->filters = filter; + filter += ppd->num_filters; + ppd->num_filters ++; + + *filter = _cupsStrAlloc(buffer); + } + while ((attr = ppdFindNextAttr(ppd, "cupsFilter2", NULL)) != NULL); + + DEBUG_puts("5ppd_update_filters: Completed OK."); + return (1); +} + + +/* + * End of "$Id: ppd.c 9900 2011-08-17 20:59:46Z mike $". */ diff --git a/cups/raster-private.h b/cups/raster-private.h new file mode 100644 index 000000000..0a1996c5c --- /dev/null +++ b/cups/raster-private.h @@ -0,0 +1,67 @@ +/* + * "$Id$" + * + * Private image library definitions for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1993-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * which should have been included with this file. If this file is + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_RASTER_PRIVATE_H_ +# define _CUPS_RASTER_PRIVATE_H_ + +/* + * Include necessary headers... + */ + +# include "raster.h" +# include +# include +# include +# ifdef WIN32 +# include +# include /* for htonl() definition */ +# else +# include +# include +# endif /* WIN32 */ + + +/* + * min/max/abs macros... + */ + +# ifndef max +# define max(a,b) ((a) > (b) ? (a) : (b)) +# endif /* !max */ +# ifndef min +# define min(a,b) ((a) < (b) ? (a) : (b)) +# endif /* !min */ +# ifndef abs +# define abs(a) ((a) < 0 ? -(a) : (a)) +# endif /* !abs */ + + +/* + * Prototypes... + */ + +extern int _cupsRasterExecPS(cups_page_header2_t *h, + int *preferred_bits, + const char *code); +extern void _cupsRasterAddError(const char *f, ...); +extern void _cupsRasterClearError(void); + +#endif /* !_CUPS_RASTER_PRIVATE_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/request.c b/cups/request.c index 7d724b6ab..e8b142512 100644 --- a/cups/request.c +++ b/cups/request.c @@ -343,7 +343,8 @@ cupsDoRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ * * Use this function to get the response for an IPP request sent using * cupsSendDocument() or cupsSendRequest(). For requests that return - * additional data, use httpRead() after getting a successful response. + * additional data, use httpRead() after getting a successful response, + * otherwise call httpFlush() to complete the response processing. * * @since CUPS 1.4/Mac OS X 10.6@ */ @@ -426,6 +427,8 @@ cupsGetResponse(http_t *http, /* I - Connection to server or @code CUPS_HTTP response = NULL; _cupsSetError(IPP_SERVICE_UNAVAILABLE, NULL, 0); + http->status = status = HTTP_ERROR; + http->error = EIO; } } else if (status != HTTP_ERROR) @@ -451,7 +454,7 @@ cupsGetResponse(http_t *http, /* I - Connection to server or @code CUPS_HTTP if (!cupsDoAuthentication(http, "POST", resource)) httpReconnect(http); else - status = HTTP_AUTHORIZATION_CANCELED; + http->status = status = HTTP_AUTHORIZATION_CANCELED; } #ifdef HAVE_SSL @@ -637,6 +640,20 @@ cupsSendRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP if ((http = _cupsConnect()) == NULL) return (HTTP_SERVICE_UNAVAILABLE); + /* + * If the prior request was not flushed out, do so now... + */ + + if (http->state == HTTP_GET_SEND || + http->state == HTTP_POST_SEND) + httpFlush(http); + else if (http->state != HTTP_WAITING) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + + return (HTTP_ERROR); + } + #ifdef HAVE_SSL /* * See if we have an auth-info attribute and are communicating over diff --git a/cups/testfile.c b/cups/testfile.c index ed3d86af6..2aa3fb99c 100644 --- a/cups/testfile.c +++ b/cups/testfile.c @@ -133,9 +133,9 @@ main(int argc, /* I - Number of command-line arguments */ * Count lines in psglyphs, rewind, then count again. */ - fputs("\ncupsFileOpen(\"../data/psglyphs\", \"r\"): ", stdout); + fputs("\ncupsFileOpen(\"../data/media.defs\", \"r\"): ", stdout); - if ((fp = cupsFileOpen("../data/psglyphs", "r")) == NULL) + if ((fp = cupsFileOpen("../data/media.defs", "r")) == NULL) { puts("FAIL"); status ++; @@ -145,9 +145,9 @@ main(int argc, /* I - Number of command-line arguments */ puts("PASS"); fputs("cupsFileGets: ", stdout); - if ((count = count_lines(fp)) != 1051) + if ((count = count_lines(fp)) != 208) { - printf("FAIL (got %d lines, expected 1051)\n", count); + printf("FAIL (got %d lines, expected 208)\n", count); status ++; } else @@ -165,9 +165,9 @@ main(int argc, /* I - Number of command-line arguments */ puts("PASS"); fputs("cupsFileGets: ", stdout); - if ((count = count_lines(fp)) != 1051) + if ((count = count_lines(fp)) != 208) { - printf("FAIL (got %d lines, expected 1051)\n", count); + printf("FAIL (got %d lines, expected 208)\n", count); status ++; } else diff --git a/data/Makefile b/data/Makefile index 4f575a5ce..7df826095 100644 --- a/data/Makefile +++ b/data/Makefile @@ -27,21 +27,15 @@ BANNERS = \ topsecret \ unclassified -CHARSETS = \ - utf-8 - DATAFILES = \ - psglyphs \ testprint PPDCFILES = \ epson.h \ - escp.h \ font.defs \ hp.h \ label.h \ media.defs \ - pcl.h \ raster.defs @@ -96,12 +90,6 @@ install-data: for file in $(BANNERS); do \ $(INSTALL_DATA) $$file $(DATADIR)/banners; \ done - $(INSTALL_DIR) -m 755 $(DATADIR)/charsets - if test "x$(BANNERTOPS)" != x -o "x$(TEXTTOPS)" != x; then \ - for file in $(CHARSETS); do \ - $(INSTALL_DATA) $$file $(DATADIR)/charsets; \ - done; \ - fi $(INSTALL_DIR) -m 755 $(DATADIR)/data for file in $(DATAFILES); do \ $(INSTALL_DATA) $$file $(DATADIR)/data; \ @@ -143,9 +131,6 @@ uninstall: for file in $(BANNERS); do \ $(RM) $(DATADIR)/banners/$$file; \ done - for file in $(CHARSETS); do \ - $(RM) $(DATADIR)/charsets/$$file; \ - done for file in $(DATAFILES); do \ $(RM) $(DATADIR)/data/$$file; \ done @@ -156,7 +141,6 @@ uninstall: -$(RMDIR) $(DATADIR)/ppdc -$(RMDIR) $(DATADIR)/model -$(RMDIR) $(DATADIR)/data - -$(RMDIR) $(DATADIR)/charsets -$(RMDIR) $(DATADIR)/banners -$(RMDIR) $(DATADIR) diff --git a/data/escp.h b/data/escp.h deleted file mode 100644 index 94389f3b9..000000000 --- a/data/escp.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * "$Id$" - * - * This file contains model number definitions for the CUPS unified - * ESC/P driver. - * - * Copyright 2007 by Apple Inc. - * Copyright 1997-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - */ - -/* General ESC/P Support */ -#define ESCP_DOTMATRIX 0x1 /* Dot matrix printer? */ -#define ESCP_MICROWEAVE 0x2 /* Use microweave command? */ -#define ESCP_STAGGER 0x4 /* Are color jets staggered? */ -#define ESCP_ESCK 0x8 /* Use print mode command?*/ -#define ESCP_EXT_UNITS 0x10 /* Use extended unit commands? */ -#define ESCP_EXT_MARGINS 0x20 /* Use extended margin command */ -#define ESCP_USB 0x40 /* Send USB packet mode escape? */ -#define ESCP_PAGE_SIZE 0x80 /* Use page size command */ -#define ESCP_RASTER_ESCI 0x100 /* Use ESC i graphics command */ - -/* Remote mode support */ -#define ESCP_REMOTE 0x1000 /* Use remote mode commands? */ - - -/* - * End of "$Id$". - */ diff --git a/data/pcl.h b/data/pcl.h deleted file mode 100644 index 0cb1effe5..000000000 --- a/data/pcl.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * "$Id$" - * - * This file contains model number definitions for the CUPS unified - * PCL driver. - * - * Copyright 2007 by Apple Inc. - * Copyright 1997-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - */ - -/* General PCL Support */ -#define PCL_PAPER_SIZE 0x1 /* Use ESC&l#A */ -#define PCL_INKJET 0x2 /* Use inkjet commands */ - -/* Raster Support */ -#define PCL_RASTER_END_COLOR 0x100 /* Use ESC*rC */ -#define PCL_RASTER_CID 0x200 /* Use ESC*v#W */ -#define PCL_RASTER_CRD 0x400 /* Use ESC*g#W */ -#define PCL_RASTER_SIMPLE 0x800 /* Use ESC*r#U */ -#define PCL_RASTER_RGB24 0x1000 /* Use 24-bit RGB mode */ - -/* PJL Support */ -#define PCL_PJL 0x10000 /* Use PJL Commands */ -#define PCL_PJL_PAPERWIDTH 0x20000 /* Use PJL PAPERWIDTH/LENGTH */ -#define PCL_PJL_HPGL2 0x40000 /* Enter HPGL2 */ -#define PCL_PJL_PCL3GUI 0x80000 /* Enter PCL3GUI */ -#define PCL_PJL_RESOLUTION 0x100000 /* Use PJL SET RESOLUTION */ - - -/* - * End of "$Id$". - */ diff --git a/data/psglyphs b/data/psglyphs deleted file mode 100644 index c4a902c66..000000000 --- a/data/psglyphs +++ /dev/null @@ -1,1051 +0,0 @@ -0020 space -0021 exclam -0022 quotedbl -0023 numbersign -0024 dollar -0025 percent -0026 ampersand -0027 quotesingle -0028 parenleft -0029 parenright -002a asterisk -002b plus -002c comma -002d minus -002e period -002f slash -0030 zero -0031 one -0032 two -0033 three -0034 four -0035 five -0036 six -0037 seven -0038 eight -0039 nine -003a colon -003b semicolon -003c less -003d equal -003e greater -003f question -0040 at -0041 A -0042 B -0043 C -0044 D -0045 E -0046 F -0047 G -0048 H -0049 I -004a J -004b K -004c L -004d M -004e N -004f O -0050 P -0051 Q -0052 R -0053 S -0054 T -0055 U -0056 V -0057 W -0058 X -0059 Y -005a Z -005b bracketleft -005c backslash -005d bracketright -005e asciicircum -005f underscore -0060 grave -0061 a -0062 b -0063 c -0064 d -0065 e -0066 f -0067 g -0068 h -0069 i -006a j -006b k -006c l -006d m -006e n -006f o -0070 p -0071 q -0072 r -0073 s -0074 t -0075 u -0076 v -0077 w -0078 x -0079 y -007a z -007b braceleft -007c bar -007d braceright -007e asciitilde -00a0 space -00a1 exclamdown -00a2 cent -00a3 sterling -00a4 currency -00a5 yen -00a6 brokenbar -00a7 section -00a8 dieresis -00a9 copyright -00aa ordfeminine -00ab guillemotleft -00ac logicalnot -00ad hyphen -00ae registered -00af macron -00b0 degree -00b1 plusminus -00b2 twosuperior -00b3 threesuperior -00b4 acute -00b5 mu -00b6 paragraph -00b7 periodcentered -00b8 cedilla -00b9 onesuperior -00ba ordmasculine -00bb guillemotright -00bc onequarter -00bd onehalf -00be threequarters -00bf questiondown -00c0 Agrave -00c1 Aacute -00c2 Acircumflex -00c3 Atilde -00c4 Adieresis -00c5 Aring -00c6 AE -00c7 Ccedilla -00c8 Egrave -00c9 Eacute -00ca Ecircumflex -00cb Edieresis -00cc Igrave -00cd Iacute -00ce Icircumflex -00cf Idieresis -00d0 Eth -00d1 Ntilde -00d2 Ograve -00d3 Oacute -00d4 Ocircumflex -00d5 Otilde -00d6 Odieresis -00d7 multiply -00d8 Oslash -00d9 Ugrave -00da Uacute -00db Ucircumflex -00dc Udieresis -00dd Yacute -00de Thorn -00df germandbls -00e0 agrave -00e1 aacute -00e2 acircumflex -00e3 atilde -00e4 adieresis -00e5 aring -00e6 ae -00e7 ccedilla -00e8 egrave -00e9 eacute -00ea ecircumflex -00eb edieresis -00ec igrave -00ed iacute -00ee icircumflex -00ef idieresis -00f0 eth -00f1 ntilde -00f2 ograve -00f3 oacute -00f4 ocircumflex -00f5 otilde -00f6 odieresis -00f7 divide -00f8 oslash -00f9 ugrave -00fa uacute -00fb ucircumflex -00fc udieresis -00fd yacute -00fe thorn -00ff ydieresis -0100 Amacron -0101 amacron -0102 Abreve -0103 abreve -0104 Aogonek -0105 aogonek -0106 Cacute -0107 cacute -0108 Ccircumflex -0109 ccircumflex -010a Cdotaccent -010b cdotaccent -010c Ccaron -010d ccaron -010e Dcaron -010f dcaron -0110 Dcroat -0111 dcroat -0112 Emacron -0113 emacron -0114 Ebreve -0115 ebreve -0116 Edotaccent -0117 edotaccent -0118 Eogonek -0119 eogonek -011a Ecaron -011b ecaron -011c Gcircumflex -011d gcircumflex -011e Gbreve -011f gbreve -0120 Gdotaccent -0121 gdotaccent -0122 Gcommaaccent -0123 gcommaaccent -0124 Hcircumflex -0125 hcircumflex -0126 Hbar -0127 hbar -0128 Itilde -0129 itilde -012a Imacron -012b imacron -012c Ibreve -012d ibreve -012e Iogonek -012f iogonek -0130 Idotaccent -0131 dotlessi -0132 IJ -0133 ij -0134 Jcircumflex -0135 jcircumflex -0136 Kcommaaccent -0137 kcommaaccent -0138 kgreenlandic -0139 Lacute -013a lacute -013b Lcommaaccent -013c lcommaaccent -013d Lcaron -013e lcaron -013f Ldot -0140 ldot -0141 Lslash -0142 lslash -0143 Nacute -0144 nacute -0145 Ncommaaccent -0146 ncommaaccent -0147 Ncaron -0148 ncaron -0149 napostrophe -014a Eng -014b eng -014c Omacron -014d omacron -014e Obreve -014f obreve -0150 Ohungarumlaut -0151 ohungarumlaut -0152 OE -0153 oe -0154 Racute -0155 racute -0156 Rcommaaccent -0157 rcommaaccent -0158 Rcaron -0159 rcaron -015a Sacute -015b sacute -015c Scircumflex -015d scircumflex -015e Scedilla -015f scedilla -0160 Scaron -0161 scaron -0162 Tcommaaccent -0163 tcommaaccent -0164 Tcaron -0165 tcaron -0166 Tbar -0167 tbar -0168 Utilde -0169 utilde -016a Umacron -016b umacron -016c Ubreve -016d ubreve -016e Uring -016f uring -0170 Uhungarumlaut -0171 uhungarumlaut -0172 Uogonek -0173 uogonek -0174 Wcircumflex -0175 wcircumflex -0176 Ycircumflex -0177 ycircumflex -0178 Ydieresis -0179 Zacute -017a zacute -017b Zdotaccent -017c zdotaccent -017d Zcaron -017e zcaron -017f longs -0192 florin -01a0 Ohorn -01a1 ohorn -01af Uhorn -01b0 uhorn -01e6 Gcaron -01e7 gcaron -01fa Aringacute -01fb aringacute -01fc AEacute -01fd aeacute -01fe Oslashacute -01ff oslashacute -0218 Scommaaccent -0219 scommaaccent -021a Tcommaaccent -021b tcommaaccent -02bc afii57929 -02bd afii64937 -02c6 circumflex -02c7 caron -02c9 macron -02d8 breve -02d9 dotaccent -02da ring -02db ogonek -02dc tilde -02dd hungarumlaut -0300 gravecomb -0301 acutecomb -0303 tildecomb -0309 hookabovecomb -0323 dotbelowcomb -0384 tonos -0385 dieresistonos -0386 Alphatonos -0387 anoteleia -0388 Epsilontonos -0389 Etatonos -038a Iotatonos -038c Omicrontonos -038e Upsilontonos -038f Omegatonos -0390 iotadieresistonos -0391 Alpha -0392 Beta -0393 Gamma -0394 Delta -0395 Epsilon -0396 Zeta -0397 Eta -0398 Theta -0399 Iota -039a Kappa -039b Lambda -039c Mu -039d Nu -039e Xi -039f Omicron -03a0 Pi -03a1 Rho -03a3 Sigma -03a4 Tau -03a5 Upsilon -03a6 Phi -03a7 Chi -03a8 Psi -03a9 Omega -03aa Iotadieresis -03ab Upsilondieresis -03ac alphatonos -03ad epsilontonos -03ae etatonos -03af iotatonos -03b0 upsilondieresistonos -03b1 alpha -03b2 beta -03b3 gamma -03b4 delta -03b5 epsilon -03b6 zeta -03b7 eta -03b8 theta -03b9 iota -03ba kappa -03bb lambda -03bc mu -03bd nu -03be xi -03bf omicron -03c0 pi -03c1 rho -03c2 sigma1 -03c3 sigma -03c4 tau -03c5 upsilon -03c6 phi -03c7 chi -03c8 psi -03c9 omega -03ca iotadieresis -03cb upsilondieresis -03cc omicrontonos -03cd upsilontonos -03ce omegatonos -03d1 theta1 -03d2 Upsilon1 -03d5 phi1 -03d6 omega1 -0401 afii10023 -0402 afii10051 -0403 afii10052 -0404 afii10053 -0405 afii10054 -0406 afii10055 -0407 afii10056 -0408 afii10057 -0409 afii10058 -040a afii10059 -040b afii10060 -040c afii10061 -040e afii10062 -040f afii10145 -0410 afii10017 -0411 afii10018 -0412 afii10019 -0413 afii10020 -0414 afii10021 -0415 afii10022 -0416 afii10024 -0417 afii10025 -0418 afii10026 -0419 afii10027 -041a afii10028 -041b afii10029 -041c afii10030 -041d afii10031 -041e afii10032 -041f afii10033 -0420 afii10034 -0421 afii10035 -0422 afii10036 -0423 afii10037 -0424 afii10038 -0425 afii10039 -0426 afii10040 -0427 afii10041 -0428 afii10042 -0429 afii10043 -042a afii10044 -042b afii10045 -042c afii10046 -042d afii10047 -042e afii10048 -042f afii10049 -0430 afii10065 -0431 afii10066 -0432 afii10067 -0433 afii10068 -0434 afii10069 -0435 afii10070 -0436 afii10072 -0437 afii10073 -0438 afii10074 -0439 afii10075 -043a afii10076 -043b afii10077 -043c afii10078 -043d afii10079 -043e afii10080 -043f afii10081 -0440 afii10082 -0441 afii10083 -0442 afii10084 -0443 afii10085 -0444 afii10086 -0445 afii10087 -0446 afii10088 -0447 afii10089 -0448 afii10090 -0449 afii10091 -044a afii10092 -044b afii10093 -044c afii10094 -044d afii10095 -044e afii10096 -044f afii10097 -0451 afii10071 -0452 afii10099 -0453 afii10100 -0454 afii10101 -0455 afii10102 -0456 afii10103 -0457 afii10104 -0458 afii10105 -0459 afii10106 -045a afii10107 -045b afii10108 -045c afii10109 -045e afii10110 -045f afii10193 -0462 afii10146 -0463 afii10194 -0472 afii10147 -0473 afii10195 -0474 afii10148 -0475 afii10196 -0490 afii10050 -0491 afii10098 -04d9 afii10846 -05b0 afii57799 -05b1 afii57801 -05b2 afii57800 -05b3 afii57802 -05b4 afii57793 -05b5 afii57794 -05b6 afii57795 -05b7 afii57798 -05b8 afii57797 -05b9 afii57806 -05bb afii57796 -05bc afii57807 -05bd afii57839 -05be afii57645 -05bf afii57841 -05c0 afii57842 -05c1 afii57804 -05c2 afii57803 -05c3 afii57658 -05d0 afii57664 -05d1 afii57665 -05d2 afii57666 -05d3 afii57667 -05d4 afii57668 -05d5 afii57669 -05d6 afii57670 -05d7 afii57671 -05d8 afii57672 -05d9 afii57673 -05da afii57674 -05db afii57675 -05dc afii57676 -05dd afii57677 -05de afii57678 -05df afii57679 -05e0 afii57680 -05e1 afii57681 -05e2 afii57682 -05e3 afii57683 -05e4 afii57684 -05e5 afii57685 -05e6 afii57686 -05e7 afii57687 -05e8 afii57688 -05e9 afii57689 -05ea afii57690 -05f0 afii57716 -05f1 afii57717 -05f2 afii57718 -060c afii57388 -061b afii57403 -061f afii57407 -0621 afii57409 -0622 afii57410 -0623 afii57411 -0624 afii57412 -0625 afii57413 -0626 afii57414 -0627 afii57415 -0628 afii57416 -0629 afii57417 -062a afii57418 -062b afii57419 -062c afii57420 -062d afii57421 -062e afii57422 -062f afii57423 -0630 afii57424 -0631 afii57425 -0632 afii57426 -0633 afii57427 -0634 afii57428 -0635 afii57429 -0636 afii57430 -0637 afii57431 -0638 afii57432 -0639 afii57433 -063a afii57434 -0640 afii57440 -0641 afii57441 -0642 afii57442 -0643 afii57443 -0644 afii57444 -0645 afii57445 -0646 afii57446 -0647 afii57470 -0648 afii57448 -0649 afii57449 -064a afii57450 -064b afii57451 -064c afii57452 -064d afii57453 -064e afii57454 -064f afii57455 -0650 afii57456 -0651 afii57457 -0652 afii57458 -0660 afii57392 -0661 afii57393 -0662 afii57394 -0663 afii57395 -0664 afii57396 -0665 afii57397 -0666 afii57398 -0667 afii57399 -0668 afii57400 -0669 afii57401 -066a afii57381 -066d afii63167 -0679 afii57511 -067e afii57506 -0686 afii57507 -0688 afii57512 -0691 afii57513 -0698 afii57508 -06a4 afii57505 -06af afii57509 -06ba afii57514 -06d2 afii57519 -06d5 afii57534 -1e80 Wgrave -1e81 wgrave -1e82 Wacute -1e83 wacute -1e84 Wdieresis -1e85 wdieresis -1ef2 Ygrave -1ef3 ygrave -200c afii61664 -200d afii301 -200e afii299 -200f afii300 -2012 figuredash -2013 endash -2014 emdash -2015 afii00208 -2017 underscoredbl -2018 quoteleft -2019 quoteright -201a quotesinglbase -201b quotereversed -201c quotedblleft -201d quotedblright -201e quotedblbase -2020 dagger -2021 daggerdbl -2022 bullet -2024 onedotenleader -2025 twodotenleader -2026 ellipsis -202c afii61573 -202d afii61574 -202e afii61575 -2030 perthousand -2032 minute -2033 second -2039 guilsinglleft -203a guilsinglright -203c exclamdbl -2044 fraction -2070 zerosuperior -2074 foursuperior -2075 fivesuperior -2076 sixsuperior -2077 sevensuperior -2078 eightsuperior -2079 ninesuperior -207d parenleftsuperior -207e parenrightsuperior -207f nsuperior -2080 zeroinferior -2081 oneinferior -2082 twoinferior -2083 threeinferior -2084 fourinferior -2085 fiveinferior -2086 sixinferior -2087 seveninferior -2088 eightinferior -2089 nineinferior -208d parenleftinferior -208e parenrightinferior -20a1 colonmonetary -20a3 franc -20a4 lira -20a7 peseta -20aa afii57636 -20ab dong -20ac Euro -2105 afii61248 -2111 Ifraktur -2113 afii61289 -2116 afii61352 -2118 weierstrass -211c Rfraktur -211e prescription -2122 trademark -2126 Omega -212e estimated -2135 aleph -2153 onethird -2154 twothirds -215b oneeighth -215c threeeighths -215d fiveeighths -215e seveneighths -2190 arrowleft -2191 arrowup -2192 arrowright -2193 arrowdown -2194 arrowboth -2195 arrowupdn -21a8 arrowupdnbse -21b5 carriagereturn -21d0 arrowdblleft -21d1 arrowdblup -21d2 arrowdblright -21d3 arrowdbldown -21d4 arrowdblboth -2200 universal -2202 partialdiff -2203 existential -2205 emptyset -2206 Delta -2207 gradient -2208 element -2209 notelement -220b suchthat -220f product -2211 summation -2212 minus -2215 fraction -2217 asteriskmath -2219 periodcentered -221a radical -221d proportional -221e infinity -221f orthogonal -2220 angle -2227 logicaland -2228 logicalor -2229 intersection -222a union -222b integral -2234 therefore -223c similar -2245 congruent -2248 approxequal -2260 notequal -2261 equivalence -2264 lessequal -2265 greaterequal -2282 propersubset -2283 propersuperset -2284 notsubset -2286 reflexsubset -2287 reflexsuperset -2295 circleplus -2297 circlemultiply -22a5 perpendicular -22c5 dotmath -2302 house -2310 revlogicalnot -2320 integraltp -2321 integralbt -2329 angleleft -232a angleright -2500 SF100000 -2502 SF110000 -250c SF010000 -2510 SF030000 -2514 SF020000 -2518 SF040000 -251c SF080000 -2524 SF090000 -252c SF060000 -2534 SF070000 -253c SF050000 -2550 SF430000 -2551 SF240000 -2552 SF510000 -2553 SF520000 -2554 SF390000 -2555 SF220000 -2556 SF210000 -2557 SF250000 -2558 SF500000 -2559 SF490000 -255a SF380000 -255b SF280000 -255c SF270000 -255d SF260000 -255e SF360000 -255f SF370000 -2560 SF420000 -2561 SF190000 -2562 SF200000 -2563 SF230000 -2564 SF470000 -2565 SF480000 -2566 SF410000 -2567 SF450000 -2568 SF460000 -2569 SF400000 -256a SF540000 -256b SF530000 -256c SF440000 -2580 upblock -2584 dnblock -2588 block -258c lfblock -2590 rtblock -2591 ltshade -2592 shade -2593 dkshade -25a0 filledbox -25a1 H22073 -25aa H18543 -25ab H18551 -25ac filledrect -25b2 triagup -25ba triagrt -25bc triagdn -25c4 triaglf -25ca lozenge -25cb circle -25cf H18533 -25d8 invbullet -25d9 invcircle -25e6 openbullet -263a smileface -263b invsmileface -263c sun -2640 female -2642 male -2660 spade -2663 club -2665 heart -2666 diamond -266a musicalnote -266b musicalnotedbl -f6be dotlessj -f6bf LL -f6c0 ll -f6c1 Scedilla -f6c2 scedilla -f6c3 commaaccent -f6c4 afii10063 -f6c5 afii10064 -f6c6 afii10192 -f6c7 afii10831 -f6c8 afii10832 -f6c9 Acute -f6ca Caron -f6cb Dieresis -f6cc DieresisAcute -f6cd DieresisGrave -f6ce Grave -f6cf Hungarumlaut -f6d0 Macron -f6d1 cyrBreve -f6d2 cyrFlex -f6d3 dblGrave -f6d4 cyrbreve -f6d5 cyrflex -f6d6 dblgrave -f6d7 dieresisacute -f6d8 dieresisgrave -f6d9 copyrightserif -f6da registerserif -f6db trademarkserif -f6dc onefitted -f6dd rupiah -f6de threequartersemdash -f6df centinferior -f6e0 centsuperior -f6e1 commainferior -f6e2 commasuperior -f6e3 dollarinferior -f6e4 dollarsuperior -f6e5 hypheninferior -f6e6 hyphensuperior -f6e7 periodinferior -f6e8 periodsuperior -f6e9 asuperior -f6ea bsuperior -f6eb dsuperior -f6ec esuperior -f6ed isuperior -f6ee lsuperior -f6ef msuperior -f6f0 osuperior -f6f1 rsuperior -f6f2 ssuperior -f6f3 tsuperior -f6f4 Brevesmall -f6f5 Caronsmall -f6f6 Circumflexsmall -f6f7 Dotaccentsmall -f6f8 Hungarumlautsmall -f6f9 Lslashsmall -f6fa OEsmall -f6fb Ogoneksmall -f6fc Ringsmall -f6fd Scaronsmall -f6fe Tildesmall -f6ff Zcaronsmall -f721 exclamsmall -f724 dollaroldstyle -f726 ampersandsmall -f730 zerooldstyle -f731 oneoldstyle -f732 twooldstyle -f733 threeoldstyle -f734 fouroldstyle -f735 fiveoldstyle -f736 sixoldstyle -f737 sevenoldstyle -f738 eightoldstyle -f739 nineoldstyle -f73f questionsmall -f760 Gravesmall -f761 Asmall -f762 Bsmall -f763 Csmall -f764 Dsmall -f765 Esmall -f766 Fsmall -f767 Gsmall -f768 Hsmall -f769 Ismall -f76a Jsmall -f76b Ksmall -f76c Lsmall -f76d Msmall -f76e Nsmall -f76f Osmall -f770 Psmall -f771 Qsmall -f772 Rsmall -f773 Ssmall -f774 Tsmall -f775 Usmall -f776 Vsmall -f777 Wsmall -f778 Xsmall -f779 Ysmall -f77a Zsmall -f7a1 exclamdownsmall -f7a2 centoldstyle -f7a8 Dieresissmall -f7af Macronsmall -f7b4 Acutesmall -f7b8 Cedillasmall -f7bf questiondownsmall -f7e0 Agravesmall -f7e1 Aacutesmall -f7e2 Acircumflexsmall -f7e3 Atildesmall -f7e4 Adieresissmall -f7e5 Aringsmall -f7e6 AEsmall -f7e7 Ccedillasmall -f7e8 Egravesmall -f7e9 Eacutesmall -f7ea Ecircumflexsmall -f7eb Edieresissmall -f7ec Igravesmall -f7ed Iacutesmall -f7ee Icircumflexsmall -f7ef Idieresissmall -f7f0 Ethsmall -f7f1 Ntildesmall -f7f2 Ogravesmall -f7f3 Oacutesmall -f7f4 Ocircumflexsmall -f7f5 Otildesmall -f7f6 Odieresissmall -f7f8 Oslashsmall -f7f9 Ugravesmall -f7fa Uacutesmall -f7fb Ucircumflexsmall -f7fc Udieresissmall -f7fd Yacutesmall -f7fe Thornsmall -f7ff Ydieresissmall -f8e5 radicalex -f8e6 arrowvertex -f8e7 arrowhorizex -f8e8 registersans -f8e9 copyrightsans -f8ea trademarksans -f8eb parenlefttp -f8ec parenleftex -f8ed parenleftbt -f8ee bracketlefttp -f8ef bracketleftex -f8f0 bracketleftbt -f8f1 bracelefttp -f8f2 braceleftmid -f8f3 braceleftbt -f8f4 braceex -f8f5 integralex -f8f6 parenrighttp -f8f7 parenrightex -f8f8 parenrightbt -f8f9 bracketrighttp -f8fa bracketrightex -f8fb bracketrightbt -f8fc bracerighttp -f8fd bracerightmid -f8fe bracerightbt -fb00 ff -fb01 fi -fb02 fl -fb03 ffi -fb04 ffl -fb1f afii57705 -fb2a afii57694 -fb2b afii57695 -fb35 afii57723 -fb4b afii57700 diff --git a/data/utf-8 b/data/utf-8 deleted file mode 100644 index 044691b46..000000000 --- a/data/utf-8 +++ /dev/null @@ -1,40 +0,0 @@ -charset utf8 - -# -# This file defines the font mappings used for Unicode/UTF-8 text printing. -# -# Each line consists of: -# -# first last direction width normal bold italic bold-italic -# -# First and last are the first and last glyphs in the font mapping -# that correspond to that font; a maximum of 256 characters can be -# mapped within each group, with a maximum of 256 mappings (this is a -# PostScript limitation.) The glyph values are hexadecimal. -# -# Direction is the string "ltor" or "rtol", indicating left-to-right or -# right-to-left text. -# -# Width is the string "single" or "double"; double means that the glyphs -# are twice as wide as ASCII characters in the Monospace typeface. -# -# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use -# for each presentation. If characters are only available in a single -# style then only one typeface should be listed, e.g. -# -# 1000 10ff ltor single Monospace -# -# Each font that is listed will be downloaded to the printer when used. -# - -0000 00FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique -0100 01FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique -0200 02FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique -0300 03FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique -0400 04FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique -1E00 1EFF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique -2000 20FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique -2300 23FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique -2400 24FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique -2500 25FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique -2600 26FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique diff --git a/driver/Dependencies b/driver/Dependencies deleted file mode 100644 index 6730f13f5..000000000 --- a/driver/Dependencies +++ /dev/null @@ -1,75 +0,0 @@ -# DO NOT DELETE - -commandtoescpx.o: ../cups/cups-private.h ../cups/cups.h ../cups/file.h -commandtoescpx.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h -commandtoescpx.o: ../cups/array.h ../cups/language.h ../cups/string-private.h -commandtoescpx.o: ../config.h ../cups/debug-private.h ../cups/ppd-private.h -commandtoescpx.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h -commandtoescpx.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h -commandtoescpx.o: ../cups/ipp-private.h ../cups/ipp.h -commandtoescpx.o: ../cups/language-private.h ../cups/transcode.h -commandtoescpx.o: ../cups/thread-private.h driver.h ../cups/raster.h -commandtoescpx.o: ../cups/ppd.h ../data/escp.h -commandtopclx.o: ../cups/cups-private.h ../cups/cups.h ../cups/file.h -commandtopclx.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h -commandtopclx.o: ../cups/array.h ../cups/language.h ../cups/string-private.h -commandtopclx.o: ../config.h ../cups/debug-private.h ../cups/ppd-private.h -commandtopclx.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h -commandtopclx.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h -commandtopclx.o: ../cups/ipp-private.h ../cups/ipp.h -commandtopclx.o: ../cups/language-private.h ../cups/transcode.h -commandtopclx.o: ../cups/thread-private.h driver.h ../cups/raster.h -commandtopclx.o: ../cups/ppd.h ../data/pcl.h -rastertoescpx.o: driver.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -rastertoescpx.o: ../cups/ipp.h ../cups/http.h ../cups/array.h -rastertoescpx.o: ../cups/language.h ../cups/raster.h ../cups/cups.h -rastertoescpx.o: ../cups/ppd.h ../cups/language-private.h ../cups/transcode.h -rastertoescpx.o: ../cups/string-private.h ../config.h ../data/escp.h -rastertopclx.o: driver.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -rastertopclx.o: ../cups/ipp.h ../cups/http.h ../cups/array.h -rastertopclx.o: ../cups/language.h ../cups/raster.h ../cups/cups.h -rastertopclx.o: ../cups/ppd.h ../cups/language-private.h ../cups/transcode.h -rastertopclx.o: ../cups/string-private.h ../config.h pcl-common.h -rastertopclx.o: ../data/pcl.h -pcl-common.o: driver.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -pcl-common.o: ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -pcl-common.o: ../cups/raster.h ../cups/cups.h ../cups/ppd.h pcl-common.h -pcl-common.o: ../cups/string-private.h ../config.h ../data/pcl.h -testcmyk.o: ../cups/string-private.h ../config.h driver.h ../cups/cups.h -testcmyk.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -testcmyk.o: ../cups/array.h ../cups/language.h ../cups/raster.h -testcmyk.o: ../cups/cups.h ../cups/ppd.h -testdither.o: driver.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -testdither.o: ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -testdither.o: ../cups/raster.h ../cups/cups.h ../cups/ppd.h -testdither.o: ../cups/string-private.h ../config.h -testrgb.o: ../cups/string-private.h ../config.h driver.h ../cups/cups.h -testrgb.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -testrgb.o: ../cups/array.h ../cups/language.h ../cups/raster.h ../cups/cups.h -testrgb.o: ../cups/ppd.h -attr.o: driver.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -attr.o: ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -attr.o: ../cups/raster.h ../cups/cups.h ../cups/ppd.h -attr.o: ../cups/string-private.h ../config.h -check.o: driver.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -check.o: ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -check.o: ../cups/raster.h ../cups/cups.h ../cups/ppd.h -cmyk.o: driver.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -cmyk.o: ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -cmyk.o: ../cups/raster.h ../cups/cups.h ../cups/ppd.h -cmyk.o: ../cups/string-private.h ../config.h -dither.o: driver.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -dither.o: ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -dither.o: ../cups/raster.h ../cups/cups.h ../cups/ppd.h ../config.h -lut.o: driver.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -lut.o: ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -lut.o: ../cups/raster.h ../cups/cups.h ../cups/ppd.h -pack.o: driver.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -pack.o: ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -pack.o: ../cups/raster.h ../cups/cups.h ../cups/ppd.h -rgb.o: driver.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -rgb.o: ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -rgb.o: ../cups/raster.h ../cups/cups.h ../cups/ppd.h -srgb.o: driver.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -srgb.o: ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -srgb.o: ../cups/raster.h ../cups/cups.h ../cups/ppd.h diff --git a/driver/Makefile b/driver/Makefile deleted file mode 100644 index 21fdfe29c..000000000 --- a/driver/Makefile +++ /dev/null @@ -1,382 +0,0 @@ -# -# "$Id$" -# -# Makefile for the CUPS base drivers. -# -# Copyright 2007-2010 by Apple Inc. -# Copyright 2002-2005 by Easy Software Products. -# -# These coded instructions, statements, and computer programs are the -# property of Apple Inc. and are protected by Federal copyright -# law. Distribution and use rights are outlined in the file "LICENSE.txt" -# which should have been included with this file. If this file is -# file is missing or damaged, see the license at "http://www.cups.org/". -# - -# -# Include standard definitions... -# - -include ../Makedefs - - -# -# Object files... -# - -LIBOBJS = \ - attr.o \ - check.o \ - cmyk.o \ - dither.o \ - lut.o \ - pack.o \ - rgb.o \ - srgb.o -OBJS = \ - commandtoescpx.o \ - commandtopclx.o \ - rastertoescpx.o \ - rastertopclx.o \ - pcl-common.o \ - testcmyk.o \ - testdither.o \ - testrgb.o \ - $(LIBOBJS) - -LIBTARGETS = \ - $(LIBCUPSDRIVER) \ - libcupsdriver.a -UNITTARGETS = \ - testcmyk \ - testdither \ - testrgb -FILTERS = \ - commandtoescpx \ - commandtopclx \ - rastertoescpx \ - rastertopclx -TARGETS = \ - $(LIBTARGETS) \ - $(FILTERS) - - -# -# Make everything... -# - -all: $(TARGETS) - - -# -# Make library targets... -# - -libs: $(LIBTARGETS) - - -# -# Make unit tests... -# - -unittests: $(UNITTARGETS) - - -# -# Clean everything... -# - -clean: - $(RM) $(OBJS) core - $(RM) *.bck core.* - $(RM) $(TARGETS) $(UNITTARGETS) - $(RM) -r test - $(RM) libcupsdriver.so libcupsdriver.sl libcupsdriver.dylib - - -# -# Update dependencies... -# - -depend: - makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1 - - -# -# Install all targets... -# - -install: all install-data install-headers install-libs install-exec - - -# -# Install data files... -# - -install-data: - - -# -# Install programs... -# - -install-exec: - $(INSTALL_DIR) $(SERVERBIN)/filter - for file in $(FILTERS); do \ - $(INSTALL_BIN) $$file $(SERVERBIN)/filter; \ - done - if test "x$(SYMROOT)" != "x"; then \ - $(INSTALL_DIR) $(SYMROOT); \ - for file in $(FILTERS); do \ - cp $$file $(SYMROOT); \ - done \ - fi - - -# -# Install headers... -# - -install-headers: - echo Installing header files in $(INCLUDEDIR)/cups... - $(INSTALL_DIR) -m 755 $(INCLUDEDIR)/cups - $(INSTALL_DATA) driver.h $(INCLUDEDIR)/cups - - -# -# Install libraries... -# - -install-libs: $(INSTALLSTATIC) - echo Installing libraries in $(LIBDIR)... - $(INSTALL_DIR) -m 755 $(LIBDIR) - $(INSTALL_LIB) $(LIBCUPSDRIVER) $(LIBDIR) - if test $(LIBCUPSDRIVER) = "libcupsdriver.so.1" -o $(LIBCUPSDRIVER) = "libcupsdriver.sl.1"; then \ - $(RM) $(LIBDIR)/`basename $(LIBCUPSDRIVER) .1`; \ - $(LN) $(LIBCUPSDRIVER) $(LIBDIR)/`basename $(LIBCUPSDRIVER) .1`; \ - fi - if test $(LIBCUPSDRIVER) = "libcupsdriver.1.dylib"; then \ - $(RM) $(LIBDIR)/libcupsdriver.dylib; \ - $(LN) $(LIBCUPSDRIVER) $(LIBDIR)/libcupsdriver.dylib; \ - fi - if test "x$(SYMROOT)" != "x"; then \ - $(INSTALL_DIR) $(SYMROOT); \ - cp $(LIBCUPSDRIVER) $(SYMROOT); \ - fi - -installstatic: - $(INSTALL_DIR) -m 755 $(LIBDIR) - $(INSTALL_LIB) -m 755 libcupsdriver.a $(LIBDIR) - $(RANLIB) $(LIBDIR)/libcupsdriver.a - $(CHMOD) 555 $(LIBDIR)/libcupsdriver.a - - -# -# Uninstall... -# - -uninstall: - for file in commandtoescpx commandtopclx rastertoescpx rastertopclx; do \ - $(RM) $(SERVERBIN)/filter/$$file; \ - done - $(RM) $(LIBDIR)/libcupsdriver.1.dylib - $(RM) $(LIBDIR)/libcupsdriver.a - $(RM) $(LIBDIR)/libcupsdriver.dylib - $(RM) $(LIBDIR)/libcupsdriver_s.a - $(RM) $(LIBDIR)/libcupsdriver.sl - $(RM) $(LIBDIR)/libcupsdriver.sl.1 - $(RM) $(LIBDIR)/libcupsdriver.so - $(RM) $(LIBDIR)/libcupsdriver.so.1 - -$(RMDIR) $(LIBDIR) - $(RM) $(INCLUDEDIR)/cups/driver.h - -$(RMDIR) $(INCLUDEDIR)/cups - - -# -# Automatic API help files... -# - -apihelp: - mxmldoc --section "Programming" \ - --title "Printer Driver API" \ - --css ../doc/cups-printable.css \ - --header api-driver.header --intro api-driver.shtml \ - api-driver.xml \ - driver.h $(LIBOBJS:.o=.c) >../doc/help/api-driver.html - mxmldoc --tokens help/api-driver.html >../doc/help/api-driver.tokens - $(RM) api-driver.xml - -framedhelp: - mxmldoc --framed api-driver \ - --section "Programming" \ - --title "Printer Driver API" \ - --css ../doc/cups-printable.css \ - --header api-driver.header --intro api-driver.shtml \ - driver.h $(LIBOBJS:.o=.c) - - -# -# commandtopclx, the PCL command printer driver. -# - -commandtopclx: commandtopclx.o $(LIBCUPSDRIVER) ../cups/$(LIBCUPS) - echo Linking $@... - $(CC) $(LDFLAGS) -o $@ commandtopclx.o -L. -lcupsdriver $(LIBS) - - -# -# commandtoescpx, the ESC/P command printer driver. -# - -commandtoescpx: commandtoescpx.o $(LIBCUPSDRIVER) ../cups/$(LIBCUPS) - echo Linking $@... - $(CC) $(LDFLAGS) -o $@ commandtoescpx.o -L. -lcupsdriver $(LIBS) - - -# -# rastertoescpx, the ESC/P raster printer driver. -# - -rastertoescpx: rastertoescpx.o $(LIBCUPSDRIVER) ../cups/$(LIBCUPS) - echo Linking $@... - $(CC) $(LDFLAGS) -o $@ rastertoescpx.o -L. -lcupsdriver \ - $(LINKCUPSIMAGE) $(LIBS) - - -# -# rastertopclx, the ESC/P raster printer driver. -# - -rastertopclx: rastertopclx.o pcl-common.o $(LIBCUPSDRIVER) \ - ../cups/$(LIBCUPS) - echo Linking $@... - $(CC) $(LDFLAGS) -o $@ rastertopclx.o pcl-common.o -L. -lcupsdriver \ - $(LINKCUPSIMAGE) $(LIBS) - - -# -# test, make a common test subdirectory for the other test programs. -# - -test: - if test ! -d test; then \ - rm -rf test; \ - mkdir test; \ - fi - - -# -# testcmyk, test cmyk separation functions. -# - -testcmyk: test testcmyk.o libcupsdriver.a ../cups/$(LIBCUPSSTATIC) - echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testcmyk.o libcupsdriver.a \ - ../cups/$(LIBCUPSSTATIC) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ - $(COMMONLIBS) $(LIBZ) - echo Running CMYK API tests... - ./testcmyk > test/testcmyk.log - - -# -# testdither, test dithering functions. -# - -testdither: test testdither.o libcupsdriver.a ../cups/$(LIBCUPSSTATIC) - echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testdither.o libcupsdriver.a \ - ../cups/$(LIBCUPSSTATIC) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ - $(COMMONLIBS) $(LIBZ) - echo Running dither API tests... - ./testdither > test/0-255.pgm 2>test/0-255.log - ./testdither 0 127 255 > test/0-127-255.pgm 2>test/0-127-255.log - ./testdither 0 85 170 255 > test/0-85-170-255.pgm 2>test/0-85-170-255.log - ./testdither 0 63 127 170 198 227 255 > test/0-63-127-170-198-227-255.pgm 2>test/0-63-127-170-198-227-255.log - ./testdither 0 210 383 > test/0-210-383.pgm 2>test/0-210-383.log - ./testdither 0 82 255 > test/0-82-255.pgm 2>test/0-82-255.log - ./testdither 0 510 > test/0-510.pgm 2>test/0-510.log - ./testdither 0 1020 > test/0-1020.pgm 2>test/0-1020.log - - -# -# testrgb, test RGB separation functions. -# - -testrgb: test testrgb.o libcupsdriver.a ../cups/$(LIBCUPSSTATIC) - echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testrgb.o libcupsdriver.a \ - ../cups/$(LIBCUPSSTATIC) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ - $(COMMONLIBS) $(LIBZ) - echo Running RGB API tests... - ./testrgb > test/testrgb.log 2>&1 || echo "RGB tests failed!" - - -# -# libcupsdriver.so.1, libcupsdriver.sl.1 -# - -libcupsdriver.so.1 libcupsdriver.sl.1: $(LIBOBJS) - echo Linking $@... - $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LIBS) - $(RM) `basename $@ .1` - $(LN) $@ `basename $@ .1` - - -# -# libcupsdriver.1.dylib -# - -libcupsdriver.1.dylib: $(LIBOBJS) libcupsdriver.exp - echo Linking $@... - $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \ - -install_name $(libdir)/$@ \ - -current_version 1.0.0 \ - -compatibility_version 1.0.0 \ - -exported_symbols_list libcupsdriver.exp \ - $(LIBOBJS) $(LIBS) - $(RM) libcupsdriver.dylib - $(LN) $@ libcupsdriver.dylib - - -# -# libcupsdriver_s.a -# - -libcupsdriver_s.a: $(LIBOBJS) - echo Creating $@... - $(DSO) $(DSOFLAGS) -o libcupsdriver_s.o $(LIBOBJS) $(LIBS) - $(RM) $@ - $(AR) $(ARFLAGS) $@ libcupsdriver_s.o - - -# -# libcupsdriver.la -# - -libcupsdriver.la: $(LIBOBJS) - echo Linking $@... - $(CC) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS:.o=.lo) -rpath $(LIBDIR) \ - -version-info 1:0 $(LIBS) - - -# -# libcupsdriver.a -# - -libcupsdriver.a: $(LIBOBJS) - echo Archiving $@... - $(RM) $@ - $(AR) $(ARFLAGS) $@ $(LIBOBJS) - $(RANLIB) $@ - - -# -# Include dependencies... -# - -include Dependencies - - -# -# End of "$Id$". -# diff --git a/driver/api-driver.header b/driver/api-driver.header deleted file mode 100644 index 0f3937bc1..000000000 --- a/driver/api-driver.header +++ /dev/null @@ -1,34 +0,0 @@ - - -

Driver API

- -
- - - - - - - - - - - - - - - - -
Headercups/driver.h
Library-lcupsdriver
See AlsoProgramming: Introduction to CUPS Programming
diff --git a/driver/api-driver.shtml b/driver/api-driver.shtml deleted file mode 100644 index 0e8bcff27..000000000 --- a/driver/api-driver.shtml +++ /dev/null @@ -1,18 +0,0 @@ - - -

Overview

- -

The driver API provides common dithering, color conversion, and utility -functions for CUPS drivers.

diff --git a/driver/attr.c b/driver/attr.c deleted file mode 100644 index 4eba32417..000000000 --- a/driver/attr.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * "$Id$" - * - * PPD attribute lookup routine for CUPS. - * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * cupsFindAttr() - Find a PPD attribute based on the colormodel, - * media, and resolution. - */ - -/* - * Include necessary headers. - */ - -#include "driver.h" -#include - - -/* - * 'cupsFindAttr()' - Find a PPD attribute based on the colormodel, - * media, and resolution. - */ - -ppd_attr_t * /* O - Matching attribute or NULL */ -cupsFindAttr(ppd_file_t *ppd, /* I - PPD file */ - const char *name, /* I - Attribute name */ - const char *colormodel, /* I - Color model */ - const char *media, /* I - Media type */ - const char *resolution, /* I - Resolution */ - char *spec, /* O - Final selection string */ - int specsize) /* I - Size of string buffer */ -{ - ppd_attr_t *attr; /* Attribute */ - - - /* - * Range check input... - */ - - if (!ppd || !name || !colormodel || !media || !resolution || !spec || - specsize < PPD_MAX_NAME) - return (NULL); - - /* - * Look for the attribute with the following keywords: - * - * ColorModel.MediaType.Resolution - * ColorModel.Resolution - * ColorModel - * MediaType.Resolution - * MediaType - * Resolution - * "" - */ - - snprintf(spec, specsize, "%s.%s.%s", colormodel, media, resolution); - fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec); - if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL) - return (attr); - - snprintf(spec, specsize, "%s.%s", colormodel, resolution); - fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec); - if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL) - return (attr); - - strlcpy(spec, colormodel, specsize); - fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec); - if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL) - return (attr); - - snprintf(spec, specsize, "%s.%s", media, resolution); - fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec); - if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL) - return (attr); - - strlcpy(spec, media, specsize); - fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec); - if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL) - return (attr); - - strlcpy(spec, resolution, specsize); - fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec); - if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL) - return (attr); - - spec[0] = '\0'; - fprintf(stderr, "DEBUG2: Looking for \"*%s\"...\n", name); - if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL) - return (attr); - - fprintf(stderr, "DEBUG2: No instance of \"*%s\" found...\n", name); - - return (NULL); -} - - -/* - * End of "$Id$". - */ diff --git a/driver/check.c b/driver/check.c deleted file mode 100644 index d7ceb3d44..000000000 --- a/driver/check.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * "$Id$" - * - * Byte checking routines for CUPS. - * - * Copyright 2007 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * cupsCheckBytes() - Check to see if all bytes are zero. - * cupsCheckValue() - Check to see if all bytes match the given value. - */ - -/* - * Include necessary headers. - */ - -#include "driver.h" - - -/* - * 'cupsCheckBytes()' - Check to see if all bytes are zero. - */ - -int /* O - 1 if they match */ -cupsCheckBytes(const unsigned char *bytes, /* I - Bytes to check */ - int length) /* I - Number of bytes to check */ -{ - while (length > 7) - { - if (*bytes++) - return (0); - if (*bytes++) - return (0); - if (*bytes++) - return (0); - if (*bytes++) - return (0); - if (*bytes++) - return (0); - if (*bytes++) - return (0); - if (*bytes++) - return (0); - if (*bytes++) - return (0); - - length -= 8; - } - - while (length > 0) - if (*bytes++) - return (0); - else - length --; - - return (1); -} - - -/* - * 'cupsCheckValue()' - Check to see if all bytes match the given value. - */ - -int /* O - 1 if they match */ -cupsCheckValue(const unsigned char *bytes, /* I - Bytes to check */ - int length, /* I - Number of bytes to check */ - const unsigned char value) /* I - Value to check */ -{ - while (length > 7) - { - if (*bytes++ != value) - return (0); - if (*bytes++ != value) - return (0); - if (*bytes++ != value) - return (0); - if (*bytes++ != value) - return (0); - if (*bytes++ != value) - return (0); - if (*bytes++ != value) - return (0); - if (*bytes++ != value) - return (0); - if (*bytes++ != value) - return (0); - - length -= 8; - } - - while (length > 0) - if (*bytes++ != value) - return (0); - else - length --; - - return (1); -} - - -/* - * End of "$Id$". - */ diff --git a/driver/cmyk.c b/driver/cmyk.c deleted file mode 100644 index c6c350c24..000000000 --- a/driver/cmyk.c +++ /dev/null @@ -1,1955 +0,0 @@ -/* - * "$Id$" - * - * CMYK color separation code for CUPS. - * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * cupsCMYKDelete() - Delete a color separation. - * cupsCMYKDoBlack() - Do a black separation... - * cupsCMYKDoCMYK() - Do a CMYK separation... - * cupsCMYKDoGray() - Do a grayscale separation... - * cupsCMYKDoRGB() - Do an sRGB separation... - * cupsCMYKLoad() - Load a CMYK color profile from PPD attributes. - * cupsCMYKNew() - Create a new CMYK color separation. - * cupsCMYKSetBlack() - Set the transition range for CMY to black. - * cupsCMYKSetCurve() - Set a color transform curve using points. - * cupsCMYKSetGamma() - Set a color transform curve using gamma and - * density. - * cupsCMYKSetInkLimit() - Set the limit on the amount of ink. - * cupsCMYKSetLtDk() - Set light/dark ink transforms. - */ - -/* - * Include necessary headers. - */ - -#include "driver.h" -#include - - -/* - * 'cupsCMYKDelete()' - Delete a color separation. - */ - -void -cupsCMYKDelete(cups_cmyk_t *cmyk) /* I - Color separation */ -{ - /* - * Range check input... - */ - - if (cmyk == NULL) - return; - - /* - * Free memory used... - */ - - free(cmyk->channels[0]); - free(cmyk); -} - - -/* - * 'cupsCMYKDoBlack()' - Do a black separation... - */ - -void -cupsCMYKDoBlack(const cups_cmyk_t *cmyk, - /* I - Color separation */ - const unsigned char *input, - /* I - Input grayscale pixels */ - short *output, - /* O - Output Device-N pixels */ - int num_pixels) - /* I - Number of pixels */ -{ - int k; /* Current black value */ - const short **channels; /* Copy of channel LUTs */ - int ink, /* Amount of ink */ - ink_limit; /* Ink limit from separation */ - - - /* - * Range check input... - */ - - if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0) - return; - - /* - * Loop through it all... - */ - - channels = (const short **)cmyk->channels; - ink_limit = cmyk->ink_limit; - - switch (cmyk->num_channels) - { - case 1 : /* Black */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - k = *input++; - *output++ = channels[0][k]; - - num_pixels --; - } - break; - - case 2 : /* Black, light black */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - k = *input++; - output[0] = channels[0][k]; - output[1] = channels[1][k]; - - if (ink_limit) - { - ink = output[0] + output[1]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - } - } - - output += 2; - num_pixels --; - } - break; - - case 3 : /* CMY */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - k = *input++; - output[0] = channels[0][k]; - output[1] = channels[1][k]; - output[2] = channels[2][k]; - - if (ink_limit) - { - ink = output[0] + output[1] + output[2]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - output[2] = ink_limit * output[2] / ink; - } - } - - output += 3; - num_pixels --; - } - break; - - case 4 : /* CMYK */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - k = *input++; - *output++ = 0; - *output++ = 0; - *output++ = 0; - *output++ = channels[3][k]; - - num_pixels --; - } - break; - - case 6 : /* CcMmYK */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - k = *input++; - *output++ = 0; - *output++ = 0; - *output++ = 0; - *output++ = 0; - *output++ = 0; - *output++ = channels[5][k]; - - num_pixels --; - } - break; - - case 7 : /* CcMmYKk */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - k = *input++; - output[0] = 0; - output[1] = 0; - output[2] = 0; - output[3] = 0; - output[4] = 0; - output[5] = channels[5][k]; - output[6] = channels[6][k]; - - if (ink_limit) - { - ink = output[5] + output[6]; - - if (ink > ink_limit) - { - output[5] = ink_limit * output[5] / ink; - output[6] = ink_limit * output[6] / ink; - } - } - - output += 7; - num_pixels --; - } - break; - } -} - - -/* - * 'cupsCMYKDoCMYK()' - Do a CMYK separation... - */ - -void -cupsCMYKDoCMYK(const cups_cmyk_t *cmyk, - /* I - Color separation */ - const unsigned char *input, - /* I - Input grayscale pixels */ - short *output, - /* O - Output Device-N pixels */ - int num_pixels) - /* I - Number of pixels */ -{ - int c, /* Current cyan value */ - m, /* Current magenta value */ - y, /* Current yellow value */ - k; /* Current black value */ - const short **channels; /* Copy of channel LUTs */ - int ink, /* Amount of ink */ - ink_limit; /* Ink limit from separation */ - - - /* - * Range check input... - */ - - if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0) - return; - - /* - * Loop through it all... - */ - - channels = (const short **)cmyk->channels; - ink_limit = cmyk->ink_limit; - - switch (cmyk->num_channels) - { - case 1 : /* Black */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - c = *input++; - m = *input++; - y = *input++; - k = *input++ + (c * 31 + m * 61 + y * 8) / 100; - - if (k < 255) - *output++ = channels[0][k]; - else - *output++ = channels[0][255]; - - num_pixels --; - } - break; - - case 2 : /* Black, light black */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - c = *input++; - m = *input++; - y = *input++; - k = *input++ + (c * 31 + m * 61 + y * 8) / 100; - - if (k < 255) - { - output[0] = channels[0][k]; - output[1] = channels[1][k]; - } - else - { - output[0] = channels[0][255]; - output[1] = channels[1][255]; - } - - if (ink_limit) - { - ink = output[0] + output[1]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - } - } - - output += 2; - num_pixels --; - } - break; - - case 3 : /* CMY */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - c = *input++; - m = *input++; - y = *input++; - k = *input++; - c += k; - m += k; - y += k; - - if (c < 255) - output[0] = channels[0][c]; - else - output[0] = channels[0][255]; - - if (m < 255) - output[1] = channels[1][m]; - else - output[1] = channels[1][255]; - - if (y < 255) - output[2] = channels[2][y]; - else - output[2] = channels[2][255]; - - if (ink_limit) - { - ink = output[0] + output[1] + output[2]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - output[2] = ink_limit * output[2] / ink; - } - } - - output += 3; - num_pixels --; - } - break; - - case 4 : /* CMYK */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - c = *input++; - m = *input++; - y = *input++; - k = *input++; - - output[0] = channels[0][c]; - output[1] = channels[1][m]; - output[2] = channels[2][y]; - output[3] = channels[3][k]; - - if (ink_limit) - { - ink = output[0] + output[1] + output[2] + output[3]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - output[2] = ink_limit * output[2] / ink; - output[3] = ink_limit * output[3] / ink; - } - } - - output += 4; - num_pixels --; - } - break; - - case 6 : /* CcMmYK */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - c = *input++; - m = *input++; - y = *input++; - k = *input++; - - output[0] = channels[0][c]; - output[1] = channels[1][c]; - output[2] = channels[2][m]; - output[3] = channels[3][m]; - output[4] = channels[4][y]; - output[5] = channels[5][k]; - - if (ink_limit) - { - ink = output[0] + output[1] + output[2] + output[3] + - output[4] + output[5]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - output[2] = ink_limit * output[2] / ink; - output[3] = ink_limit * output[3] / ink; - output[4] = ink_limit * output[4] / ink; - output[5] = ink_limit * output[5] / ink; - } - } - - output += 6; - num_pixels --; - } - break; - - case 7 : /* CcMmYKk */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - c = *input++; - m = *input++; - y = *input++; - k = *input++; - - output[0] = channels[0][c]; - output[1] = channels[1][c]; - output[2] = channels[2][m]; - output[3] = channels[3][m]; - output[4] = channels[4][y]; - output[5] = channels[5][k]; - output[6] = channels[6][k]; - - if (ink_limit) - { - ink = output[0] + output[1] + output[2] + output[3] + - output[4] + output[5] + output[6]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - output[2] = ink_limit * output[2] / ink; - output[3] = ink_limit * output[3] / ink; - output[4] = ink_limit * output[4] / ink; - output[5] = ink_limit * output[5] / ink; - output[6] = ink_limit * output[6] / ink; - } - } - - output += 7; - num_pixels --; - } - break; - } -} - - -/* - * 'cupsCMYKDoGray()' - Do a grayscale separation... - */ - -void -cupsCMYKDoGray(const cups_cmyk_t *cmyk, - /* I - Color separation */ - const unsigned char *input, - /* I - Input grayscale pixels */ - short *output, - /* O - Output Device-N pixels */ - int num_pixels) - /* I - Number of pixels */ -{ - int k, /* Current black value */ - kc; /* Current black color value */ - const short **channels; /* Copy of channel LUTs */ - int ink, /* Amount of ink */ - ink_limit; /* Ink limit from separation */ - - - /* - * Range check input... - */ - - if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0) - return; - - /* - * Loop through it all... - */ - - channels = (const short **)cmyk->channels; - ink_limit = cmyk->ink_limit; - - switch (cmyk->num_channels) - { - case 1 : /* Black */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - k = cups_scmy_lut[*input++]; - *output++ = channels[0][k]; - - num_pixels --; - } - break; - - case 2 : /* Black, light black */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - k = cups_scmy_lut[*input++]; - output[0] = channels[0][k]; - output[1] = channels[1][k]; - - if (ink_limit) - { - ink = output[0] + output[1]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - } - } - - output += 2; - num_pixels --; - } - break; - - case 3 : /* CMY */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - k = cups_scmy_lut[*input++]; - output[0] = channels[0][k]; - output[1] = channels[1][k]; - output[2] = channels[2][k]; - - if (ink_limit) - { - ink = output[0] + output[1] + output[2]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - output[2] = ink_limit * output[2] / ink; - } - } - - output += 3; - num_pixels --; - } - break; - - case 4 : /* CMYK */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - k = cups_scmy_lut[*input++]; - kc = cmyk->color_lut[k]; - k = cmyk->black_lut[k]; - output[0] = channels[0][kc]; - output[1] = channels[1][kc]; - output[2] = channels[2][kc]; - output[3] = channels[3][k]; - - if (ink_limit) - { - ink = output[0] + output[1] + output[2] + output[3]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - output[2] = ink_limit * output[2] / ink; - output[3] = ink_limit * output[3] / ink; - } - } - - output += 4; - num_pixels --; - } - break; - - case 6 : /* CcMmYK */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - k = cups_scmy_lut[*input++]; - kc = cmyk->color_lut[k]; - k = cmyk->black_lut[k]; - output[0] = channels[0][kc]; - output[1] = channels[1][kc]; - output[2] = channels[2][kc]; - output[3] = channels[3][kc]; - output[4] = channels[4][kc]; - output[5] = channels[5][k]; - - if (ink_limit) - { - ink = output[0] + output[1] + output[2] + output[3] + - output[4] + output[5]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - output[2] = ink_limit * output[2] / ink; - output[3] = ink_limit * output[3] / ink; - output[4] = ink_limit * output[4] / ink; - output[5] = ink_limit * output[5] / ink; - } - } - - output += 6; - num_pixels --; - } - break; - - case 7 : /* CcMmYKk */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - k = cups_scmy_lut[*input++]; - kc = cmyk->color_lut[k]; - k = cmyk->black_lut[k]; - output[0] = channels[0][kc]; - output[1] = channels[1][kc]; - output[2] = channels[2][kc]; - output[3] = channels[3][kc]; - output[4] = channels[4][kc]; - output[5] = channels[5][k]; - output[6] = channels[6][k]; - - if (ink_limit) - { - ink = output[0] + output[1] + output[2] + output[3] + - output[4] + output[5] + output[6]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - output[2] = ink_limit * output[2] / ink; - output[3] = ink_limit * output[3] / ink; - output[4] = ink_limit * output[4] / ink; - output[5] = ink_limit * output[5] / ink; - output[6] = ink_limit * output[6] / ink; - } - } - - output += 7; - num_pixels --; - } - break; - } -} - - -/* - * 'cupsCMYKDoRGB()' - Do an sRGB separation... - */ - -void -cupsCMYKDoRGB(const cups_cmyk_t *cmyk, - /* I - Color separation */ - const unsigned char *input, - /* I - Input grayscale pixels */ - short *output, - /* O - Output Device-N pixels */ - int num_pixels) - /* I - Number of pixels */ -{ - int c, /* Current cyan value */ - m, /* Current magenta value */ - y, /* Current yellow value */ - k, /* Current black value */ - kc, /* Current black color value */ - km; /* Maximum black value */ - const short **channels; /* Copy of channel LUTs */ - int ink, /* Amount of ink */ - ink_limit; /* Ink limit from separation */ - - - /* - * Range check input... - */ - - if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0) - return; - - /* - * Loop through it all... - */ - - channels = (const short **)cmyk->channels; - ink_limit = cmyk->ink_limit; - - switch (cmyk->num_channels) - { - case 1 : /* Black */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - c = cups_scmy_lut[*input++]; - m = cups_scmy_lut[*input++]; - y = cups_scmy_lut[*input++]; - k = (c * 31 + m * 61 + y * 8) / 100; - - *output++ = channels[0][k]; - - num_pixels --; - } - break; - - case 2 : /* Black, light black */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - c = cups_scmy_lut[*input++]; - m = cups_scmy_lut[*input++]; - y = cups_scmy_lut[*input++]; - k = (c * 31 + m * 61 + y * 8) / 100; - - output[0] = channels[0][k]; - output[1] = channels[1][k]; - - if (ink_limit) - { - ink = output[0] + output[1]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - } - } - - output += 2; - num_pixels --; - } - break; - - case 3 : /* CMY */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - c = cups_scmy_lut[*input++]; - m = cups_scmy_lut[*input++]; - y = cups_scmy_lut[*input++]; - - output[0] = channels[0][c]; - output[1] = channels[1][m]; - output[2] = channels[2][y]; - - if (ink_limit) - { - ink = output[0] + output[1] + output[2]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - output[2] = ink_limit * output[2] / ink; - } - } - - output += 3; - num_pixels --; - } - break; - - case 4 : /* CMYK */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - c = cups_scmy_lut[*input++]; - m = cups_scmy_lut[*input++]; - y = cups_scmy_lut[*input++]; - k = min(c, min(m, y)); - - if ((km = max(c, max(m, y))) > k) - k = k * k * k / (km * km); - - kc = cmyk->color_lut[k] - k; - k = cmyk->black_lut[k]; - c += kc; - m += kc; - y += kc; - - output[0] = channels[0][c]; - output[1] = channels[1][m]; - output[2] = channels[2][y]; - output[3] = channels[3][k]; - - if (ink_limit) - { - ink = output[0] + output[1] + output[2] + output[3]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - output[2] = ink_limit * output[2] / ink; - output[3] = ink_limit * output[3] / ink; - } - } - - output += 4; - num_pixels --; - } - break; - - case 6 : /* CcMmYK */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - c = cups_scmy_lut[*input++]; - m = cups_scmy_lut[*input++]; - y = cups_scmy_lut[*input++]; - k = min(c, min(m, y)); - - if ((km = max(c, max(m, y))) > k) - k = k * k * k / (km * km); - - kc = cmyk->color_lut[k] - k; - k = cmyk->black_lut[k]; - c += kc; - m += kc; - y += kc; - - output[0] = channels[0][c]; - output[1] = channels[1][c]; - output[2] = channels[2][m]; - output[3] = channels[3][m]; - output[4] = channels[4][y]; - output[5] = channels[5][k]; - - if (ink_limit) - { - ink = output[0] + output[1] + output[2] + output[3] + - output[4] + output[5]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - output[2] = ink_limit * output[2] / ink; - output[3] = ink_limit * output[3] / ink; - output[4] = ink_limit * output[4] / ink; - output[5] = ink_limit * output[5] / ink; - } - } - - output += 6; - num_pixels --; - } - break; - - case 7 : /* CcMmYKk */ - while (num_pixels > 0) - { - /* - * Get the input black value and then set the corresponding color - * channel values... - */ - - c = cups_scmy_lut[*input++]; - m = cups_scmy_lut[*input++]; - y = cups_scmy_lut[*input++]; - k = min(c, min(m, y)); - - if ((km = max(c, max(m, y))) > k) - k = k * k * k / (km * km); - - kc = cmyk->color_lut[k] - k; - k = cmyk->black_lut[k]; - c += kc; - m += kc; - y += kc; - - output[0] = channels[0][c]; - output[1] = channels[1][c]; - output[2] = channels[2][m]; - output[3] = channels[3][m]; - output[4] = channels[4][y]; - output[5] = channels[5][k]; - output[6] = channels[6][k]; - - if (ink_limit) - { - ink = output[0] + output[1] + output[2] + output[3] + - output[4] + output[5] + output[6]; - - if (ink > ink_limit) - { - output[0] = ink_limit * output[0] / ink; - output[1] = ink_limit * output[1] / ink; - output[2] = ink_limit * output[2] / ink; - output[3] = ink_limit * output[3] / ink; - output[4] = ink_limit * output[4] / ink; - output[5] = ink_limit * output[5] / ink; - output[6] = ink_limit * output[6] / ink; - } - } - - output += 7; - num_pixels --; - } - break; - } -} - - -/* - * 'cupsCMYKLoad()' - Load a CMYK color profile from PPD attributes. - */ - -cups_cmyk_t * /* O - CMYK color separation */ -cupsCMYKLoad(ppd_file_t *ppd, /* I - PPD file */ - const char *colormodel, /* I - ColorModel value */ - const char *media, /* I - MediaType value */ - const char *resolution) /* I - Resolution value */ -{ - cups_cmyk_t *cmyk; /* CMYK color separation */ - char spec[PPD_MAX_NAME]; /* Profile name */ - ppd_attr_t *attr; /* Attribute from PPD file */ - int num_channels; /* Number of color components */ - float gamval, /* Gamma correction value */ - density, /* Density value */ - light, /* Light ink limit */ - dark, /* Light ink cut-off */ - lower, /* Start of black ink */ - upper; /* End of color ink */ - int num_xypoints; /* Number of X,Y points */ - float xypoints[100 * 2], /* X,Y points */ - *xyptr; /* Current X,Y point */ - - - /* - * Range check input... - */ - - if (ppd == NULL || colormodel == NULL || resolution == NULL || media == NULL) - return (NULL); - - /* - * Find the following attributes: - * - * cupsAllGamma - Set default curve using gamma + density - * cupsAllXY - Set default curve using XY points - * cupsBlackGamma - Set black curve using gamma + density - * cupsBlackGeneration - Set black generation - * cupsBlackLightDark - Set black light/dark transition - * cupsBlackXY - Set black curve using XY points - * cupsCyanGamma - Set cyan curve using gamma + density - * cupsCyanLightDark - Set cyan light/dark transition - * cupsCyanXY - Set cyan curve using XY points - * cupsInkChannels - Set number of color channels - * cupsInkLimit - Set total ink limit - * cupsLightBlackGamma - Set light black curve using gamma + density - * cupsLightBlackXY - Set light black curve using XY points - * cupsLightCyanGamma - Set light cyan curve using gamma + density - * cupsLightCyanXY - Set light cyan curve using XY points - * cupsLightMagentaGamma - Set light magenta curve using gamma + density - * cupsLightMagentaXY - Set light magenta curve using XY points - * cupsMagentaGamma - Set magenta curve using gamma + density - * cupsMagentaLightDark - Set magenta light/dark transition - * cupsMagentaXY - Set magenta curve using XY points - * cupsYellowGamma - Set yellow curve using gamma + density - * cupsYellowXY - Set yellow curve using XY points - * - * The only required attribute is cupsInkChannels. - * - * The *XY attributes have precedence over the *Gamma attributes, and - * the *Light* attributes have precedence over the corresponding - * *LightDark* attributes. - */ - - /* - * Get the required cupsInkChannels attribute... - */ - - if ((attr = cupsFindAttr(ppd, "cupsInkChannels", colormodel, media, - resolution, spec, sizeof(spec))) == NULL) - return (NULL); - - num_channels = atoi(attr->value); - - if (num_channels < 1 || num_channels > 7 || num_channels == 5) - return (NULL); - - if ((cmyk = cupsCMYKNew(num_channels)) == NULL) - return (NULL); - - /* - * Get the optional cupsInkLimit attribute... - */ - - if ((attr = cupsFindAttr(ppd, "cupsInkLimit", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - cupsCMYKSetInkLimit(cmyk, atof(attr->value)); - - /* - * Get the optional cupsBlackGeneration attribute... - */ - - if ((attr = cupsFindAttr(ppd, "cupsBlackGeneration", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - if (sscanf(attr->value, "%f%f", &lower, &upper) == 2) - cupsCMYKSetBlack(cmyk, lower, upper); - } - - /* - * Get the optional cupsBlackXY or cupsBlackGamma attributes... - */ - - if (num_channels != 3) - { - if ((attr = cupsFindAttr(ppd, "cupsBlackXY", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - for (num_xypoints = 0, xyptr = xypoints; - attr != NULL && attr->value != NULL && num_xypoints < 100; - attr = ppdFindNextAttr(ppd, "cupsBlackXY", spec)) - if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) - { - num_xypoints ++; - xyptr += 2; - } - - switch (num_channels) - { - case 1 : - case 2 : - cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints); - break; - case 4 : - cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints); - break; - case 6 : - case 7 : - cupsCMYKSetCurve(cmyk, 5, num_xypoints, xypoints); - break; - } - } - else if ((attr = cupsFindAttr(ppd, "cupsBlackGamma", colormodel, - media, resolution, spec, - sizeof(spec))) != NULL) - { - if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) - switch (num_channels) - { - case 1 : - case 2 : - cupsCMYKSetGamma(cmyk, 0, gamval, density); - break; - case 4 : - cupsCMYKSetGamma(cmyk, 3, gamval, density); - break; - case 6 : - case 7 : - cupsCMYKSetGamma(cmyk, 5, gamval, density); - break; - } - } - else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - for (num_xypoints = 0, xyptr = xypoints; - attr != NULL && attr->value != NULL && num_xypoints < 100; - attr = ppdFindNextAttr(ppd, "cupsAllXY", spec)) - if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) - { - num_xypoints ++; - xyptr += 2; - } - - switch (num_channels) - { - case 1 : - case 2 : - cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints); - break; - case 4 : - cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints); - break; - case 6 : - case 7 : - cupsCMYKSetCurve(cmyk, 5, num_xypoints, xypoints); - break; - } - } - else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, - media, resolution, spec, - sizeof(spec))) != NULL && - num_channels != 3) - { - if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) - switch (num_channels) - { - case 1 : - case 2 : - cupsCMYKSetGamma(cmyk, 0, gamval, density); - break; - case 4 : - cupsCMYKSetGamma(cmyk, 3, gamval, density); - break; - case 6 : - case 7 : - cupsCMYKSetGamma(cmyk, 5, gamval, density); - break; - } - } - } - - if (num_channels > 2) - { - /* - * Get the optional cupsCyanXY or cupsCyanGamma attributes... - */ - - if ((attr = cupsFindAttr(ppd, "cupsCyanXY", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - for (num_xypoints = 0, xyptr = xypoints; - attr != NULL && attr->value != NULL && num_xypoints < 100; - attr = ppdFindNextAttr(ppd, "cupsCyanXY", spec)) - if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) - { - num_xypoints ++; - xyptr += 2; - } - - cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints); - } - else if ((attr = cupsFindAttr(ppd, "cupsCyanGamma", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) - cupsCMYKSetGamma(cmyk, 0, gamval, density); - } - else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - for (num_xypoints = 0, xyptr = xypoints; - attr != NULL && attr->value != NULL && num_xypoints < 100; - attr = ppdFindNextAttr(ppd, "cupsAllXY", spec)) - if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) - { - num_xypoints ++; - xyptr += 2; - } - - cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints); - } - else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) - cupsCMYKSetGamma(cmyk, 0, gamval, density); - } - - /* - * Get the optional cupsMagentaXY or cupsMagentaGamma attributes... - */ - - if ((attr = cupsFindAttr(ppd, "cupsMagentaXY", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - for (num_xypoints = 0, xyptr = xypoints; - attr != NULL && attr->value != NULL && num_xypoints < 100; - attr = ppdFindNextAttr(ppd, "cupsMagentaXY", spec)) - if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) - { - num_xypoints ++; - xyptr += 2; - } - - switch (num_channels) - { - case 3 : - case 4 : - cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints); - break; - case 6 : - case 7 : - cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints); - break; - } - } - else if ((attr = cupsFindAttr(ppd, "cupsMagentaGamma", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) - switch (num_channels) - { - case 3 : - case 4 : - cupsCMYKSetGamma(cmyk, 1, gamval, density); - break; - case 6 : - case 7 : - cupsCMYKSetGamma(cmyk, 2, gamval, density); - break; - } - } - else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - for (num_xypoints = 0, xyptr = xypoints; - attr != NULL && attr->value != NULL && num_xypoints < 100; - attr = ppdFindNextAttr(ppd, "cupsAllXY", spec)) - if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) - { - num_xypoints ++; - xyptr += 2; - } - - switch (num_channels) - { - case 3 : - case 4 : - cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints); - break; - case 6 : - case 7 : - cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints); - break; - } - } - else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) - switch (num_channels) - { - case 3 : - case 4 : - cupsCMYKSetGamma(cmyk, 1, gamval, density); - break; - case 6 : - case 7 : - cupsCMYKSetGamma(cmyk, 2, gamval, density); - break; - } - } - - /* - * Get the optional cupsYellowXY or cupsYellowGamma attributes... - */ - - if ((attr = cupsFindAttr(ppd, "cupsYellowXY", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - for (num_xypoints = 0, xyptr = xypoints; - attr != NULL && attr->value != NULL && num_xypoints < 100; - attr = ppdFindNextAttr(ppd, "cupsYellowXY", spec)) - if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) - { - num_xypoints ++; - xyptr += 2; - } - - switch (num_channels) - { - case 3 : - case 4 : - cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints); - break; - case 6 : - case 7 : - cupsCMYKSetCurve(cmyk, 4, num_xypoints, xypoints); - break; - } - } - else if ((attr = cupsFindAttr(ppd, "cupsYellowGamma", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) - switch (num_channels) - { - case 3 : - case 4 : - cupsCMYKSetGamma(cmyk, 2, gamval, density); - break; - case 6 : - case 7 : - cupsCMYKSetGamma(cmyk, 4, gamval, density); - break; - } - } - else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - for (num_xypoints = 0, xyptr = xypoints; - attr != NULL && attr->value != NULL && num_xypoints < 100; - attr = ppdFindNextAttr(ppd, "cupsAllXY", spec)) - if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) - { - num_xypoints ++; - xyptr += 2; - } - - switch (num_channels) - { - case 3 : - case 4 : - cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints); - break; - case 6 : - case 7 : - cupsCMYKSetCurve(cmyk, 4, num_xypoints, xypoints); - break; - } - } - else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) - switch (num_channels) - { - case 3 : - case 4 : - cupsCMYKSetGamma(cmyk, 2, gamval, density); - break; - case 6 : - case 7 : - cupsCMYKSetGamma(cmyk, 4, gamval, density); - break; - } - } - } - - /* - * Get the optional cupsLightBlackXY, cupsLightBlackGamma, or - * cupsBlackLtDk attributes... - */ - - if (num_channels == 2 || num_channels == 7) - { - if ((attr = cupsFindAttr(ppd, "cupsLightBlackXY", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - for (num_xypoints = 0, xyptr = xypoints; - attr != NULL && attr->value != NULL && num_xypoints < 100; - attr = ppdFindNextAttr(ppd, "cupsLightBlackXY", spec)) - if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) - { - num_xypoints ++; - xyptr += 2; - } - - switch (num_channels) - { - case 2 : - cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints); - break; - case 7 : - cupsCMYKSetCurve(cmyk, 6, num_xypoints, xypoints); - break; - } - } - else if ((attr = cupsFindAttr(ppd, "cupsLightBlackGamma", colormodel, - media, resolution, spec, - sizeof(spec))) != NULL) - { - if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) - switch (num_channels) - { - case 2 : - cupsCMYKSetGamma(cmyk, 1, gamval, density); - break; - case 7 : - cupsCMYKSetGamma(cmyk, 6, gamval, density); - break; - } - } - else if ((attr = cupsFindAttr(ppd, "cupsBlackLtDk", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - if (sscanf(attr->value, "%f%f", &light, &dark) == 2) - switch (num_channels) - { - case 2 : - cupsCMYKSetLtDk(cmyk, 0, light, dark); - break; - case 7 : - cupsCMYKSetLtDk(cmyk, 5, light, dark); - break; - } - else - fprintf(stderr, "ERROR: Bad cupsBlackLtDk value \"%s\"!\n", - attr->value); - } - else - fprintf(stderr, "WARNING: No light black attribute found for %s!\n", - spec); - } - - if (num_channels >= 6) - { - /* - * Get the optional cupsLightCyanXY, cupsLightCyanGamma, or - * cupsCyanLtDk attributes... - */ - - if ((attr = cupsFindAttr(ppd, "cupsLightCyanXY", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - for (num_xypoints = 0, xyptr = xypoints; - attr != NULL && attr->value != NULL && num_xypoints < 100; - attr = ppdFindNextAttr(ppd, "cupsLightCyanXY", spec)) - if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) - { - num_xypoints ++; - xyptr += 2; - } - - cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints); - } - else if ((attr = cupsFindAttr(ppd, "cupsLightCyanGamma", colormodel, - media, resolution, spec, - sizeof(spec))) != NULL) - { - if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) - cupsCMYKSetGamma(cmyk, 1, gamval, density); - } - else if ((attr = cupsFindAttr(ppd, "cupsCyanLtDk", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - if (sscanf(attr->value, "%f%f", &light, &dark) == 2) - cupsCMYKSetLtDk(cmyk, 0, light, dark); - else - fprintf(stderr, "ERROR: Bad cupsCyanLtDk value \"%s\"!\n", - attr->value); - } - else - fprintf(stderr, "WARNING: No light cyan attribute found for %s!\n", - spec); - - /* - * Get the optional cupsLightMagentaXY, cupsLightMagentaGamma, or - * cupsMagentaLtDk attributes... - */ - - if ((attr = cupsFindAttr(ppd, "cupsLightMagentaXY", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - for (num_xypoints = 0, xyptr = xypoints; - attr != NULL && attr->value != NULL && num_xypoints < 100; - attr = ppdFindNextAttr(ppd, "cupsLightMagentaXY", spec)) - if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) - { - num_xypoints ++; - xyptr += 2; - } - - cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints); - } - else if ((attr = cupsFindAttr(ppd, "cupsLightMagentaGamma", colormodel, - media, resolution, spec, - sizeof(spec))) != NULL) - { - if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) - cupsCMYKSetGamma(cmyk, 3, gamval, density); - } - else if ((attr = cupsFindAttr(ppd, "cupsMagentaLtDk", colormodel, media, - resolution, spec, sizeof(spec))) != NULL) - { - if (sscanf(attr->value, "%f%f", &light, &dark) == 2) - cupsCMYKSetLtDk(cmyk, 2, light, dark); - else - fprintf(stderr, "ERROR: Bad cupsMagentaLtDk value \"%s\"!\n", - attr->value); - } - else - fprintf(stderr, "WARNING: No light magenta attribute found for %s!\n", - spec); - } - - /* - * Return the new profile... - */ - - return (cmyk); -} - - -/* - * 'cupsCMYKNew()' - Create a new CMYK color separation. - */ - -cups_cmyk_t * /* O - New CMYK separation or NULL */ -cupsCMYKNew(int num_channels) /* I - Number of color components */ -{ - cups_cmyk_t *cmyk; /* New color separation */ - int i; /* Looping var */ - - - /* - * Range-check the input... - */ - - if (num_channels < 1) - return (NULL); - - /* - * Allocate memory for the separation... - */ - - if ((cmyk = calloc(1, sizeof(cups_cmyk_t))) == NULL) - return (NULL); - - /* - * Allocate memory for the LUTs... - */ - - cmyk->num_channels = num_channels; - - if ((cmyk->channels[0] = calloc(num_channels * 256, sizeof(short))) == NULL) - { - free(cmyk); - return (NULL); - } - - for (i = 1; i < num_channels; i ++) - cmyk->channels[i] = cmyk->channels[0] + i * 256; - - /* - * Fill in the LUTs with unity transitions... - */ - - for (i = 0; i < 256; i ++) - cmyk->black_lut[i] = i; - - switch (num_channels) - { - case 1 : /* K */ - case 2 : /* Kk */ - for (i = 0; i < 256; i ++) - { - cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255; - } - break; - case 3 : /* CMY */ - for (i = 0; i < 256; i ++) - { - cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255; - cmyk->channels[1][i] = CUPS_MAX_LUT * i / 255; - cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255; - } - break; - case 4 : /* CMYK */ - for (i = 0; i < 256; i ++) - { - cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255; - cmyk->channels[1][i] = CUPS_MAX_LUT * i / 255; - cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255; - cmyk->channels[3][i] = CUPS_MAX_LUT * i / 255; - } - break; - case 6 : /* CcMmYK */ - case 7 : /* CcMmYKk */ - for (i = 0; i < 256; i ++) - { - cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255; - cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255; - cmyk->channels[4][i] = CUPS_MAX_LUT * i / 255; - cmyk->channels[5][i] = CUPS_MAX_LUT * i / 255; - } - break; - } - - /* - * Return the separation... - */ - - return (cmyk); -} - - -/* - * 'cupsCMYKSetBlack()' - Set the transition range for CMY to black. - */ - -void -cupsCMYKSetBlack(cups_cmyk_t *cmyk, /* I - CMYK color separation */ - float lower, /* I - No black ink */ - float upper) /* I - Only black ink */ -{ - int i, /* Looping var */ - delta, /* Difference between lower and upper */ - ilower, /* Lower level from 0 to 255 */ - iupper; /* Upper level from 0 to 255 */ - - - /* - * Range check input... - */ - - if (cmyk == NULL || lower < 0.0 || lower > 1.0 || upper < 0.0 || upper > 1.0 || - lower > upper) - return; - - /* - * Convert lower and upper to integers from 0 to 255... - */ - - ilower = (int)(255.0 * lower + 0.5); - iupper = (int)(255.0 * upper + 0.5); - delta = iupper - ilower; - - /* - * Generate the CMY-only data... - */ - - for (i = 0; i < ilower; i ++) - { - cmyk->black_lut[i] = 0; - cmyk->color_lut[i] = i; - } - - /* - * Then the transition data... - */ - - for (; i < iupper; i ++) - { - cmyk->black_lut[i] = iupper * (i - ilower) / delta; - cmyk->color_lut[i] = ilower - ilower * (i - ilower) / delta; - } - - /* - * Then the K-only data... - */ - - for (; i < 256; i ++) - { - cmyk->black_lut[i] = i; - cmyk->color_lut[i] = 0; - } - - fprintf(stderr, "DEBUG: cupsCMYKSetBlack(cmyk, lower=%.3f, upper=%.3f)\n", lower, upper); - - for (i = 0; i < 256; i += 17) - fprintf(stderr, "DEBUG: %3d = %3dk + %3dc\n", i, - cmyk->black_lut[i], cmyk->color_lut[i]); -} - - -/* - * 'cupsCMYKSetCurve()' - Set a color transform curve using points. - */ - -void -cupsCMYKSetCurve(cups_cmyk_t *cmyk, /* I - CMYK color separation */ - int channel, /* I - Color channel */ - int num_xypoints, - /* I - Number of X,Y points */ - const float *xypoints) /* I - X,Y points */ -{ - int i; /* Looping var */ - int xstart; /* Start position */ - int xend; /* End position */ - int xdelta; /* Difference in position */ - int ystart; /* Start value */ - int yend; /* End value */ - int ydelta; /* Difference in value */ - - - /* - * Range check input... - */ - - if (cmyk == NULL || channel < 0 || channel >= cmyk->num_channels || - num_xypoints < 1 || xypoints == NULL) - return; - - /* - * Initialize the lookup table for the specified channel... - */ - - for (xstart = xend = 0, ystart = yend = 0; - num_xypoints > 0; - num_xypoints --, xypoints += 2, xstart = xend, ystart = yend) - { - xend = (int)(255.0 * xypoints[1] + 0.5); - yend = (int)(CUPS_MAX_LUT * xypoints[0] + 0.5); - xdelta = xend - xstart; - ydelta = yend - ystart; - - for (i = xstart; i < xend; i ++) - cmyk->channels[channel][i] = ystart + ydelta * (i - xstart) / xdelta; - } - - /* - * Initialize any trailing values to the maximum of the last data point... - */ - - for (i = xend; i < 256; i ++) - cmyk->channels[channel][i] = yend; - - fprintf(stderr, "DEBUG: cupsCMYKSetXY(cmyk, channel=%d, num_xypoints=%d, " - "xypoints=[%.3f %.3f %.3f %.3f ...])\n", channel, - num_xypoints, xypoints[0], xypoints[1], xypoints[2], xypoints[3]); - - for (i = 0; i < 256; i += 17) - fprintf(stderr, "DEBUG: %3d = %4d\n", i, - cmyk->channels[channel + 0][i]); -} - - -/* - * 'cupsCMYKSetGamma()' - Set a color transform curve using gamma and density. - */ - -void -cupsCMYKSetGamma(cups_cmyk_t *cmyk, /* I - CMYK color separation */ - int channel, /* I - Ink channel */ - float gamval, /* I - Gamma correction */ - float density) /* I - Maximum density */ -{ - int i; /* Looping var */ - - - /* - * Range check input... - */ - - if (cmyk == NULL || channel < 0 || channel >= cmyk->num_channels || - gamval <= 0.0 || density <= 0.0 || density > 1.0) - return; - - /* - * Initialize the lookup table for the specified channel... - */ - - for (i = 0; i < 256; i ++) - cmyk->channels[channel][i] = (int)(density * CUPS_MAX_LUT * - pow((float)i / 255.0, gamval) + 0.5); - - fprintf(stderr, "DEBUG: cupsCMYKSetGamma(cmyk, channel=%d, gamval=%.3f, " - "density=%.3f)\n", channel, gamval, density); - - for (i = 0; i < 256; i += 17) - fprintf(stderr, "DEBUG: %3d = %4d\n", i, - cmyk->channels[channel + 0][i]); -} - - -/* - * 'cupsCMYKSetInkLimit()' - Set the limit on the amount of ink. - */ - -void -cupsCMYKSetInkLimit(cups_cmyk_t *cmyk, /* I - CMYK color separation */ - float limit) /* I - Limit of ink */ -{ - if (!cmyk || limit < 0.0) - return; - - cmyk->ink_limit = limit * CUPS_MAX_LUT; -} - - -/* - * 'cupsCMYKSetLtDk()' - Set light/dark ink transforms. - */ - -void -cupsCMYKSetLtDk(cups_cmyk_t *cmyk, /* I - CMYK color separation */ - int channel, /* I - Dark ink channel (+1 for light) */ - float light, /* I - Light ink only level */ - float dark) /* I - Dark ink only level */ -{ - int i, /* Looping var */ - delta, /* Difference between lower and upper */ - ilight, /* Light level from 0 to 255 */ - idark; /* Dark level from 0 to 255 */ - short lut[256]; /* Original LUT data */ - - - /* - * Range check input... - */ - - if (cmyk == NULL || light < 0.0 || light > 1.0 || dark < 0.0 || dark > 1.0 || - light > dark || channel < 0 || channel > (cmyk->num_channels - 2)) - return; - - /* - * Convert lower and upper to integers from 0 to 255... - */ - - ilight = (int)(255.0 * light + 0.5); - idark = (int)(255.0 * dark + 0.5); - delta = idark - ilight; - - /* - * Copy the dark ink LUT... - */ - - memcpy(lut, cmyk->channels[channel], sizeof(lut)); - - /* - * Generate the light-only data... - */ - - for (i = 0; i < ilight; i ++) - { - cmyk->channels[channel + 0][i] = 0; - cmyk->channels[channel + 1][i] = CUPS_MAX_LUT * i / ilight; - } - - /* - * Then the transition data... - */ - - for (; i < idark; i ++) - { - cmyk->channels[channel + 0][i] = CUPS_MAX_LUT * idark * (i - ilight) / - delta / 255; - cmyk->channels[channel + 1][i] = CUPS_MAX_LUT - CUPS_MAX_LUT * - (i - ilight) / delta; - } - - /* - * Then the K-only data... - */ - - for (; i < 256; i ++) - { - cmyk->channels[channel + 0][i] = CUPS_MAX_LUT * i / 255; - cmyk->channels[channel + 1][i] = 0; - } - - fprintf(stderr, "DEBUG: cupsCMYKSetLtDk(cmyk, channel=%d, light=%.3f, " - "dark=%.3f)\n", channel, light, dark); - - for (i = 0; i < 256; i += 17) - fprintf(stderr, "DEBUG: %3d = %4dlt + %4ddk\n", i, - cmyk->channels[channel + 0][i], cmyk->channels[channel + 1][i]); -} - - -/* - * End of "$Id$". - */ diff --git a/driver/commandtoescpx.c b/driver/commandtoescpx.c deleted file mode 100644 index d11bd9bd4..000000000 --- a/driver/commandtoescpx.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * "$Id$" - * - * Advanced EPSON ESC/P command filter for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * - * Contents: - * - * main() - Main entry and command processing. - */ - -/* - * Include necessary headers... - */ - -#include -#include "driver.h" -#include "data/escp.h" - - -/* - * 'main()' - Main entry and processing of driver. - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments */ - char *argv[]) /* I - Command-line arguments */ -{ - FILE *fp; /* Command file */ - char line[1024], /* Line from file */ - *lineptr; /* Pointer into line */ - int feedpage; /* Feed the page */ - ppd_file_t *ppd; /* PPD file */ - - - /* - * Check for valid arguments... - */ - - if (argc < 6 || argc > 7) - { - /* - * We don't have the correct number of arguments; write an error message - * and return. - */ - - _cupsLangPrintf(stderr, - _("Usage: %s job-id user title copies options [file]"), - argv[0]); - return (1); - } - - /* - * Open the PPD file... - */ - - if ((ppd = ppdOpenFile(getenv("PPD"))) == NULL) - { - fputs("ERROR: Unable to open PPD file!\n", stderr); - return (1); - } - - /* - * Open the command file as needed... - */ - - if (argc == 7) - { - if ((fp = fopen(argv[6], "r")) == NULL) - { - perror("ERROR: Unable to open command file - "); - return (1); - } - } - else - fp = stdin; - - /* - * Some EPSON printers need an additional command issued at the - * beginning of each job to exit from USB "packet" mode... - */ - - if (ppd->model_number & ESCP_USB) - cupsWritePrintData("\000\000\000\033\001@EJL 1284.4\n@EJL \n\033@", 29); - - /* - * Reset the printer... - */ - - cupsWritePrintData("\033@", 2); - - /* - * Enter remote mode... - */ - - cupsWritePrintData("\033(R\010\000\000REMOTE1", 13); - feedpage = 0; - - /* - * Read the commands from the file and send the appropriate commands... - */ - - while (fgets(line, sizeof(line), fp) != NULL) - { - /* - * Drop trailing newline... - */ - - lineptr = line + strlen(line) - 1; - if (*lineptr == '\n') - *lineptr = '\0'; - - /* - * Skip leading whitespace... - */ - - for (lineptr = line; isspace(*lineptr); lineptr ++); - - /* - * Skip comments and blank lines... - */ - - if (*lineptr == '#' || !*lineptr) - continue; - - /* - * Parse the command... - */ - - if (_cups_strncasecmp(lineptr, "Clean", 5) == 0) - { - /* - * Clean heads... - */ - - cupsWritePrintData("CH\002\000\000\000", 6); - } - else if (_cups_strncasecmp(lineptr, "PrintAlignmentPage", 18) == 0) - { - /* - * Print alignment page... - */ - - int phase; - - phase = atoi(lineptr + 18); - - cupsWritePrintData("DT\003\000\000", 5); - putchar(phase & 255); - putchar(phase >> 8); - feedpage = 1; - } - else if (_cups_strncasecmp(lineptr, "PrintSelfTestPage", 17) == 0) - { - /* - * Print version info and nozzle check... - */ - - cupsWritePrintData("VI\002\000\000\000", 6); - cupsWritePrintData("NC\002\000\000\000", 6); - feedpage = 1; - } - else if (_cups_strncasecmp(lineptr, "ReportLevels", 12) == 0) - { - /* - * Report ink levels... - */ - - cupsWritePrintData("IQ\001\000\001", 5); - } - else if (_cups_strncasecmp(lineptr, "SetAlignment", 12) == 0) - { - /* - * Set head alignment... - */ - - int phase, x; - - if (sscanf(lineptr + 12, "%d%d", &phase, &x) != 2) - { - fprintf(stderr, "ERROR: Invalid printer command \"%s\"!\n", lineptr); - continue; - } - - cupsWritePrintData("DA\004\000", 4); - putchar(0); - putchar(phase); - putchar(0); - putchar(x); - cupsWritePrintData("SV\000\000", 4); - } - else - fprintf(stderr, "ERROR: Invalid printer command \"%s\"!\n", lineptr); - } - - /* - * Exit remote mode... - */ - - cupsWritePrintData("\033\000\000\000", 4); - - /* - * Eject the page as needed... - */ - - if (feedpage) - { - fputs("PAGE: 1 1\n", stderr); - - putchar(13); - putchar(10); - putchar(12); - } - - /* - * Reset the printer... - */ - - cupsWritePrintData("\033@", 2); - - /* - * Close the command file and return... - */ - - ppdClose(ppd); - - if (fp != stdin) - fclose(fp); - - return (0); -} - - -/* - * End of "$Id$". - */ diff --git a/driver/commandtopclx.c b/driver/commandtopclx.c deleted file mode 100644 index 1ef53aab4..000000000 --- a/driver/commandtopclx.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * "$Id$" - * - * Advanced PCL command filter for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * - * Contents: - * - * main() - Main entry and command processing. - */ - -/* - * Include necessary headers... - */ - -#include -#include "driver.h" -#include "data/pcl.h" - - -/* - * 'main()' - Main entry and processing of driver. - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments */ - char *argv[]) /* I - Command-line arguments */ -{ - FILE *fp; /* Command file */ - char line[1024], /* Line from file */ - *lineptr; /* Pointer into line */ - int feedpage; /* Feed the page */ - ppd_file_t *ppd; /* PPD file */ - - - /* - * Check for valid arguments... - */ - - if (argc < 6 || argc > 7) - { - /* - * We don't have the correct number of arguments; write an error message - * and return. - */ - - _cupsLangPrintf(stderr, - _("Usage: %s job-id user title copies options [file]"), - argv[0]); - return (1); - } - - /* - * Open the PPD file... - */ - - if ((ppd = ppdOpenFile(getenv("PPD"))) == NULL) - { - fputs("ERROR: Unable to open PPD file!\n", stderr); - return (1); - } - - /* - * Open the command file as needed... - */ - - if (argc == 7) - { - if ((fp = fopen(argv[6], "r")) == NULL) - { - perror("ERROR: Unable to open command file - "); - return (1); - } - } - else - fp = stdin; - - /* - * Reset the printer... - */ - - cupsWritePrintData("\033E", 2); - - /* - * Read the commands from the file and send the appropriate commands... - */ - - feedpage = 0; - - while (fgets(line, sizeof(line), fp) != NULL) - { - /* - * Drop trailing newline... - */ - - lineptr = line + strlen(line) - 1; - if (*lineptr == '\n') - *lineptr = '\0'; - - /* - * Skip leading whitespace... - */ - - for (lineptr = line; isspace(*lineptr); lineptr ++); - - /* - * Skip comments and blank lines... - */ - - if (*lineptr == '#' || !*lineptr) - continue; - - /* - * Parse the command... - */ - - if (_cups_strncasecmp(lineptr, "Clean", 5) == 0 && - (ppd->model_number & PCL_INKJET)) - { - /* - * Clean heads... - */ - - cupsWritePrintData("\033&b16WPML \004\000\006\001\004\001\005\001" - "\001\004\001\144", 22); - } - else - fprintf(stderr, "ERROR: Invalid printer command \"%s\"!\n", lineptr); - } - - /* - * Eject the page as needed... - */ - - if (feedpage) - { - fputs("PAGE: 1 1\n", stderr); - - putchar(12); - } - - /* - * Reset the printer... - */ - - cupsWritePrintData("\033E", 2); - - /* - * Close the command file and return... - */ - - ppdClose(ppd); - - if (fp != stdin) - fclose(fp); - - return (0); -} - - -/* - * End of "$Id$". - */ diff --git a/driver/dither.c b/driver/dither.c deleted file mode 100644 index dfefed7c1..000000000 --- a/driver/dither.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * "$Id$" - * - * Dithering routines for CUPS. - * - * Copyright 2007 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * cupsDitherDelete() - Free a dithering buffer. - * cupsDitherLine() - Dither a line of pixels... - * cupsDitherNew() - Create a dithering buffer. - */ - -/* - * Include necessary headers. - */ - -#include "driver.h" -#include - - -/* - * 'cupsDitherDelete()' - Free a dithering buffer. - * - * Returns 0 on success, -1 on failure. - */ - -void -cupsDitherDelete(cups_dither_t *d) /* I - Dithering buffer */ -{ - if (d != NULL) - free(d); -} - - -/* - * 'cupsDitherLine()' - Dither a line of pixels... - */ - -void -cupsDitherLine(cups_dither_t *d, /* I - Dither data */ - const cups_lut_t *lut, /* I - Lookup table */ - const short *data, /* I - Separation data */ - int num_channels, - /* I - Number of components */ - unsigned char *p) /* O - Pixels */ -{ - register int x, /* Horizontal position in line... */ - pixel, /* Current adjusted pixel... */ - e, /* Current error */ - e0,e1,e2; /* Error values */ - register int errval0, /* First half of error value */ - errval1, /* Second half of error value */ - errbase, /* Base multiplier */ - errbase0, /* Base multiplier for large values */ - errbase1, /* Base multiplier for small values */ - errrange; /* Range of random multiplier */ - register int *p0, /* Error buffer pointers... */ - *p1; - static char logtable[16384]; /* Error magnitude for randomness */ - static char loginit = 0; /* Has the table been initialized? */ - - - if (!loginit) - { - /* - * Initialize a logarithmic table for the magnitude of randomness - * that is introduced. - */ - - loginit = 1; - - logtable[0] = 0; - for (x = 1; x < 2049; x ++) - logtable[x] = (int)(log(x / 16.0) / log(2.0) + 1.0); - for (; x < 16384; x ++) - logtable[x] = logtable[2049]; - } - - if (d->row == 0) - { - /* - * Dither from left to right: - * - * e0 == p0[0] - * e1 e2 == p1[-1] p1[0] - */ - - p0 = d->errors + 2; - p1 = d->errors + 2 + d->width + 4; - e0 = p0[0]; - e1 = 0; - e2 = 0; - - /* - * Error diffuse each output pixel... - */ - - for (x = d->width; - x > 0; - x --, p0 ++, p1 ++, p ++, data += num_channels) - { - /* - * Skip blank pixels... - */ - - if (*data == 0) - { - *p = 0; - e0 = p0[1]; - p1[-1] = e1; - e1 = e2; - e2 = 0; - continue; - } - - /* - * Compute the net pixel brightness and brightness error. Set a dot - * if necessary... - */ - - pixel = lut[*data].intensity + e0 / 128; - - if (pixel > CUPS_MAX_LUT) - pixel = CUPS_MAX_LUT; - else if (pixel < 0) - pixel = 0; - - *p = lut[pixel].pixel; - e = lut[pixel].error; - - /* - * Set the randomness factor... - */ - - if (e > 0) - errrange = logtable[e]; - else - errrange = logtable[-e]; - - errbase = 8 - errrange; - errrange = errrange * 2 + 1; - - /* - * Randomize the error value. - */ - - if (errrange > 1) - { - errbase0 = errbase + (CUPS_RAND() % errrange); - errbase1 = errbase + (CUPS_RAND() % errrange); - } - else - errbase0 = errbase1 = errbase; - - /* - * X 7/16 = X e0 - * 3/16 5/16 1/16 = e1 e2 - */ - - errval0 = errbase0 * e; - errval1 = (16 - errbase0) * e; - e0 = p0[1] + 7 * errval0; - e1 = e2 + 5 * errval1; - - errval0 = errbase1 * e; - errval1 = (16 - errbase1) * e; - e2 = errval0; - p1[-1] = e1 + 3 * errval1; - } - } - else - { - /* - * Dither from right to left: - * - * e0 == p0[0] - * e2 e1 == p1[0] p1[1] - */ - - p0 = d->errors + d->width + 1 + d->width + 4; - p1 = d->errors + d->width + 1; - p += d->width - 1; - data += num_channels * (d->width - 1); - e0 = p0[0]; - e1 = 0; - e2 = 0; - - /* - * Error diffuse each output pixel... - */ - - for (x = d->width; - x > 0; - x --, p0 --, p1 --, p --, data -= num_channels) - { - /* - * Skip blank pixels... - */ - - if (*data == 0) - { - *p = 0; - e0 = p0[-1]; - p1[1] = e1; - e1 = e2; - e2 = 0; - continue; - } - - /* - * Compute the net pixel brightness and brightness error. Set a dot - * if necessary... - */ - - pixel = lut[*data].intensity + e0 / 128; - - if (pixel > CUPS_MAX_LUT) - pixel = CUPS_MAX_LUT; - else if (pixel < 0) - pixel = 0; - - *p = lut[pixel].pixel; - e = lut[pixel].error; - - /* - * Set the randomness factor... - */ - - if (e > 0) - errrange = logtable[e]; - else - errrange = logtable[-e]; - - errbase = 8 - errrange; - errrange = errrange * 2 + 1; - - /* - * Randomize the error value. - */ - - if (errrange > 1) - { - errbase0 = errbase + (CUPS_RAND() % errrange); - errbase1 = errbase + (CUPS_RAND() % errrange); - } - else - errbase0 = errbase1 = errbase; - - /* - * X 7/16 = X e0 - * 3/16 5/16 1/16 = e1 e2 - */ - - errval0 = errbase0 * e; - errval1 = (16 - errbase0) * e; - e0 = p0[-1] + 7 * errval0; - e1 = e2 + 5 * errval1; - - errval0 = errbase1 * e; - errval1 = (16 - errbase1) * e; - e2 = errval0; - p1[1] = e1 + 3 * errval1; - } - } - - /* - * Update to the next row... - */ - - d->row = 1 - d->row; -} - - -/* - * 'cupsDitherNew()' - Create an error-diffusion dithering buffer. - */ - -cups_dither_t * /* O - New state array */ -cupsDitherNew(int width) /* I - Width of output in pixels */ -{ - cups_dither_t *d; /* New dithering buffer */ - - - if ((d = (cups_dither_t *)calloc(1, sizeof(cups_dither_t) + - 2 * (width + 4) * - sizeof(int))) == NULL) - return (NULL); - - d->width = width; - - return (d); -} - - -/* - * End of "$Id$". - */ diff --git a/driver/driver.h b/driver/driver.h deleted file mode 100644 index ed4eab96d..000000000 --- a/driver/driver.h +++ /dev/null @@ -1,249 +0,0 @@ -/* - * "$Id$" - * - * Printer driver utilities header file for CUPS. - * - * Copyright 2007 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - */ - -#ifndef _CUPS_DRIVER_H_ -# define _CUPS_DRIVER_H_ - -# ifdef __cplusplus -extern "C" { -# endif /* __cplusplus */ - -/* - * Include necessary headers... - */ - -# include -# include -# include -# include - -# if defined(WIN32) || defined(__EMX__) -# include -# else -# include -# include -# endif /* WIN32 || __EMX__ */ - -# include -# include - - -/* - * Common macros... - */ - -# ifndef min -# define min(a,b) ((a) < (b) ? (a) : (b)) -# define max(a,b) ((a) > (b) ? (a) : (b)) -# endif /* !min */ - - -/* - * Constants... - */ - -#define CUPS_MAX_CHAN 15 /* Maximum number of color components */ -#define CUPS_MAX_LUT 4095 /* Maximum LUT value */ -#define CUPS_MAX_RGB 4 /* Maximum number of sRGB components */ - - -/* - * Types/structures for the various routines. - */ - -typedef struct cups_lut_s /**** Lookup Table for Dithering ****/ -{ - short intensity; /* Adjusted intensity */ - short pixel; /* Output pixel value */ - int error; /* Error from desired value */ -} cups_lut_t; - -typedef struct cups_dither_s /**** Dithering State ****/ -{ - int width; /* Width of buffer */ - int row; /* Current row */ - int errors[96]; /* Error values */ -} cups_dither_t; - -typedef struct cups_sample_s /**** Color sample point ****/ -{ - unsigned char rgb[3]; /* sRGB values */ - unsigned char colors[CUPS_MAX_RGB]; /* Color values */ -} cups_sample_t; - -typedef struct cups_rgb_s /**** Color separation lookup table ****/ -{ - int cube_size; /* Size of color cube (2-N) on a side */ - int num_channels; /* Number of colors per sample */ - unsigned char ****colors; /* 4-D array of sample values */ - int cube_index[256]; /* Index into cube for a given sRGB value */ - int cube_mult[256]; /* Multiplier value for a given sRGB value */ - int cache_init; /* Are cached values initialized? */ - unsigned char black[CUPS_MAX_RGB]; /* Cached black (sRGB = 0,0,0) */ - unsigned char white[CUPS_MAX_RGB]; /* Cached white (sRGB = 255,255,255) */ -} cups_rgb_t; - -typedef struct cups_cmyk_s /**** Simple CMYK lookup table ****/ -{ - unsigned char black_lut[256]; /* Black generation LUT */ - unsigned char color_lut[256]; /* Color removal LUT */ - int ink_limit; /* Ink limit */ - int num_channels; /* Number of components */ - short *channels[CUPS_MAX_CHAN]; - /* Lookup tables */ -} cups_cmyk_t; - - -/* - * Globals... - */ - -extern const unsigned char - cups_srgb_lut[256]; - /* sRGB gamma lookup table */ -extern const unsigned char - cups_scmy_lut[256]; - /* sRGB gamma lookup table (inverted) */ - - -/* - * Prototypes... - */ - -/* - * Attribute function... - */ - -extern ppd_attr_t *cupsFindAttr(ppd_file_t *ppd, const char *name, - const char *colormodel, - const char *media, - const char *resolution, - char *spec, int specsize); - -/* - * Byte checking functions... - */ - -extern int cupsCheckBytes(const unsigned char *, int); -extern int cupsCheckValue(const unsigned char *, int, - const unsigned char); - -/* - * Dithering functions... - */ - -extern void cupsDitherLine(cups_dither_t *d, const cups_lut_t *lut, - const short *data, int num_channels, - unsigned char *p); -extern cups_dither_t *cupsDitherNew(int width); -extern void cupsDitherDelete(cups_dither_t *); - -/* - * Lookup table functions for dithering... - */ - -extern cups_lut_t *cupsLutNew(int num_vals, const float *vals); -extern void cupsLutDelete(cups_lut_t *lut); -extern cups_lut_t *cupsLutLoad(ppd_file_t *ppd, - const char *colormodel, - const char *media, - const char *resolution, - const char *ink); - - -/* - * Bit packing functions... - */ - -extern void cupsPackHorizontal(const unsigned char *, - unsigned char *, int, - const unsigned char, const int); -extern void cupsPackHorizontal2(const unsigned char *, - unsigned char *, int, const int); -extern void cupsPackHorizontalBit(const unsigned char *, - unsigned char *, int, - const unsigned char, - const unsigned char); -extern void cupsPackVertical(const unsigned char *, unsigned char *, - int, const unsigned char, const int); - -/* - * Color separation functions... - */ - -extern void cupsRGBDelete(cups_rgb_t *rgb); -extern void cupsRGBDoGray(cups_rgb_t *rgb, - const unsigned char *input, - unsigned char *output, int num_pixels); -extern void cupsRGBDoRGB(cups_rgb_t *rgb, - const unsigned char *input, - unsigned char *output, int num_pixels); -extern cups_rgb_t *cupsRGBLoad(ppd_file_t *ppd, - const char *colormodel, - const char *media, - const char *resolution); -extern cups_rgb_t *cupsRGBNew(int num_samples, cups_sample_t *samples, - int cube_size, int num_channels); - -/* - * CMYK separation functions... - */ - -extern cups_cmyk_t *cupsCMYKNew(int num_channels); -extern void cupsCMYKDelete(cups_cmyk_t *cmyk); -extern void cupsCMYKDoBlack(const cups_cmyk_t *cmyk, - const unsigned char *input, - short *output, int num_pixels); -extern void cupsCMYKDoCMYK(const cups_cmyk_t *cmyk, - const unsigned char *input, - short *output, int num_pixels); -extern void cupsCMYKDoGray(const cups_cmyk_t *cmyk, - const unsigned char *input, - short *output, int num_pixels); -extern void cupsCMYKDoRGB(const cups_cmyk_t *cmyk, - const unsigned char *input, - short *output, int num_pixels); -extern cups_cmyk_t *cupsCMYKLoad(ppd_file_t *ppd, - const char *colormodel, - const char *media, - const char *resolution); -extern void cupsCMYKSetBlack(cups_cmyk_t *cmyk, - float lower, float upper); -extern void cupsCMYKSetCurve(cups_cmyk_t *cmyk, int channel, - int num_xypoints, - const float *xypoints); -extern void cupsCMYKSetGamma(cups_cmyk_t *cmyk, int channel, - float gamval, float density); -extern void cupsCMYKSetInkLimit(cups_cmyk_t *cmyk, float limit); -extern void cupsCMYKSetLtDk(cups_cmyk_t *cmyk, int channel, - float light, float dark); - - -/* - * Convenience macro for writing print data... - */ - -# define cupsWritePrintData(s,n) fwrite((s), 1, (n), stdout) - -# ifdef __cplusplus -} -# endif /* __cplusplus */ - -#endif /* !_CUPS_DRIVER_H_ */ - -/* - * End of "$Id$". - */ - diff --git a/driver/image.pgm b/driver/image.pgm deleted file mode 100644 index c0b7a22f7..000000000 Binary files a/driver/image.pgm and /dev/null differ diff --git a/driver/image.ppm b/driver/image.ppm deleted file mode 100644 index 3823fe48b..000000000 Binary files a/driver/image.ppm and /dev/null differ diff --git a/driver/libcupsdriver.exp b/driver/libcupsdriver.exp deleted file mode 100644 index fff6506fe..000000000 --- a/driver/libcupsdriver.exp +++ /dev/null @@ -1,30 +0,0 @@ -_cupsCMYKDelete -_cupsCMYKDoBlack -_cupsCMYKDoCMYK -_cupsCMYKDoGray -_cupsCMYKDoRGB -_cupsCMYKLoad -_cupsCMYKNew -_cupsCMYKSetBlack -_cupsCMYKSetCurve -_cupsCMYKSetGamma -_cupsCMYKSetInkLimit -_cupsCMYKSetLtDk -_cupsCheckBytes -_cupsCheckValue -_cupsDitherDelete -_cupsDitherLine -_cupsDitherNew -_cupsFindAttr -_cupsLutDelete -_cupsLutLoad -_cupsLutNew -_cupsPackHorizontal -_cupsPackHorizontal2 -_cupsPackHorizontalBit -_cupsPackVertical -_cupsRGBDelete -_cupsRGBDoGray -_cupsRGBDoRGB -_cupsRGBLoad -_cupsRGBNew diff --git a/driver/lut.c b/driver/lut.c deleted file mode 100644 index 7ca7e4350..000000000 --- a/driver/lut.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * "$Id$" - * - * Lookup table routines for CUPS. - * - * Copyright 2007 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * cupsLutDelete() - Free the memory used by a lookup table. - * cupsLutLoad() - Load a LUT from a PPD file. - * cupsLutNew() - Make a lookup table from a list of pixel values. - */ - -/* - * Include necessary headers. - */ - -#include "driver.h" -#include - - -/* - * 'cupsLutDelete()' - Free the memory used by a lookup table. - */ - -void -cupsLutDelete(cups_lut_t *lut) /* I - Lookup table to free */ -{ - if (lut != NULL) - free(lut); -} - - -/* - * 'cupsLutLoad()' - Load a LUT from a PPD file. - */ - -cups_lut_t * /* O - New lookup table */ -cupsLutLoad(ppd_file_t *ppd, /* I - PPD file */ - const char *colormodel, /* I - Color model */ - const char *media, /* I - Media type */ - const char *resolution, /* I - Resolution */ - const char *ink) /* I - Ink name */ -{ - char name[PPD_MAX_NAME], /* Attribute name */ - spec[PPD_MAX_NAME]; /* Attribute spec */ - ppd_attr_t *attr; /* Attribute */ - int nvals; /* Number of values */ - float vals[4]; /* Values */ - - - /* - * Range check input... - */ - - if (!ppd || !colormodel || !media || !resolution || !ink) - return (NULL); - - /* - * Try to find the LUT values... - */ - - snprintf(name, sizeof(name), "cups%sDither", ink); - - if ((attr = cupsFindAttr(ppd, name, colormodel, media, resolution, spec, - sizeof(spec))) == NULL) - attr = cupsFindAttr(ppd, "cupsAllDither", colormodel, media, - resolution, spec, sizeof(spec)); - - if (!attr) - return (NULL); - - vals[0] = 0.0; - vals[1] = 0.0; - vals[2] = 0.0; - vals[3] = 0.0; - nvals = sscanf(attr->value, "%f%f%f", vals + 1, vals + 2, vals + 3) + 1; - - fprintf(stderr, "DEBUG: Loaded LUT %s from PPD with values [%.3f %.3f %.3f %.3f]\n", - name, vals[0], vals[1], vals[2], vals[3]); - - return (cupsLutNew(nvals, vals)); -} - - -/* - * 'cupsLutNew()' - Make a lookup table from a list of pixel values. - * - * Returns a pointer to the lookup table on success, NULL on failure. - */ - -cups_lut_t * /* O - New lookup table */ -cupsLutNew(int num_values, /* I - Number of values */ - const float *values) /* I - Lookup table values */ -{ - int pixel; /* Pixel value */ - cups_lut_t *lut; /* Lookup table */ - int start, /* Start value */ - end, /* End value */ - maxval; /* Maximum value */ - - - /* - * Range check... - */ - - if (!num_values || !values) - return (NULL); - - /* - * Allocate memory for the lookup table... - */ - - if ((lut = (cups_lut_t *)calloc((CUPS_MAX_LUT + 1), - sizeof(cups_lut_t))) == NULL) - return (NULL); - - /* - * Generate the dither lookup table. The pixel values are roughly - * defined by a piecewise linear curve that has an intensity value - * at each output pixel. This isn't perfectly accurate, but it's - * close enough for jazz. - */ - - maxval = CUPS_MAX_LUT / values[num_values - 1]; - - for (start = 0; start <= CUPS_MAX_LUT; start ++) - lut[start].intensity = start * maxval / CUPS_MAX_LUT; - - for (pixel = 0; pixel < num_values; pixel ++) - { - /* - * Select start and end values for this pixel... - */ - - if (pixel == 0) - start = 0; - else - start = (int)(0.5 * maxval * (values[pixel - 1] + - values[pixel])) + 1; - - if (start < 0) - start = 0; - else if (start > CUPS_MAX_LUT) - start = CUPS_MAX_LUT; - - if (pixel == (num_values - 1)) - end = CUPS_MAX_LUT; - else - end = (int)(0.5 * maxval * (values[pixel] + values[pixel + 1])); - - if (end < 0) - end = 0; - else if (end > CUPS_MAX_LUT) - end = CUPS_MAX_LUT; - - if (start == end) - break; - - /* - * Generate lookup values and errors for each pixel. - */ - - while (start <= end) - { - lut[start].pixel = pixel; - if (start == 0) - lut[0].error = 0; - else - lut[start].error = start - maxval * values[pixel]; - - start ++; - } - } - - /* - * Show the lookup table... - */ - - for (start = 0; start <= CUPS_MAX_LUT; start += CUPS_MAX_LUT / 15) - fprintf(stderr, "DEBUG: %d = %d/%d/%d\n", start, lut[start].intensity, - lut[start].pixel, lut[start].error); - - /* - * Return the lookup table... - */ - - return (lut); -} - - -/* - * End of "$Id$". - */ diff --git a/driver/pack.c b/driver/pack.c deleted file mode 100644 index d9d01d16b..000000000 --- a/driver/pack.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * "$Id$" - * - * Bit packing routines for CUPS. - * - * Copyright 2007 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * cupsPackHorizontal() - Pack pixels horizontally... - * cupsPackHorizontal2() - Pack 2-bit pixels horizontally... - * cupsPackHorizontalBit() - Pack pixels horizontally by bit... - * cupsPackVertical() - Pack pixels vertically... - */ - -/* - * Include necessary headers... - */ - -#include "driver.h" - - -/* - * 'cupsPackHorizontal()' - Pack pixels horizontally... - */ - -void -cupsPackHorizontal(const unsigned char *ipixels,/* I - Input pixels */ - unsigned char *obytes, /* O - Output bytes */ - int width, /* I - Number of pixels */ - const unsigned char clearto, /* I - Initial value of bytes */ - const int step) /* I - Step value between pixels */ -{ - register unsigned char b; /* Current byte */ - - - /* - * Do whole bytes first... - */ - - while (width > 7) - { - b = clearto; - - if (*ipixels) - b ^= 0x80; - ipixels += step; - if (*ipixels) - b ^= 0x40; - ipixels += step; - if (*ipixels) - b ^= 0x20; - ipixels += step; - if (*ipixels) - b ^= 0x10; - ipixels += step; - if (*ipixels) - b ^= 0x08; - ipixels += step; - if (*ipixels) - b ^= 0x04; - ipixels += step; - if (*ipixels) - b ^= 0x02; - ipixels += step; - if (*ipixels) - b ^= 0x01; - ipixels += step; - - *obytes++ = b; - - width -= 8; - } - - /* - * Then do the last N bytes (N < 8)... - */ - - b = clearto; - - switch (width) - { - case 7 : - if (ipixels[6 * step]) - b ^= 0x02; - case 6 : - if (ipixels[5 * step]) - b ^= 0x04; - case 5 : - if (ipixels[4 * step]) - b ^= 0x08; - case 4 : - if (ipixels[3 * step]) - b ^= 0x10; - case 3 : - if (ipixels[2 * step]) - b ^= 0x20; - case 2 : - if (ipixels[1 * step]) - b ^= 0x40; - case 1 : - if (ipixels[0]) - b ^= 0x80; - *obytes = b; - break; - } -} - - -/* - * 'cupsPackHorizontal2()' - Pack 2-bit pixels horizontally... - */ - -void -cupsPackHorizontal2(const unsigned char *ipixels, /* I - Input pixels */ - unsigned char *obytes, /* O - Output bytes */ - int width, /* I - Number of pixels */ - const int step) /* I - Stepping value */ -{ - register unsigned char b; /* Current byte */ - - - /* - * Do whole bytes first... - */ - - while (width > 3) - { - b = *ipixels; - ipixels += step; - b = (b << 2) | *ipixels; - ipixels += step; - b = (b << 2) | *ipixels; - ipixels += step; - b = (b << 2) | *ipixels; - ipixels += step; - - *obytes++ = b; - - width -= 4; - } - - /* - * Then do the last N bytes (N < 4)... - */ - - b = 0; - - switch (width) - { - case 3 : - b = ipixels[2 * step]; - case 2 : - b = (b << 2) | ipixels[step]; - case 1 : - b = (b << 2) | ipixels[0]; - *obytes = b << (8 - 2 * width); - break; - } -} - - -/* - * 'cupsPackHorizontalBit()' - Pack pixels horizontally by bit... - */ - -void -cupsPackHorizontalBit(const unsigned char *ipixels, /* I - Input pixels */ - unsigned char *obytes, /* O - Output bytes */ - int width, /* I - Number of pixels */ - const unsigned char clearto, /* I - Initial value of bytes */ - const unsigned char bit) /* I - Bit to check */ -{ - register unsigned char b; /* Current byte */ - - - /* - * Do whole bytes first... - */ - - while (width > 7) - { - b = clearto; - - if (*ipixels++ & bit) - b ^= 0x80; - if (*ipixels++ & bit) - b ^= 0x40; - if (*ipixels++ & bit) - b ^= 0x20; - if (*ipixels++ & bit) - b ^= 0x10; - if (*ipixels++ & bit) - b ^= 0x08; - if (*ipixels++ & bit) - b ^= 0x04; - if (*ipixels++ & bit) - b ^= 0x02; - if (*ipixels++ & bit) - b ^= 0x01; - - *obytes++ = b; - - width -= 8; - } - - /* - * Then do the last N bytes (N < 8)... - */ - - b = clearto; - - switch (width) - { - case 7 : - if (ipixels[6] & bit) - b ^= 0x02; - case 6 : - if (ipixels[5] & bit) - b ^= 0x04; - case 5 : - if (ipixels[4] & bit) - b ^= 0x08; - case 4 : - if (ipixels[3] & bit) - b ^= 0x10; - case 3 : - if (ipixels[2] & bit) - b ^= 0x20; - case 2 : - if (ipixels[1] & bit) - b ^= 0x40; - case 1 : - if (ipixels[0] & bit) - b ^= 0x80; - *obytes = b; - break; - } -} - - -/* - * 'cupsPackVertical()' - Pack pixels vertically... - */ - -void -cupsPackVertical(const unsigned char *ipixels, /* I - Input pixels */ - unsigned char *obytes, /* O - Output bytes */ - int width, /* I - Number of input pixels */ - const unsigned char bit, /* I - Output bit */ - const int step) /* I - Number of bytes between columns */ -{ - /* - * Loop through the entire array... - */ - - while (width > 7) - { - if (*ipixels++) - *obytes ^= bit; - obytes += step; - if (*ipixels++) - *obytes ^= bit; - obytes += step; - if (*ipixels++) - *obytes ^= bit; - obytes += step; - if (*ipixels++) - *obytes ^= bit; - obytes += step; - if (*ipixels++) - *obytes ^= bit; - obytes += step; - if (*ipixels++) - *obytes ^= bit; - obytes += step; - if (*ipixels++) - *obytes ^= bit; - obytes += step; - if (*ipixels++) - *obytes ^= bit; - obytes += step; - - width -= 8; - } - - while (width > 0) - { - if (*ipixels++) - *obytes ^= bit; - - obytes += step; - width --; - } -} - - -/* - * End of "$Id$". - */ diff --git a/driver/pcl-common.c b/driver/pcl-common.c deleted file mode 100644 index 427879338..000000000 --- a/driver/pcl-common.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * "$Id$" - * - * Common PCL functions for CUPS. - * - * Copyright 2007 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * pcl_set_media_size() - Set media size using the page size command. - * pjl_write() - Write a PJL command string, performing - * substitutions as needed. - */ - -/* - * Include necessary headers... - */ - -#include "driver.h" -#include "pcl-common.h" -#include - - -/* - * 'pcl_set_media_size()' - Set media size using the page size command. - */ - -void -pcl_set_media_size(ppd_file_t *ppd, /* I - PPD file */ - float width, /* I - Width of page */ - float length) /* I - Length of page */ -{ - (void)width; - - printf("\033&l0O"); /* Set portrait orientation */ - - if (ppd->model_number & PCL_PAPER_SIZE) - switch ((int)(length + 0.5f)) - { - case 419 : /* Postcard */ - printf("\033&l71A"); /* Set page size */ - break; - - case 540 : /* Monarch Envelope */ - printf("\033&l80A"); /* Set page size */ - break; - - case 567 : /* Double Postcard */ - printf("\033&l72A"); /* Set page size */ - break; - - case 595 : /* A5 */ - printf("\033&l25A"); /* Set page size */ - break; - - case 612 : /* Statement */ - printf("\033&l5A"); /* Set page size */ - break; - - case 624 : /* DL Envelope */ - printf("\033&l90A"); /* Set page size */ - break; - - case 649 : /* C5 Envelope */ - printf("\033&l91A"); /* Set page size */ - break; - - case 684 : /* COM-10 Envelope */ - printf("\033&l81A"); /* Set page size */ - break; - - case 709 : /* B5 Envelope */ - printf("\033&l100A"); /* Set page size */ - break; - - case 729 : /* B5 */ - printf("\033&l45A"); /* Set page size */ - break; - - case 756 : /* Executive */ - printf("\033&l1A"); /* Set page size */ - break; - - case 792 : /* Letter */ - printf("\033&l2A"); /* Set page size */ - break; - - case 842 : /* A4 */ - printf("\033&l26A"); /* Set page size */ - break; - - case 936 : /* Foolscap */ - printf("\033&l23A"); /* Set page size */ - break; - - case 1008 : /* Legal */ - printf("\033&l3A"); /* Set page size */ - break; - - case 1032 : /* B4 */ - printf("\033&l46A"); /* Set page size */ - break; - - case 1191 : /* A3 */ - printf("\033&l27A"); /* Set page size */ - break; - - case 1224 : /* Tabloid */ - printf("\033&l6A"); /* Set page size */ - break; - - default : - printf("\033&l101A"); /* Set page size */ - printf("\033&l6D\033&k12H"); /* Set 6 LPI, 10 CPI */ - printf("\033&l%.2fP", length / 12.0); - /* Set page length */ - printf("\033&l%.0fF", length / 12.0); - /* Set text length to page */ - break; - } - else - { - printf("\033&l6D\033&k12H"); /* Set 6 LPI, 10 CPI */ - printf("\033&l%.2fP", length / 12.0); - /* Set page length */ - printf("\033&l%.0fF", length / 12.0); - /* Set text length to page */ - } - - printf("\033&l0L"); /* Turn off perforation skip */ - printf("\033&l0E"); /* Reset top margin to 0 */ -} - - -/* - * 'pjl_write()' - Write a PJL command string, performing substitutions as needed. - */ - -void -pjl_write(ppd_file_t *ppd, /* I - PPD file */ - const char *format, /* I - Format string */ - const char *value, /* I - Value for %s */ - int job_id, /* I - Job ID */ - const char *user, /* I - Username */ - const char *title, /* I - Title */ - int num_options, /* I - Number of options */ - cups_option_t *options) /* I - Options */ -{ - const char *optval; /* Option value */ - char match[255], /* Match string */ - *mptr; /* Pointer into match string */ - - - if (!format) - return; - - while (*format) - { - if (*format == '%') - { - /* - * Perform substitution... - */ - - format ++; - switch (*format) - { - case 'b' : /* job-billing */ - if ((optval = cupsGetOption("job-billing", num_options, - options)) != NULL) - fputs(optval, stdout); - break; - - case 'h' : /* job-originating-host-name */ - if ((optval = cupsGetOption("job-originating-host-name", - num_options, options)) != NULL) - fputs(optval, stdout); - break; - - case 'j' : /* job-id */ - printf("%d", job_id); - break; - - case 'n' : /* CR + LF */ - putchar('\r'); - putchar('\n'); - break; - - case 'q' : /* double quote (") */ - putchar('\"'); - break; - - case 's' : /* "value" */ - if (value) - fputs(value, stdout); - break; - - case 't' : /* job-name */ - fputs(title, stdout); - break; - - case 'u' : /* job-originating-user-name */ - fputs(user, stdout); - break; - - case '?' : /* ?value:string; */ - /* - * Get the match value... - */ - - for (format ++, mptr = match; *format && *format != ':'; format ++) - if (mptr < (match + sizeof(match) - 1)) - *mptr++ = *format; - - if (!*format) - return; - - /* - * See if we have a match... - */ - - format ++; - *mptr = '\0'; - - if (!value || strcmp(match, value)) - { - /* - * Value doesn't match; skip the string that follows... - */ - - while (*format && *format != ';') - format ++; - } - else - { - /* - * Value matches; copy the string that follows... - */ - - while (*format && *format != ';') - putchar(*format++); - } - - if (!*format) - return; - break; - - default : /* Anything else */ - putchar('%'); - case '%' : /* %% = single % */ - putchar(*format); - break; - } - } - else - putchar(*format); - - format ++; - } -} - - -/* - * End of "$Id$". - */ diff --git a/driver/pcl-common.h b/driver/pcl-common.h deleted file mode 100644 index 7cab21cb9..000000000 --- a/driver/pcl-common.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * "$Id$" - * - * Common HP-PCL definitions for CUPS. - * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products, All Rights Reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - */ - -/* - * Include necessary headers... - */ - -#include -#include "data/pcl.h" - - -/* - * Functions/macros... - */ - -#define pcl_reset()\ - printf("\033E") -#define pcl_set_copies(copies)\ - printf("\033&l%dX", (copies)) -#define pcl_set_pcl_mode(m)\ - printf("\033%%%dA", (m)) -#define pcl_set_hpgl_mode(m)\ - printf("\033%%%dB", (m)) -#define pcl_set_negative_motion()\ - printf("\033&a1N") -#define pcl_set_media_source(source)\ - printf("\033&l%dH", source) -#define pcl_set_media_type(type)\ - printf("\033&l%dM", type) -#define pcl_set_duplex(duplex,landscape)\ - if (duplex) printf("\033&l%dS", (duplex) + (landscape)) -#define pcl_set_simple_black()\ - printf("\033*r-1U") -#define pcl_set_simple_color()\ - printf("\033*r3U") -#define pcl_set_simple_cmy()\ - printf("\033*r-3U") -#define pcl_set_simple_kcmy()\ - printf("\033*r-4U") -#define pcl_set_simple_resolution(r)\ - printf("\033*t%dR", (r)) - -#define pjl_escape()\ - printf("\033%%-12345X@PJL\r\n") -#define pjl_set_job(job_id,user,title)\ - printf("@PJL JOB NAME = \"%s\" DISPLAY = \"%d %s %s\"\r\n", \ - (title), (job_id), (user), (title)) -#define pjl_enter_language(lang)\ - printf("@PJL ENTER LANGUAGE=%s\r\n", (lang)) - -extern void pcl_set_media_size(ppd_file_t *ppd, float width, float length); -extern void pjl_write(ppd_file_t *ppd, const char *format, - const char *value, int job_id, - const char *user, const char *title, - int num_options, cups_option_t *options); - -/* - * End of "$Id$". - */ diff --git a/driver/rastertoescpx.c b/driver/rastertoescpx.c deleted file mode 100644 index 0bcc0a92c..000000000 --- a/driver/rastertoescpx.c +++ /dev/null @@ -1,1931 +0,0 @@ -/* - * "$Id$" - * - * Advanced EPSON ESC/P raster driver for CUPS. - * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * Setup() - Prepare the printer for graphics output. - * StartPage() - Start a page of graphics. - * EndPage() - Finish a page of graphics. - * Shutdown() - Shutdown a printer. - * CancelJob() - Cancel the current job... - * CompressData() - Compress a line of graphics. - * OutputBand() - Output a band of graphics. - * ProcessLine() - Read graphics from the page stream and output - * as needed. - * main() - Main entry and processing of driver. - */ - -/* - * Include necessary headers... - */ - -#include "driver.h" -#include -#include -#include "data/escp.h" -#include - - -/* - * Softweave data... - */ - -typedef struct cups_weave_str -{ - struct cups_weave_str *prev, /* Previous band */ - *next; /* Next band */ - int x, y, /* Column/Line on the page */ - plane, /* Color plane */ - dirty, /* Is this buffer dirty? */ - row, /* Row in the buffer */ - count; /* Max rows this pass */ - unsigned char *buffer; /* Data buffer */ -} cups_weave_t; - - -/* - * Globals... - */ - -cups_rgb_t *RGB; /* RGB color separation data */ -cups_cmyk_t *CMYK; /* CMYK color separation data */ -unsigned char *PixelBuffer, /* Pixel buffer */ - *CMYKBuffer, /* CMYK buffer */ - *OutputBuffers[7], /* Output buffers */ - *DotBuffers[7], /* Dot buffers */ - *CompBuffer; /* Compression buffer */ -short *InputBuffer; /* Color separation buffer */ -cups_weave_t *DotAvailList, /* Available buffers */ - *DotUsedList, /* Used buffers */ - *DotBands[128][7]; /* Buffers in use */ -int DotBufferSize, /* Size of dot buffers */ - DotRowMax, /* Maximum row number in buffer */ - DotColStep, /* Step for each output column */ - DotRowStep, /* Step for each output line */ - DotRowFeed, /* Amount to feed for interleave */ - DotRowCount, /* Number of rows to output */ - DotRowOffset[7], /* Offset for each color on print head */ - DotRowCurrent, /* Current row */ - DotSize; /* Dot size (Pro 5000 only) */ -int PrinterPlanes, /* # of color planes */ - BitPlanes, /* # of bit planes per color */ - PrinterTop, /* Top of page */ - PrinterLength; /* Length of page */ -cups_lut_t *DitherLuts[7]; /* Lookup tables for dithering */ -cups_dither_t *DitherStates[7]; /* Dither state tables */ -int OutputFeed; /* Number of lines to skip */ -int Canceled; /* Is the job canceled? */ - - -/* - * Prototypes... - */ - -void Setup(ppd_file_t *); -void StartPage(ppd_file_t *, cups_page_header2_t *); -void EndPage(ppd_file_t *, cups_page_header2_t *); -void Shutdown(ppd_file_t *); - -void AddBand(cups_weave_t *band); -void CancelJob(int sig); -void CompressData(ppd_file_t *, const unsigned char *, const int, - int, int, const int, const int, const int, - const int); -void OutputBand(ppd_file_t *, cups_page_header2_t *, - cups_weave_t *band); -void ProcessLine(ppd_file_t *, cups_raster_t *, - cups_page_header2_t *, const int y); - - -/* - * 'Setup()' - Prepare a printer for graphics output. - */ - -void -Setup(ppd_file_t *ppd) /* I - PPD file */ -{ - /* - * Some EPSON printers need an additional command issued at the - * beginning of each job to exit from USB "packet" mode... - */ - - if (ppd->model_number & ESCP_USB) - cupsWritePrintData("\000\000\000\033\001@EJL 1284.4\n@EJL \n\033@", 29); -} - - -/* - * 'StartPage()' - Start a page of graphics. - */ - -void -StartPage(ppd_file_t *ppd, /* I - PPD file */ - cups_page_header2_t *header) /* I - Page header */ -{ - int i, y; /* Looping vars */ - int subrow, /* Current subrow */ - modrow, /* Subrow modulus */ - plane; /* Current color plane */ - unsigned char *ptr; /* Pointer into dot buffer */ - int bands; /* Number of bands to allocate */ - int units; /* Units for resolution */ - cups_weave_t *band; /* Current band */ - const char *colormodel; /* Color model string */ - char resolution[PPD_MAX_NAME], - /* Resolution string */ - spec[PPD_MAX_NAME]; /* PPD attribute name */ - ppd_attr_t *attr; /* Attribute from PPD file */ - const float default_lut[2] = /* Default dithering lookup table */ - { - 0.0, - 1.0 - }; - - - fprintf(stderr, "DEBUG: StartPage...\n"); - fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass); - fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor); - fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType); - fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType); - - fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance); - fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia); - fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate); - fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia); - fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex); - fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0], - header->HWResolution[1]); - fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n", - header->ImagingBoundingBox[0], header->ImagingBoundingBox[1], - header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]); - fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet); - fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog); - fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge); - fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0], - header->Margins[1]); - fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed); - fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition); - fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight); - fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint); - fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint); - fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies); - fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation); - fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp); - fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0], - header->PageSize[1]); - fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations); - fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch); - fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble); - fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth); - fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight); - fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType); - fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header->cupsBitsPerColor); - fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header->cupsBitsPerPixel); - fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header->cupsBytesPerLine); - fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header->cupsColorOrder); - fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header->cupsColorSpace); - fprintf(stderr, "DEBUG: cupsCompression = %d\n", header->cupsCompression); - fprintf(stderr, "DEBUG: cupsRowCount = %d\n", header->cupsRowCount); - fprintf(stderr, "DEBUG: cupsRowFeed = %d\n", header->cupsRowFeed); - fprintf(stderr, "DEBUG: cupsRowStep = %d\n", header->cupsRowStep); - - /* - * Figure out the color model and spec strings... - */ - - switch (header->cupsColorSpace) - { - case CUPS_CSPACE_K : - colormodel = "Black"; - break; - case CUPS_CSPACE_W : - colormodel = "Gray"; - break; - default : - case CUPS_CSPACE_RGB : - colormodel = "RGB"; - break; - case CUPS_CSPACE_CMYK : - colormodel = "CMYK"; - break; - } - - if (header->HWResolution[0] != header->HWResolution[1]) - snprintf(resolution, sizeof(resolution), "%dx%ddpi", - header->HWResolution[0], header->HWResolution[1]); - else - snprintf(resolution, sizeof(resolution), "%ddpi", - header->HWResolution[0]); - - if (!header->MediaType[0]) - strcpy(header->MediaType, "Plain"); - - /* - * Load the appropriate color profiles... - */ - - RGB = NULL; - CMYK = NULL; - - fputs("DEBUG: Attempting to load color profiles using the following values:\n", stderr); - fprintf(stderr, "DEBUG: ColorModel = %s\n", colormodel); - fprintf(stderr, "DEBUG: MediaType = %s\n", header->MediaType); - fprintf(stderr, "DEBUG: Resolution = %s\n", resolution); - - if (header->cupsColorSpace == CUPS_CSPACE_RGB || - header->cupsColorSpace == CUPS_CSPACE_W) - RGB = cupsRGBLoad(ppd, colormodel, header->MediaType, resolution); - else - RGB = NULL; - - CMYK = cupsCMYKLoad(ppd, colormodel, header->MediaType, resolution); - - if (RGB) - fputs("DEBUG: Loaded RGB separation from PPD.\n", stderr); - - if (CMYK) - fputs("DEBUG: Loaded CMYK separation from PPD.\n", stderr); - else - { - fputs("DEBUG: Loading default CMYK separation.\n", stderr); - CMYK = cupsCMYKNew(4); - } - - PrinterPlanes = CMYK->num_channels; - - fprintf(stderr, "DEBUG: PrinterPlanes = %d\n", PrinterPlanes); - - /* - * Get the dithering parameters... - */ - - switch (PrinterPlanes) - { - case 1 : /* K */ - DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Black"); - break; - - case 2 : /* Kk */ - DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Black"); - DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "LightBlack"); - break; - - case 3 : /* CMY */ - DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Cyan"); - DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Magenta"); - DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Yellow"); - break; - - case 4 : /* CMYK */ - DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Cyan"); - DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Magenta"); - DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Yellow"); - DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Black"); - break; - - case 6 : /* CcMmYK */ - DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Cyan"); - DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "LightCyan"); - DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Magenta"); - DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "LightMagenta"); - DitherLuts[4] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Yellow"); - DitherLuts[5] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Black"); - break; - - case 7 : /* CcMmYKk */ - DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Cyan"); - DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "LightCyan"); - DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Magenta"); - DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "LightMagenta"); - DitherLuts[4] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Yellow"); - DitherLuts[5] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Black"); - DitherLuts[6] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "LightBlack"); - break; - } - - for (plane = 0; plane < PrinterPlanes; plane ++) - { - DitherStates[plane] = cupsDitherNew(header->cupsWidth); - - if (!DitherLuts[plane]) - DitherLuts[plane] = cupsLutNew(2, default_lut); - } - - if (DitherLuts[0][4095].pixel > 1) - BitPlanes = 2; - else - BitPlanes = 1; - - /* - * Initialize the printer... - */ - - printf("\033@"); - - if (ppd->model_number & ESCP_REMOTE) - { - /* - * Go into remote mode... - */ - - cupsWritePrintData("\033(R\010\000\000REMOTE1", 13); - - /* - * Disable status reporting... - */ - - cupsWritePrintData("ST\002\000\000\000", 6); - - /* - * Enable borderless printing... - */ - - if ((attr = ppdFindAttr(ppd, "cupsESCPFP", NULL)) != NULL && attr->value) - { - /* - * Set horizontal offset... - */ - - i = atoi(attr->value); - - cupsWritePrintData("FP\003\000\000", 5); - putchar(i & 255); - putchar(i >> 8); - } - - /* - * Set media type... - */ - - if (header->cupsMediaType) - { - sprintf(spec, "%d", header->cupsMediaType); - - if ((attr = ppdFindAttr(ppd, "cupsESCPSN0", spec)) != NULL && attr->value) - { - /* - * Set feed sequence... - */ - - cupsWritePrintData("SN\003\000\000\000", 6); - putchar(atoi(attr->value)); - } - - if ((attr = ppdFindAttr(ppd, "cupsESCPSN1", spec)) != NULL && attr->value) - { - /* - * Set platten gap... - */ - - cupsWritePrintData("SN\003\000\000\001", 6); - putchar(atoi(attr->value)); - } - - if ((attr = ppdFindAttr(ppd, "cupsESCPSN2", spec)) != NULL && attr->value) - { - /* - * Paper feeding/ejecting sequence... - */ - - cupsWritePrintData("SN\003\000\000\002", 6); - putchar(atoi(attr->value)); - } - - if ((attr = ppdFindAttr(ppd, "cupsESCPSN6", spec)) != NULL && attr->value) - { - /* - * Eject delay... - */ - - cupsWritePrintData("SN\003\000\000\006", 6); - putchar(atoi(attr->value)); - } - - if ((attr = ppdFindAttr(ppd, "cupsESCPMT", spec)) != NULL && attr->value) - { - /* - * Set media type. - */ - - cupsWritePrintData("MT\003\000\000\000", 6); - putchar(atoi(attr->value)); - } - - if ((attr = ppdFindAttr(ppd, "cupsESCPPH", spec)) != NULL && attr->value) - { - /* - * Set paper thickness. - */ - - cupsWritePrintData("PH\002\000\000", 5); - putchar(atoi(attr->value)); - } - } - - sprintf(spec, "%d", header->MediaPosition); - - if (header->MediaPosition) - { - if ((attr = ppdFindAttr(ppd, "cupsESCPPC", spec)) != NULL && attr->value) - { - /* - * Paper check. - */ - - cupsWritePrintData("PC\002\000\000", 5); - putchar(atoi(attr->value)); - } - - if ((attr = ppdFindAttr(ppd, "cupsESCPPP", spec)) != NULL && attr->value) - { - /* - * Paper path. - */ - - int a, b; - - a = b = 0; - sscanf(attr->value, "%d%d", &a, &b); - - cupsWritePrintData("PP\003\000\000", 5); - putchar(a); - putchar(b); - } - - if ((attr = ppdFindAttr(ppd, "cupsESCPEX", spec)) != NULL && attr->value) - { - /* - * Set media position. - */ - - cupsWritePrintData("EX\006\000\000\000\000\000\005", 9); - putchar(atoi(attr->value)); - } - } - - if ((attr = ppdFindAttr(ppd, "cupsESCPMS", spec)) != NULL && attr->value) - { - /* - * Set media size... - */ - - cupsWritePrintData("MS\010\000\000", 5); - putchar(atoi(attr->value)); - - switch (header->PageSize[1]) - { - case 1191 : /* A3 */ - putchar(0x01); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - break; - case 1032 : /* B4 */ - putchar(0x02); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - break; - case 842 : /* A4 */ - putchar(0x03); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - break; - case 595 : /* A4.Transverse */ - putchar(0x03); - putchar(0x01); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - break; - case 729 : /* B5 */ - putchar(0x04); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - break; - case 516 : /* B5.Transverse */ - putchar(0x04); - putchar(0x01); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - break; - case 1369 : /* Super A3/B */ - putchar(0x20); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - break; - case 792 : /* Letter */ - putchar(0x08); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - break; - case 612 : /* Letter.Transverse */ - putchar(0x08); - putchar(0x01); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - break; - case 1004 : /* Legal */ - putchar(0x0a); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - break; - case 1224 : /* Tabloid */ - putchar(0x2d); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - putchar(0x00); - break; - default : /* Custom size */ - putchar(0xff); - putchar(0xff); - i = 360 * header->PageSize[0] / 72; - putchar(i); - putchar(i >> 8); - i = 360 * header->PageSize[1] / 72; - putchar(i); - putchar(i >> 8); - break; - } - } - - sprintf(spec, "%d", header->CutMedia); - - if ((attr = ppdFindAttr(ppd, "cupsESCPAC", spec)) != NULL && attr->value) - { - /* - * Enable/disable cutter. - */ - - cupsWritePrintData("AC\002\000\000", 5); - putchar(atoi(attr->value)); - - if ((attr = ppdFindAttr(ppd, "cupsESCPSN80", header->MediaType)) != NULL && attr->value) - { - /* - * Cutting method... - */ - - cupsWritePrintData("SN\003\000\000\200", 6); - putchar(atoi(attr->value)); - } - - if ((attr = ppdFindAttr(ppd, "cupsESCPSN81", header->MediaType)) != NULL && attr->value) - { - /* - * Cutting pressure... - */ - - cupsWritePrintData("SN\003\000\000\201", 6); - putchar(atoi(attr->value)); - } - } - - if ((attr = ppdFindAttr(ppd, "cupsESCPCO", spec)) != NULL && attr->value) - { - /* - * Enable/disable cutter. - */ - - cupsWritePrintData("CO\010\000\000\000", 6); - putchar(atoi(attr->value)); - cupsWritePrintData("\000\000\000\000\000", 5); - } - - /* - * Exit remote mode... - */ - - cupsWritePrintData("\033\000\000\000", 4); - } - - /* - * Enter graphics mode... - */ - - cupsWritePrintData("\033(G\001\000\001", 6); - - /* - * Set the line feed increment... - */ - - /* TODO: get this from the PPD file... */ - for (units = 1440; units < header->HWResolution[0]; units *= 2); - - if (ppd->model_number & ESCP_EXT_UNITS) - { - cupsWritePrintData("\033(U\005\000", 5); - putchar(units / header->HWResolution[1]); - putchar(units / header->HWResolution[1]); - putchar(units / header->HWResolution[0]); - putchar(units); - putchar(units >> 8); - } - else - { - cupsWritePrintData("\033(U\001\000", 5); - putchar(3600 / header->HWResolution[1]); - } - - /* - * Set the page length... - */ - - PrinterLength = header->PageSize[1] * header->HWResolution[1] / 72; - - if (ppd->model_number & ESCP_PAGE_SIZE) - { - /* - * Set page size (expands bottom margin)... - */ - - cupsWritePrintData("\033(S\010\000", 5); - - i = header->PageSize[0] * header->HWResolution[1] / 72; - putchar(i); - putchar(i >> 8); - putchar(i >> 16); - putchar(i >> 24); - - i = header->PageSize[1] * header->HWResolution[1] / 72; - putchar(i); - putchar(i >> 8); - putchar(i >> 16); - putchar(i >> 24); - } - else - { - cupsWritePrintData("\033(C\002\000", 5); - putchar(PrinterLength & 255); - putchar(PrinterLength >> 8); - } - - /* - * Set the top and bottom margins... - */ - - PrinterTop = (int)((ppd->sizes[1].length - ppd->sizes[1].top) * - header->HWResolution[1] / 72.0); - - if (ppd->model_number & ESCP_EXT_MARGINS) - { - cupsWritePrintData("\033(c\010\000", 5); - - putchar(PrinterTop); - putchar(PrinterTop >> 8); - putchar(PrinterTop >> 16); - putchar(PrinterTop >> 24); - - putchar(PrinterLength); - putchar(PrinterLength >> 8); - putchar(PrinterLength >> 16); - putchar(PrinterLength >> 24); - } - else - { - cupsWritePrintData("\033(c\004\000", 5); - - putchar(PrinterTop & 255); - putchar(PrinterTop >> 8); - - putchar(PrinterLength & 255); - putchar(PrinterLength >> 8); - } - - /* - * Set the top position... - */ - - cupsWritePrintData("\033(V\002\000\000\000", 7); - - /* - * Enable unidirectional printing depending on the mode... - */ - - if ((attr = cupsFindAttr(ppd, "cupsESCPDirection", colormodel, - header->MediaType, resolution, spec, - sizeof(spec))) != NULL) - printf("\033U%c", atoi(attr->value)); - - /* - * Enable/disable microweaving as needed... - */ - - if ((attr = cupsFindAttr(ppd, "cupsESCPMicroWeave", colormodel, - header->MediaType, resolution, spec, - sizeof(spec))) != NULL) - printf("\033(i\001%c%c", 0, atoi(attr->value)); - - /* - * Set the dot size and print speed as needed... - */ - - if ((attr = cupsFindAttr(ppd, "cupsESCPDotSize", colormodel, - header->MediaType, resolution, spec, - sizeof(spec))) != NULL) - printf("\033(e\002%c%c%c", 0, 0, atoi(attr->value)); - - if (ppd->model_number & ESCP_ESCK) - { - /* - * Set the print mode... - */ - - if (PrinterPlanes == 1) - { - /* - * Fast black printing. - */ - - cupsWritePrintData("\033(K\002\000\000\001", 7); - } - else - { - /* - * Color printing. - */ - - cupsWritePrintData("\033(K\002\000\000\002", 7); - } - } - - /* - * Get softweave settings from header... - */ - - if (header->cupsRowCount <= 1) - { - DotRowCount = 1; - DotColStep = 1; - DotRowStep = 1; - DotRowFeed = 1; - } - else - { - DotRowCount = header->cupsRowCount; - DotRowFeed = header->cupsRowFeed; - DotRowStep = header->cupsRowStep % 100; - DotColStep = header->cupsRowStep / 100; - - if (DotColStep == 0) - DotColStep ++; - } - - /* - * Setup softweave parameters... - */ - - DotRowCurrent = 0; - DotRowMax = DotRowCount * DotRowStep; - DotBufferSize = (header->cupsWidth / DotColStep * BitPlanes + 7) / 8; - - fprintf(stderr, "DEBUG: DotBufferSize = %d\n", DotBufferSize); - fprintf(stderr, "DEBUG: DotColStep = %d\n", DotColStep); - fprintf(stderr, "DEBUG: DotRowMax = %d\n", DotRowMax); - fprintf(stderr, "DEBUG: DotRowStep = %d\n", DotRowStep); - fprintf(stderr, "DEBUG: DotRowFeed = %d\n", DotRowFeed); - fprintf(stderr, "DEBUG: DotRowCount = %d\n", DotRowCount); - - DotAvailList = NULL; - DotUsedList = NULL; - DotBuffers[0] = NULL; - - fprintf(stderr, "DEBUG: model_number = %x\n", ppd->model_number); - - if (DotRowMax > 1) - { - /* - * Compute offsets for the color jets on the print head... - */ - - bands = DotRowStep * DotColStep * PrinterPlanes * 4; - - memset(DotRowOffset, 0, sizeof(DotRowOffset)); - - if (PrinterPlanes == 1) - { - /* - * Use full height of print head... - */ - - if ((attr = ppdFindAttr(ppd, "cupsESCPBlack", resolution)) != NULL && - attr->value) - { - /* - * Use custom black head data... - */ - - sscanf(attr->value, "%d%d", &DotRowCount, &DotRowStep); - } - } - else if (ppd->model_number & ESCP_STAGGER) - { - /* - * Use staggered print head... - */ - - fputs("DEBUG: Offset head detected...\n", stderr); - - if ((attr = ppdFindAttr(ppd, "cupsESCPOffsets", resolution)) != NULL && - attr->value) - { - /* - * Use only 1/3 of the print head when printing color... - */ - - sscanf(attr->value, "%d%d%d%d", DotRowOffset + 0, - DotRowOffset + 1, DotRowOffset + 2, DotRowOffset + 3); - } - } - - for (i = 0; i < PrinterPlanes; i ++) - fprintf(stderr, "DEBUG: DotRowOffset[%d] = %d\n", i, DotRowOffset[i]); - - /* - * Allocate bands... - */ - - for (i = 0; i < bands; i ++) - { - band = (cups_weave_t *)calloc(1, sizeof(cups_weave_t)); - band->next = DotAvailList; - DotAvailList = band; - - band->buffer = calloc(DotRowCount, DotBufferSize); - } - - if (!DotAvailList) - { - fputs("ERROR: Unable to allocate band list\n", stderr); - exit(1); - } - - fputs("DEBUG: Pointer list at start of page...\n", stderr); - - for (band = DotAvailList; band != NULL; band = band->next) - fprintf(stderr, "DEBUG: %p\n", band); - - fputs("DEBUG: ----END----\n", stderr); - - /* - * Fill the initial bands... - */ - - modrow = DotColStep * DotRowStep; - - if (DotRowFeed == 0) - { - /* - * Automatically compute the optimal feed value... - */ - - DotRowFeed = DotRowCount / DotColStep - DotRowStep; - - while ((((DotRowFeed % 2) == 0) == ((DotRowCount % 2) == 0) || - ((DotRowFeed % 3) == 0) == ((DotRowCount % 3) == 0) || - ((DotRowFeed % 5) == 0) == ((DotRowCount % 5) == 0)) && - DotRowFeed > 1) - DotRowFeed --; - - if (DotRowFeed < 1) - DotRowFeed = 1; - - fprintf(stderr, "DEBUG: Auto DotRowFeed = %d, modrow=%d...\n", - DotRowFeed, modrow); - } - - memset(DotBands, 0, sizeof(DotBands)); - - for (i = modrow, subrow = modrow - 1, y = DotRowFeed; - i > 0; - i --, y += DotRowFeed) - { - while (DotBands[subrow][0]) - { - /* - * This subrow is already used, move to another one... - */ - - subrow = (subrow + 1) % modrow; - } - - for (plane = 0; plane < PrinterPlanes; plane ++) - { - /* - * Pull the next available band from the list... - */ - - band = DotAvailList; - DotAvailList = DotAvailList->next; - DotBands[subrow][plane] = band; - - /* - * Start the band in the first few passes, with the number of rows - * varying to allow for a nice interleaved pattern... - */ - - band->x = subrow / DotRowStep; - band->y = (subrow % DotRowStep) + DotRowOffset[plane]; - band->plane = plane; - band->row = 0; - band->count = DotRowCount - y / DotRowStep; - - if (band->count < 1) - band->count = 1; - else if (band->count > DotRowCount) - band->count = DotRowCount; - - fprintf(stderr, "DEBUG: DotBands[%d][%d] = %p, x = %d, y = %d, plane = %d, count = %d\n", - subrow, plane, band, band->x, band->y, band->plane, band->count); - } - - subrow = (subrow + DotRowFeed) % modrow; - } - } - else - { - /* - * Allocate memory for a single line of graphics... - */ - - ptr = calloc(PrinterPlanes, DotBufferSize); - - for (plane = 0; plane < PrinterPlanes; plane ++, ptr += DotBufferSize) - DotBuffers[plane] = ptr; - } - - /* - * Set the output resolution... - */ - - cupsWritePrintData("\033(D\004\000", 5); - putchar(units); - putchar(units >> 8); - putchar(units * DotRowStep / header->HWResolution[1]); - putchar(units * DotColStep / header->HWResolution[0]); - - /* - * Set the top of form... - */ - - OutputFeed = 0; - - /* - * Allocate buffers as needed... - */ - - PixelBuffer = malloc(header->cupsBytesPerLine); - InputBuffer = malloc(header->cupsWidth * PrinterPlanes * 2); - OutputBuffers[0] = malloc(PrinterPlanes * header->cupsWidth); - - for (i = 1; i < PrinterPlanes; i ++) - OutputBuffers[i] = OutputBuffers[0] + i * header->cupsWidth; - - if (RGB) - CMYKBuffer = malloc(header->cupsWidth * PrinterPlanes); - - CompBuffer = malloc(10 * DotBufferSize * DotRowMax); -} - - -/* - * 'EndPage()' - Finish a page of graphics. - */ - -void -EndPage(ppd_file_t *ppd, /* I - PPD file */ - cups_page_header2_t *header) /* I - Page header */ -{ - int i; /* Looping var */ - cups_weave_t *band, /* Current band */ - *next; /* Next band in list */ - int plane; /* Current plane */ - int subrow; /* Current subrow */ - int subrows; /* Number of subrows */ - - - /* - * Output the last bands of print data as necessary... - */ - - if (DotRowMax > 1) - { - /* - * Move the remaining bands to the used or avail lists... - */ - - subrows = DotRowStep * DotColStep; - - for (subrow = 0; subrow < subrows; subrow ++) - for (plane = 0; plane < PrinterPlanes; plane ++) - { - if (DotBands[subrow][plane]->dirty) - { - /* - * Insert into the used list... - */ - - DotBands[subrow][plane]->count = DotBands[subrow][plane]->row; - - AddBand(DotBands[subrow][plane]); - } - else - { - /* - * Nothing here, so move it to the available list... - */ - - DotBands[subrow][plane]->next = DotAvailList; - DotAvailList = DotBands[subrow][plane]; - } - - DotBands[subrow][plane] = NULL; - } - - /* - * Loop until all bands are written... - */ - - fputs("DEBUG: Pointer list at end of page...\n", stderr); - - for (band = DotUsedList; band != NULL; band = band->next) - fprintf(stderr, "DEBUG: %p (used)\n", band); - for (band = DotAvailList; band != NULL; band = band->next) - fprintf(stderr, "DEBUG: %p (avail)\n", band); - - fputs("DEBUG: ----END----\n", stderr); - - for (band = DotUsedList; band != NULL; band = next) - { - next = band->next; - - OutputBand(ppd, header, band); - - fprintf(stderr, "DEBUG: freeing used band %p, prev = %p, next = %p\n", - band, band->prev, band->next); - - free(band->buffer); - free(band); - } - - /* - * Free memory for the available bands, if any... - */ - - for (band = DotAvailList; band != NULL; band = next) - { - next = band->next; - - fprintf(stderr, "DEBUG: freeing avail band %p, prev = %p, next = %p\n", - band, band->prev, band->next); - - free(band->buffer); - free(band); - } - } - else - free(DotBuffers[0]); - - /* - * Output a page eject sequence... - */ - - putchar(12); - - /* - * Free memory for the page... - */ - - for (i = 0; i < PrinterPlanes; i ++) - { - cupsDitherDelete(DitherStates[i]); - cupsLutDelete(DitherLuts[i]); - } - - free(OutputBuffers[0]); - - free(PixelBuffer); - free(InputBuffer); - free(CompBuffer); - - cupsCMYKDelete(CMYK); - - if (RGB) - { - cupsRGBDelete(RGB); - free(CMYKBuffer); - } -} - - -/* - * 'Shutdown()' - Shutdown a printer. - */ - -void -Shutdown(ppd_file_t *ppd) /* I - PPD file */ -{ - /* - * Reset the printer... - */ - - printf("\033@"); - - if (ppd->model_number & ESCP_REMOTE) - { - /* - * Go into remote mode... - */ - - cupsWritePrintData("\033(R\010\000\000REMOTE1", 13); - - /* - * Load defaults... - */ - - cupsWritePrintData("LD\000\000", 4); - - /* - * Exit remote mode... - */ - - cupsWritePrintData("\033\000\000\000", 4); - } -} - - -/* - * 'AddBand()' - Add a band of data to the used list. - */ - -void -AddBand(cups_weave_t *band) /* I - Band to add */ -{ - cups_weave_t *current, /* Current band */ - *prev; /* Previous band */ - - - if (band->count < 1) - return; - - for (current = DotUsedList, prev = NULL; - current != NULL; - prev = current, current = current->next) - if (band->y < current->y || - (band->y == current->y && band->x < current->x) || - (band->y == current->y && band->x == current->x && - band->plane < current->plane)) - break; - - if (current != NULL) - { - /* - * Insert the band... - */ - - band->next = current; - band->prev = prev; - current->prev = band; - - if (prev != NULL) - prev->next = band; - else - DotUsedList = band; - } - else if (prev != NULL) - { - /* - * Append the band to the end... - */ - - band->prev = prev; - prev->next = band; - band->next = NULL; - } - else - { - /* - * First band in list... - */ - - DotUsedList = band; - band->prev = NULL; - band->next = NULL; - } -} - - -/* - * 'CancelJob()' - Cancel the current job... - */ - -void -CancelJob(int sig) /* I - Signal */ -{ - (void)sig; - - Canceled = 1; -} - - -/* - * 'CompressData()' - Compress a line of graphics. - */ - -void -CompressData(ppd_file_t *ppd, /* I - PPD file information */ - const unsigned char *line, /* I - Data to compress */ - const int length,/* I - Number of bytes */ - int plane, /* I - Color plane */ - int type, /* I - Type of compression */ - const int rows, /* I - Number of lines to write */ - const int xstep, /* I - Spacing between columns */ - const int ystep, /* I - Spacing between lines */ - const int offset)/* I - Head offset */ -{ - register const unsigned char *line_ptr, - /* Current byte pointer */ - *line_end, /* End-of-line byte pointer */ - *start; /* Start of compression sequence */ - register unsigned char *comp_ptr; /* Pointer into compression buffer */ - register int count; /* Count of bytes for output */ - register int bytes; /* Number of bytes per row */ - static int ctable[7][7] = /* Colors */ - { - { 0, 0, 0, 0, 0, 0, 0 }, /* K */ - { 0, 16, 0, 0, 0, 0, 0 }, /* Kk */ - { 2, 1, 4, 0, 0, 0, 0 }, /* CMY */ - { 2, 1, 4, 0, 0, 0, 0 }, /* CMYK */ - { 0, 0, 0, 0, 0, 0, 0 }, - { 2, 18, 1, 17, 4, 0, 0 }, /* CcMmYK */ - { 2, 18, 1, 17, 4, 0, 16 }, /* CcMmYKk */ - }; - - - switch (type) - { - case 0 : - /* - * Do no compression... - */ - - line_ptr = (const unsigned char *)line; - line_end = (const unsigned char *)line + length; - break; - - default : - /* - * Do TIFF pack-bits encoding... - */ - - line_ptr = (const unsigned char *)line; - line_end = (const unsigned char *)line + length; - comp_ptr = CompBuffer; - - while (line_ptr < line_end && (comp_ptr - CompBuffer) < length) - { - if ((line_ptr + 1) >= line_end) - { - /* - * Single byte on the end... - */ - - *comp_ptr++ = 0x00; - *comp_ptr++ = *line_ptr++; - } - else if (line_ptr[0] == line_ptr[1]) - { - /* - * Repeated sequence... - */ - - line_ptr ++; - count = 2; - - while (line_ptr < (line_end - 1) && - line_ptr[0] == line_ptr[1] && - count < 127) - { - line_ptr ++; - count ++; - } - - *comp_ptr++ = 257 - count; - *comp_ptr++ = *line_ptr++; - } - else - { - /* - * Non-repeated sequence... - */ - - start = line_ptr; - line_ptr ++; - count = 1; - - while (line_ptr < (line_end - 1) && - line_ptr[0] != line_ptr[1] && - count < 127) - { - line_ptr ++; - count ++; - } - - *comp_ptr++ = count - 1; - - memcpy(comp_ptr, start, count); - comp_ptr += count; - } - } - - if ((comp_ptr - CompBuffer) < length) - { - line_ptr = (const unsigned char *)CompBuffer; - line_end = (const unsigned char *)comp_ptr; - } - else - { - type = 0; - line_ptr = (const unsigned char *)line; - line_end = (const unsigned char *)line + length; - } - break; - } - - /* - * Position the print head... - */ - - putchar(0x0d); - - if (offset) - { - if (BitPlanes == 1) - cupsWritePrintData("\033(\\\004\000\240\005", 7); - else - printf("\033\\"); - - putchar(offset); - putchar(offset >> 8); - } - - /* - * Send the graphics... - */ - - bytes = length / rows; - - if (ppd->model_number & ESCP_RASTER_ESCI) - { - /* - * Send graphics with ESC i command. - */ - - printf("\033i"); - putchar(ctable[PrinterPlanes - 1][plane]); - putchar(type != 0); - putchar(BitPlanes); - putchar(bytes & 255); - putchar(bytes >> 8); - putchar(rows & 255); - putchar(rows >> 8); - } - else - { - /* - * Set the color if necessary... - */ - - if (PrinterPlanes > 1) - { - plane = ctable[PrinterPlanes - 1][plane]; - - if (plane & 0x10) - printf("\033(r%c%c%c%c", 2, 0, 1, plane & 0x0f); - else - printf("\033r%c", plane); - } - - /* - * Send graphics with ESC . command. - */ - - bytes *= 8; - - printf("\033."); - putchar(type != 0); - putchar(ystep); - putchar(xstep); - putchar(rows); - putchar(bytes & 255); - putchar(bytes >> 8); - } - - cupsWritePrintData(line_ptr, line_end - line_ptr); -} - - -/* - * 'OutputBand()' - Output a band of graphics. - */ - -void -OutputBand(ppd_file_t *ppd, /* I - PPD file */ - cups_page_header2_t *header, /* I - Page header */ - cups_weave_t *band) /* I - Current band */ -{ - int xstep, /* Spacing between columns */ - ystep; /* Spacing between rows */ - - - /* - * Interleaved ESC/P2 graphics... - */ - - OutputFeed = band->y - DotRowCurrent; - DotRowCurrent = band->y; - - fprintf(stderr, "DEBUG: Printing band %p, x = %d, y = %d, plane = %d, count = %d, OutputFeed = %d\n", - band, band->x, band->y, band->plane, band->count, OutputFeed); - - /* - * Compute step values... - */ - - xstep = 3600 * DotColStep / header->HWResolution[0]; - ystep = 3600 * DotRowStep / header->HWResolution[1]; - - /* - * Output the band... - */ - - if (OutputFeed > 0) - { - cupsWritePrintData("\033(v\002\000", 5); - putchar(OutputFeed & 255); - putchar(OutputFeed >> 8); - - OutputFeed = 0; - } - - CompressData(ppd, band->buffer, band->count * DotBufferSize, band->plane, - header->cupsCompression, band->count, xstep, ystep, band->x); - - /* - * Clear the band... - */ - - memset(band->buffer, 0, band->count * DotBufferSize); - band->dirty = 0; - - /* - * Flush the output buffers... - */ - - fflush(stdout); -} - - -/* - * 'ProcessLine()' - Read graphics from the page stream and output as needed. - */ - -void -ProcessLine(ppd_file_t *ppd, /* I - PPD file */ - cups_raster_t *ras, /* I - Raster stream */ - cups_page_header2_t *header, /* I - Page header */ - const int y) /* I - Current scanline */ -{ - int plane, /* Current color plane */ - width, /* Width of line */ - subwidth, /* Width of interleaved row */ - subrow, /* Subrow for interleaved output */ - offset, /* Offset to current line */ - pass, /* Pass number */ - xstep, /* X step value */ - ystep; /* Y step value */ - cups_weave_t *band; /* Current band */ - - - /* - * Read a row of graphics... - */ - - if (!cupsRasterReadPixels(ras, PixelBuffer, header->cupsBytesPerLine)) - return; - - /* - * Perform the color separation... - */ - - width = header->cupsWidth; - subwidth = header->cupsWidth / DotColStep; - xstep = 3600 / header->HWResolution[0]; - ystep = 3600 / header->HWResolution[1]; - - switch (header->cupsColorSpace) - { - case CUPS_CSPACE_W : - if (RGB) - { - cupsRGBDoGray(RGB, PixelBuffer, CMYKBuffer, width); - cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width); - } - else - cupsCMYKDoGray(CMYK, PixelBuffer, InputBuffer, width); - break; - - case CUPS_CSPACE_K : - cupsCMYKDoBlack(CMYK, PixelBuffer, InputBuffer, width); - break; - - default : - case CUPS_CSPACE_RGB : - if (RGB) - { - cupsRGBDoRGB(RGB, PixelBuffer, CMYKBuffer, width); - cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width); - } - else - cupsCMYKDoRGB(CMYK, PixelBuffer, InputBuffer, width); - break; - - case CUPS_CSPACE_CMYK : - cupsCMYKDoCMYK(CMYK, PixelBuffer, InputBuffer, width); - break; - } - - /* - * Dither the pixels... - */ - - for (plane = 0; plane < PrinterPlanes; plane ++) - { - cupsDitherLine(DitherStates[plane], DitherLuts[plane], InputBuffer + plane, - PrinterPlanes, OutputBuffers[plane]); - - if (DotRowMax == 1) - { - /* - * Handle microweaved output... - */ - - if (cupsCheckBytes(OutputBuffers[plane], width)) - continue; - - if (BitPlanes == 1) - cupsPackHorizontal(OutputBuffers[plane], DotBuffers[plane], - width, 0, 1); - else - cupsPackHorizontal2(OutputBuffers[plane], DotBuffers[plane], - width, 1); - - if (OutputFeed > 0) - { - cupsWritePrintData("\033(v\002\000", 5); - putchar(OutputFeed & 255); - putchar(OutputFeed >> 8); - OutputFeed = 0; - } - - CompressData(ppd, DotBuffers[plane], DotBufferSize, plane, 1, 1, - xstep, ystep, 0); - fflush(stdout); - } - else - { - /* - * Handle softweaved output... - */ - - for (pass = 0, subrow = y % DotRowStep; - pass < DotColStep; - pass ++, subrow += DotRowStep) - { - /* - * See if we need to output the band... - */ - - band = DotBands[subrow][plane]; - offset = band->row * DotBufferSize; - - if (BitPlanes == 1) - cupsPackHorizontal(OutputBuffers[plane] + pass, - band->buffer + offset, subwidth, 0, DotColStep); - else - cupsPackHorizontal2(OutputBuffers[plane] + pass, - band->buffer + offset, subwidth, DotColStep); - - band->row ++; - band->dirty |= !cupsCheckBytes(band->buffer + offset, DotBufferSize); - if (band->row >= band->count) - { - if (band->dirty) - { - /* - * Dirty band needs to be added to the used list... - */ - - AddBand(band); - - /* - * Then find a new band... - */ - - if (DotAvailList == NULL) - { - OutputBand(ppd, header, DotUsedList); - - DotBands[subrow][plane] = DotUsedList; - DotUsedList->x = band->x; - DotUsedList->y = band->y + band->count * DotRowStep; - DotUsedList->plane = band->plane; - DotUsedList->row = 0; - DotUsedList->count = DotRowCount; - DotUsedList = DotUsedList->next; - } - else - { - DotBands[subrow][plane] = DotAvailList; - DotAvailList->x = band->x; - DotAvailList->y = band->y + band->count * DotRowStep; - DotAvailList->plane = band->plane; - DotAvailList->row = 0; - DotAvailList->count = DotRowCount; - DotAvailList = DotAvailList->next; - } - } - else - { - /* - * This band isn't dirty, so reuse it... - */ - - fprintf(stderr, "DEBUG: Blank band %p, x = %d, y = %d, plane = %d, count = %d\n", - band, band->x, band->y, band->plane, band->count); - - band->y += band->count * DotRowStep; - band->row = 0; - band->count = DotRowCount; - } - } - } - } - } - - if (DotRowMax == 1) - OutputFeed ++; -} - - -/* - * 'main()' - Main entry and processing of driver. - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments */ - char *argv[]) /* I - Command-line arguments */ -{ - int fd; /* File descriptor */ - cups_raster_t *ras; /* Raster stream for printing */ - cups_page_header2_t header; /* Page header from file */ - int page; /* Current page */ - int y; /* Current line */ - ppd_file_t *ppd; /* PPD file */ - int num_options; /* Number of options */ - cups_option_t *options; /* Options */ -#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) - struct sigaction action; /* Actions for POSIX signals */ -#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ - - - /* - * Make sure status messages are not buffered... - */ - - setbuf(stderr, NULL); - - /* - * Check command-line... - */ - - if (argc < 6 || argc > 7) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("%s job-id user title copies options [file]"), - "rastertoescpx"); - return (1); - } - - num_options = cupsParseOptions(argv[5], 0, &options); - - /* - * Open the PPD file... - */ - - ppd = ppdOpenFile(getenv("PPD")); - - if (!ppd) - { - ppd_status_t status; /* PPD error */ - int linenum; /* Line number */ - - _cupsLangPrintFilter(stderr, "ERROR", - _("The PPD file could not be opened.")); - - status = ppdLastError(&linenum); - - fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum); - - return (1); - } - - ppdMarkDefaults(ppd); - cupsMarkOptions(ppd, num_options, options); - - /* - * Open the page stream... - */ - - if (argc == 7) - { - if ((fd = open(argv[6], O_RDONLY)) == -1) - { - _cupsLangPrintError("ERROR", _("Unable to open raster file")); - return (1); - } - } - else - fd = 0; - - ras = cupsRasterOpen(fd, CUPS_RASTER_READ); - - /* - * Register a signal handler to eject the current page if the - * job is cancelled. - */ - - Canceled = 0; - -#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ - sigset(SIGTERM, CancelJob); -#elif defined(HAVE_SIGACTION) - memset(&action, 0, sizeof(action)); - - sigemptyset(&action.sa_mask); - action.sa_handler = CancelJob; - sigaction(SIGTERM, &action, NULL); -#else - signal(SIGTERM, CancelJob); -#endif /* HAVE_SIGSET */ - - /* - * Initialize the print device... - */ - - Setup(ppd); - - /* - * Process pages as needed... - */ - - page = 0; - - while (cupsRasterReadHeader2(ras, &header)) - { - /* - * Write a status message with the page number and number of copies. - */ - - if (Canceled) - break; - - page ++; - - fprintf(stderr, "PAGE: %d 1\n", page); - _cupsLangPrintFilter(stderr, "INFO", _("Starting page %d."), page); - - StartPage(ppd, &header); - - for (y = 0; y < header.cupsHeight; y ++) - { - /* - * Let the user know how far we have progressed... - */ - - if (Canceled) - break; - - if ((y & 127) == 0) - { - _cupsLangPrintFilter(stderr, "INFO", - _("Printing page %d, %d%% complete."), - page, 100 * y / header.cupsHeight); - fprintf(stderr, "ATTR: job-media-progress=%d\n", - 100 * y / header.cupsHeight); - } - - /* - * Read and write a line of graphics or whitespace... - */ - - ProcessLine(ppd, ras, &header, y); - } - - /* - * Eject the page... - */ - - _cupsLangPrintFilter(stderr, "INFO", _("Finished page %d."), page); - - EndPage(ppd, &header); - - if (Canceled) - break; - } - - Shutdown(ppd); - - cupsFreeOptions(num_options, options); - - cupsRasterClose(ras); - - if (fd != 0) - close(fd); - - if (page == 0) - { - _cupsLangPrintFilter(stderr, "ERROR", _("No pages were found.")); - return (1); - } - else - { - _cupsLangPrintFilter(stderr, "INFO", _("Ready to print.")); - return (0); - } -} - - -/* - * End of "$Id$". - */ diff --git a/driver/rastertopclx.c b/driver/rastertopclx.c deleted file mode 100644 index 42f008220..000000000 --- a/driver/rastertopclx.c +++ /dev/null @@ -1,1956 +0,0 @@ -/* - * "$Id$" - * - * Advanced HP Page Control Language and Raster Transfer Language - * filter for CUPS. - * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * StartPage() - Start a page of graphics. - * EndPage() - Finish a page of graphics. - * Shutdown() - Shutdown a printer. - * CancelJob() - Cancel the current job... - * CompressData() - Compress a line of graphics. - * OutputLine() - Output the specified number of lines of graphics. - * ReadLine() - Read graphics from the page stream. - * main() - Main entry and processing of driver. - */ - -/* - * Include necessary headers... - */ - -#include "driver.h" -#include -#include -#include "pcl-common.h" -#include - - -/* - * Output modes... - */ - -typedef enum -{ - OUTPUT_BITMAP, /* Output bitmap data from RIP */ - OUTPUT_INVERBIT, /* Output inverted bitmap data */ - OUTPUT_RGB, /* Output 24-bit RGB data from RIP */ - OUTPUT_DITHERED /* Output dithered data */ -} pcl_output_t; - - -/* - * Globals... - */ - -cups_rgb_t *RGB; /* RGB color separation data */ -cups_cmyk_t *CMYK; /* CMYK color separation data */ -unsigned char *PixelBuffer, /* Pixel buffer */ - *CMYKBuffer, /* CMYK buffer */ - *OutputBuffers[6], /* Output buffers */ - *DotBuffers[6], /* Bit buffers */ - *CompBuffer, /* Compression buffer */ - *SeedBuffer, /* Mode 3 seed buffers */ - BlankValue; /* The blank value */ -short *InputBuffer; /* Color separation buffer */ -cups_lut_t *DitherLuts[6]; /* Lookup tables for dithering */ -cups_dither_t *DitherStates[6]; /* Dither state tables */ -int PrinterPlanes, /* Number of color planes */ - SeedInvalid, /* Contents of seed buffer invalid? */ - DotBits[6], /* Number of bits per color */ - DotBufferSizes[6], /* Size of one row of color dots */ - DotBufferSize, /* Size of complete line */ - OutputFeed, /* Number of lines to skip */ - Page; /* Current page number */ -pcl_output_t OutputMode; /* Output mode - see OUTPUT_ consts */ -const int ColorOrders[7][7] = /* Order of color planes */ - { - { 0, 0, 0, 0, 0, 0, 0 }, /* Black */ - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 1, 2, 0, 0, 0, 0 }, /* CMY */ - { 3, 0, 1, 2, 0, 0, 0 }, /* KCMY */ - { 0, 0, 0, 0, 0, 0, 0 }, - { 5, 0, 1, 2, 3, 4, 0 }, /* KCMYcm */ - { 5, 0, 1, 2, 3, 4, 6 } /* KCMYcmk */ - }; -int Canceled; /* Is the job canceled? */ - - -/* - * Prototypes... - */ - -void StartPage(ppd_file_t *ppd, cups_page_header2_t *header, int job_id, - const char *user, const char *title, int num_options, - cups_option_t *options); -void EndPage(ppd_file_t *ppd, cups_page_header2_t *header); -void Shutdown(ppd_file_t *ppd, int job_id, const char *user, - const char *title, int num_options, cups_option_t *options); - -void CancelJob(int sig); -void CompressData(unsigned char *line, int length, int plane, int pend, - int type); -void OutputLine(ppd_file_t *ppd, cups_page_header2_t *header); -int ReadLine(cups_raster_t *ras, cups_page_header2_t *header); - - -/* - * 'StartPage()' - Start a page of graphics. - */ - -void -StartPage(ppd_file_t *ppd, /* I - PPD file */ - cups_page_header2_t *header, /* I - Page header */ - int job_id, /* I - Job ID */ - const char *user, /* I - User printing job */ - const char *title, /* I - Title of job */ - int num_options, - /* I - Number of command-line options */ - cups_option_t *options) /* I - Command-line options */ -{ - int i; /* Temporary/looping var */ - int plane; /* Current plane */ - char s[255]; /* Temporary value */ - const char *colormodel; /* Color model string */ - char resolution[PPD_MAX_NAME], - /* Resolution string */ - spec[PPD_MAX_NAME]; /* PPD attribute name */ - ppd_attr_t *attr; /* Attribute from PPD file */ - ppd_choice_t *choice; /* Selected option */ - const int *order; /* Order to use */ - int xorigin, /* X origin of page */ - yorigin; /* Y origin of page */ - static const float default_lut[2] = /* Default dithering lookup table */ - { - 0.0, - 1.0 - }; - - - /* - * Debug info... - */ - - fprintf(stderr, "DEBUG: StartPage...\n"); - fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass); - fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor); - fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType); - fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType); - - fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance); - fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia); - fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate); - fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia); - fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex); - fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0], - header->HWResolution[1]); - fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n", - header->ImagingBoundingBox[0], header->ImagingBoundingBox[1], - header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]); - fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet); - fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog); - fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge); - fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0], - header->Margins[1]); - fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed); - fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition); - fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight); - fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint); - fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint); - fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies); - fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation); - fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp); - fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0], - header->PageSize[1]); - fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations); - fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch); - fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble); - fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth); - fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight); - fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType); - fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header->cupsBitsPerColor); - fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header->cupsBitsPerPixel); - fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header->cupsBytesPerLine); - fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header->cupsColorOrder); - fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header->cupsColorSpace); - fprintf(stderr, "DEBUG: cupsCompression = %d\n", header->cupsCompression); - -#ifdef __APPLE__ - /* - * MacOS X 10.2.x doesn't set most of the page device attributes, so check - * the options and set them accordingly... - */ - - if (ppdIsMarked(ppd, "Duplex", "DuplexNoTumble")) - { - header->Duplex = CUPS_TRUE; - header->Tumble = CUPS_FALSE; - } - else if (ppdIsMarked(ppd, "Duplex", "DuplexTumble")) - { - header->Duplex = CUPS_TRUE; - header->Tumble = CUPS_TRUE; - } - - fprintf(stderr, "DEBUG: num_options=%d\n", num_options); - - for (i = 0; i < num_options; i ++) - fprintf(stderr, "DEBUG: options[%d]=[\"%s\" \"%s\"]\n", i, - options[i].name, options[i].value); -#endif /* __APPLE__ */ - - /* - * Figure out the color model and spec strings... - */ - - switch (header->cupsColorSpace) - { - case CUPS_CSPACE_K : - colormodel = "Black"; - break; - case CUPS_CSPACE_W : - colormodel = "Gray"; - break; - default : - case CUPS_CSPACE_RGB : - colormodel = "RGB"; - break; - case CUPS_CSPACE_CMY : - colormodel = "CMY"; - break; - case CUPS_CSPACE_CMYK : - colormodel = "CMYK"; - break; - } - - if (header->HWResolution[0] != header->HWResolution[1]) - snprintf(resolution, sizeof(resolution), "%dx%ddpi", - header->HWResolution[0], header->HWResolution[1]); - else - snprintf(resolution, sizeof(resolution), "%ddpi", - header->HWResolution[0]); - - if (!header->MediaType[0]) - strcpy(header->MediaType, "PLAIN"); - - /* - * Get the dithering parameters... - */ - - BlankValue = 0x00; - - if (header->cupsBitsPerColor == 1) - { - /* - * Use raw bitmap mode... - */ - - switch (header->cupsColorSpace) - { - case CUPS_CSPACE_K : - OutputMode = OUTPUT_BITMAP; - PrinterPlanes = 1; - break; - case CUPS_CSPACE_W : - OutputMode = OUTPUT_INVERBIT; - PrinterPlanes = 1; - break; - default : - case CUPS_CSPACE_RGB : - OutputMode = OUTPUT_INVERBIT; - PrinterPlanes = 3; - break; - case CUPS_CSPACE_CMY : - OutputMode = OUTPUT_BITMAP; - PrinterPlanes = 3; - break; - case CUPS_CSPACE_CMYK : - OutputMode = OUTPUT_BITMAP; - PrinterPlanes = 4; - break; - } - - if (OutputMode == OUTPUT_INVERBIT) - BlankValue = 0xff; - - DotBufferSize = header->cupsBytesPerLine; - - memset(DitherLuts, 0, sizeof(DitherLuts)); - memset(DitherStates, 0, sizeof(DitherStates)); - } - else if (header->cupsColorSpace == CUPS_CSPACE_RGB && - (ppd->model_number & PCL_RASTER_RGB24)) - { - /* - * Use 24-bit RGB output mode... - */ - - OutputMode = OUTPUT_RGB; - PrinterPlanes = 3; - DotBufferSize = header->cupsBytesPerLine; - - if (header->cupsCompression == 10) - BlankValue = 0xff; - - memset(DitherLuts, 0, sizeof(DitherLuts)); - memset(DitherStates, 0, sizeof(DitherStates)); - } - else if ((header->cupsColorSpace == CUPS_CSPACE_K || - header->cupsColorSpace == CUPS_CSPACE_W) && - (ppd->model_number & PCL_RASTER_RGB24) && - header->cupsCompression == 10) - { - /* - * Use 24-bit RGB output mode for grayscale/black output... - */ - - OutputMode = OUTPUT_RGB; - PrinterPlanes = 1; - DotBufferSize = header->cupsBytesPerLine; - - if (header->cupsColorSpace == CUPS_CSPACE_W) - BlankValue = 0xff; - - memset(DitherLuts, 0, sizeof(DitherLuts)); - memset(DitherStates, 0, sizeof(DitherStates)); - } - else - { - /* - * Use dithered output mode... - */ - - OutputMode = OUTPUT_DITHERED; - - /* - * Load the appropriate color profiles... - */ - - RGB = NULL; - CMYK = NULL; - - fputs("DEBUG: Attempting to load color profiles using the following values:\n", stderr); - fprintf(stderr, "DEBUG: ColorModel = %s\n", colormodel); - fprintf(stderr, "DEBUG: MediaType = %s\n", header->MediaType); - fprintf(stderr, "DEBUG: Resolution = %s\n", resolution); - - if (header->cupsColorSpace == CUPS_CSPACE_RGB || - header->cupsColorSpace == CUPS_CSPACE_W) - RGB = cupsRGBLoad(ppd, colormodel, header->MediaType, resolution); - - CMYK = cupsCMYKLoad(ppd, colormodel, header->MediaType, resolution); - - if (RGB) - fputs("DEBUG: Loaded RGB separation from PPD.\n", stderr); - - if (CMYK) - fputs("DEBUG: Loaded CMYK separation from PPD.\n", stderr); - else - { - fputs("DEBUG: Loading default K separation.\n", stderr); - CMYK = cupsCMYKNew(1); - } - - PrinterPlanes = CMYK->num_channels; - - /* - * Use dithered mode... - */ - - switch (PrinterPlanes) - { - case 1 : /* K */ - DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Black"); - break; - - case 3 : /* CMY */ - DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Cyan"); - DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Magenta"); - DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Yellow"); - break; - - case 4 : /* CMYK */ - DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Cyan"); - DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Magenta"); - DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Yellow"); - DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Black"); - break; - - case 6 : /* CcMmYK */ - DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Cyan"); - DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "LightCyan"); - DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Magenta"); - DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "LightMagenta"); - DitherLuts[4] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Yellow"); - DitherLuts[5] = cupsLutLoad(ppd, colormodel, header->MediaType, - resolution, "Black"); - break; - } - - for (plane = 0; plane < PrinterPlanes; plane ++) - { - if (!DitherLuts[plane]) - DitherLuts[plane] = cupsLutNew(2, default_lut); - - if (DitherLuts[plane][4095].pixel > 1) - DotBits[plane] = 2; - else - DotBits[plane] = 1; - - DitherStates[plane] = cupsDitherNew(header->cupsWidth); - - if (!DitherLuts[plane]) - DitherLuts[plane] = cupsLutNew(2, default_lut); - } - } - - fprintf(stderr, "DEBUG: PrinterPlanes = %d\n", PrinterPlanes); - - /* - * Initialize the printer... - */ - - if ((attr = ppdFindAttr(ppd, "cupsInitialNulls", NULL)) != NULL) - for (i = atoi(attr->value); i > 0; i --) - putchar(0); - - if (Page == 1 && (ppd->model_number & PCL_PJL)) - { - pjl_escape(); - - /* - * PJL job setup... - */ - - pjl_set_job(job_id, user, title); - - if ((attr = ppdFindAttr(ppd, "cupsPJL", "StartJob")) != NULL) - pjl_write(ppd, attr->value, NULL, job_id, user, title, num_options, - options); - - snprintf(spec, sizeof(spec), "RENDERMODE.%s", colormodel); - if ((attr = ppdFindAttr(ppd, "cupsPJL", spec)) != NULL) - printf("@PJL SET RENDERMODE=%s\r\n", attr->value); - - snprintf(spec, sizeof(spec), "COLORSPACE.%s", colormodel); - if ((attr = ppdFindAttr(ppd, "cupsPJL", spec)) != NULL) - printf("@PJL SET COLORSPACE=%s\r\n", attr->value); - - snprintf(spec, sizeof(spec), "RENDERINTENT.%s", colormodel); - if ((attr = ppdFindAttr(ppd, "cupsPJL", spec)) != NULL) - printf("@PJL SET RENDERINTENT=%s\r\n", attr->value); - - if ((attr = ppdFindAttr(ppd, "cupsPJL", "Duplex")) != NULL) - { - sprintf(s, "%d", header->Duplex); - pjl_write(ppd, attr->value, s, job_id, user, title, num_options, options); - } - - if ((attr = ppdFindAttr(ppd, "cupsPJL", "Tumble")) != NULL) - { - sprintf(s, "%d", header->Tumble); - pjl_write(ppd, attr->value, s, job_id, user, title, num_options, options); - } - - if ((attr = ppdFindAttr(ppd, "cupsPJL", "MediaClass")) != NULL) - pjl_write(ppd, attr->value, header->MediaClass, job_id, user, title, - num_options, options); - - if ((attr = ppdFindAttr(ppd, "cupsPJL", "MediaColor")) != NULL) - pjl_write(ppd, attr->value, header->MediaColor, job_id, user, title, - num_options, options); - - if ((attr = ppdFindAttr(ppd, "cupsPJL", "MediaType")) != NULL) - pjl_write(ppd, attr->value, header->MediaType, job_id, user, title, - num_options, options); - - if ((attr = ppdFindAttr(ppd, "cupsPJL", "OutputType")) != NULL) - pjl_write(ppd, attr->value, header->OutputType, job_id, user, title, - num_options, options); - - if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsBooklet")) != NULL && - (choice = ppdFindMarkedChoice(ppd, "cupsBooklet")) != NULL) - pjl_write(ppd, attr->value, choice->choice, job_id, user, title, - num_options, options); - - if ((attr = ppdFindAttr(ppd, "cupsPJL", "Jog")) != NULL) - { - sprintf(s, "%d", header->Jog); - pjl_write(ppd, attr->value, s, job_id, user, title, num_options, options); - } - - if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsPunch")) != NULL && - (choice = ppdFindMarkedChoice(ppd, "cupsPunch")) != NULL) - pjl_write(ppd, attr->value, choice->choice, job_id, user, title, - num_options, options); - - if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsStaple")) != NULL && - (choice = ppdFindMarkedChoice(ppd, "cupsStaple")) != NULL) - pjl_write(ppd, attr->value, choice->choice, job_id, user, title, - num_options, options); - - if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsRET")) != NULL && - (choice = ppdFindMarkedChoice(ppd, "cupsRET")) != NULL) - pjl_write(ppd, attr->value, choice->choice, job_id, user, title, - num_options, options); - - if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsTonerSave")) != NULL && - (choice = ppdFindMarkedChoice(ppd, "cupsTonerSave")) != NULL) - pjl_write(ppd, attr->value, choice->choice, job_id, user, title, - num_options, options); - - if (ppd->model_number & PCL_PJL_PAPERWIDTH) - { - printf("@PJL SET PAPERLENGTH=%d\r\n", header->PageSize[1] * 10); - printf("@PJL SET PAPERWIDTH=%d\r\n", header->PageSize[0] * 10); - } - - if (ppd->model_number & PCL_PJL_RESOLUTION) - printf("@PJL SET RESOLUTION=%d\r\n", header->HWResolution[0]); - - if (ppd->model_number & PCL_PJL_HPGL2) - pjl_enter_language("HPGL2"); - else if (ppd->model_number & PCL_PJL_PCL3GUI) - pjl_enter_language("PCL3GUI"); - else - pjl_enter_language("PCL"); - } - - if (Page == 1) - { - pcl_reset(); - } - - if (ppd->model_number & PCL_PJL_HPGL2) - { - if (Page == 1) - { - /* - * HP-GL/2 initialization... - */ - - printf("IN;"); - printf("MG\"%d %s %s\";", job_id, user, title); - } - - /* - * Set media size, position, type, etc... - */ - - printf("BP5,0;"); - printf("PS%.0f,%.0f;", - header->cupsHeight * 1016.0 / header->HWResolution[1], - header->cupsWidth * 1016.0 / header->HWResolution[0]); - printf("PU;"); - printf("PA0,0"); - - printf("MT%d;", header->cupsMediaType); - - if (header->CutMedia == CUPS_CUT_PAGE) - printf("EC;"); - else - printf("EC0;"); - - /* - * Set graphics mode... - */ - - pcl_set_pcl_mode(0); - pcl_set_negative_motion(); - } - else - { - /* - * Set media size, position, type, etc... - */ - - if (!header->Duplex || (Page & 1)) - { - pcl_set_media_size(ppd, header->PageSize[0], header->PageSize[1]); - - if (header->MediaPosition) - pcl_set_media_source(header->MediaPosition); - - pcl_set_media_type(header->cupsMediaType); - - if (ppdFindAttr(ppd, "cupsPJL", "Duplex") == NULL) - pcl_set_duplex(header->Duplex, header->Tumble); - - /* - * Set the number of copies... - */ - - if (!ppd->manual_copies) - pcl_set_copies(header->NumCopies); - - /* - * Set the output order/bin... - */ - - if (ppdFindAttr(ppd, "cupsPJL", "Jog") == NULL && header->Jog) - printf("\033&l%dG", header->Jog); - } - else - { - /* - * Print on the back side... - */ - - printf("\033&a2G"); - } - - if (header->Duplex && (ppd->model_number & PCL_RASTER_CRD)) - { - /* - * Reload the media... - */ - - pcl_set_media_source(-2); - } - - /* - * Set the units for cursor positioning and go to the top of the form. - */ - - printf("\033&u%dD", header->HWResolution[0]); - printf("\033*p0Y\033*p0X"); - } - - if ((attr = cupsFindAttr(ppd, "cupsPCLQuality", colormodel, - header->MediaType, resolution, spec, - sizeof(spec))) != NULL) - { - /* - * Set the print quality... - */ - - if (ppd->model_number & PCL_PJL_HPGL2) - printf("QM%d", atoi(attr->value)); - else - printf("\033*o%dM", atoi(attr->value)); - } - - /* - * Enter graphics mode... - */ - - if (ppd->model_number & PCL_RASTER_CRD) - { - /* - * Use configure raster data command... - */ - - if (OutputMode == OUTPUT_RGB) - { - /* - * Send 12-byte configure raster data command with horizontal and - * vertical resolutions as well as a color count... - */ - - if ((attr = cupsFindAttr(ppd, "cupsPCLCRDMode", colormodel, - header->MediaType, resolution, spec, - sizeof(spec))) != NULL) - i = atoi(attr->value); - else - i = 31; - - printf("\033*g12W"); - putchar(6); /* Format 6 */ - putchar(i); /* Set pen mode */ - putchar(0x00); /* Number components */ - putchar(0x01); /* (1 for RGB) */ - - putchar(header->HWResolution[0] >> 8); - putchar(header->HWResolution[0]); - putchar(header->HWResolution[1] >> 8); - putchar(header->HWResolution[1]); - - putchar(header->cupsCompression); /* Compression mode 3 or 10 */ - putchar(0x01); /* Portrait orientation */ - putchar(0x20); /* Bits per pixel (32 = RGB) */ - putchar(0x01); /* Planes per pixel (1 = chunky RGB) */ - } - else - { - /* - * Send the configure raster data command with horizontal and - * vertical resolutions as well as a color count... - */ - - printf("\033*g%dW", PrinterPlanes * 6 + 2); - putchar(2); /* Format 2 */ - putchar(PrinterPlanes); /* Output planes */ - - order = ColorOrders[PrinterPlanes - 1]; - - for (i = 0; i < PrinterPlanes; i ++) - { - plane = order[i]; - - putchar(header->HWResolution[0] >> 8); - putchar(header->HWResolution[0]); - putchar(header->HWResolution[1] >> 8); - putchar(header->HWResolution[1]); - putchar(0); - putchar(1 << DotBits[plane]); - } - } - } - else if ((ppd->model_number & PCL_RASTER_CID) && OutputMode == OUTPUT_RGB) - { - /* - * Use configure image data command... - */ - - pcl_set_simple_resolution(header->HWResolution[0]); - /* Set output resolution */ - - cupsWritePrintData("\033*v6W\0\3\0\10\10\10", 11); - /* 24-bit RGB */ - } - else - { - /* - * Use simple raster commands... - */ - - pcl_set_simple_resolution(header->HWResolution[0]); - /* Set output resolution */ - - if (PrinterPlanes == 3) - pcl_set_simple_cmy(); - else if (PrinterPlanes == 4) - pcl_set_simple_kcmy(); - } - - if ((attr = ppdFindAttr(ppd, "cupsPCLOrigin", "X")) != NULL) - xorigin = atoi(attr->value); - else - xorigin = 0; - - if ((attr = ppdFindAttr(ppd, "cupsPCLOrigin", "Y")) != NULL) - yorigin = atoi(attr->value); - else - yorigin = 120; - - printf("\033&a%dH\033&a%dV", xorigin, yorigin); - printf("\033*r%dS", header->cupsWidth); - printf("\033*r%dT", header->cupsHeight); - printf("\033*r1A"); - - if (header->cupsCompression && header->cupsCompression != 10) - printf("\033*b%dM", header->cupsCompression); - - OutputFeed = 0; - - /* - * Allocate memory for the page... - */ - - PixelBuffer = malloc(header->cupsBytesPerLine); - - if (OutputMode == OUTPUT_DITHERED) - { - InputBuffer = malloc(header->cupsWidth * PrinterPlanes * 2); - OutputBuffers[0] = malloc(PrinterPlanes * header->cupsWidth); - - for (i = 1; i < PrinterPlanes; i ++) - OutputBuffers[i] = OutputBuffers[0] + i * header->cupsWidth; - - if (RGB) - CMYKBuffer = malloc(header->cupsWidth * PrinterPlanes); - - for (plane = 0, DotBufferSize = 0; plane < PrinterPlanes; plane ++) - { - DotBufferSizes[plane] = (header->cupsWidth + 7) / 8 * DotBits[plane]; - DotBufferSize += DotBufferSizes[plane]; - } - - DotBuffers[0] = malloc(DotBufferSize); - for (plane = 1; plane < PrinterPlanes; plane ++) - DotBuffers[plane] = DotBuffers[plane - 1] + DotBufferSizes[plane - 1]; - } - - if (header->cupsCompression) - CompBuffer = malloc(DotBufferSize * 4); - - if (header->cupsCompression >= 3) - SeedBuffer = malloc(DotBufferSize); - - SeedInvalid = 1; - - fprintf(stderr, "BlankValue=%d\n", BlankValue); -} - - -/* - * 'EndPage()' - Finish a page of graphics. - */ - -void -EndPage(ppd_file_t *ppd, /* I - PPD file */ - cups_page_header2_t *header) /* I - Page header */ -{ - int plane; /* Current plane */ - - - /* - * End graphics mode... - */ - - if (ppd->model_number & PCL_RASTER_END_COLOR) - printf("\033*rC"); /* End color GFX */ - else - printf("\033*r0B"); /* End B&W GFX */ - - /* - * Output a page eject sequence... - */ - - if (ppd->model_number & PCL_PJL_HPGL2) - { - pcl_set_hpgl_mode(0); /* Back to HP-GL/2 mode */ - printf("PG;"); /* Eject the current page */ - } - else if (!(header->Duplex && (Page & 1))) - printf("\014"); /* Eject current page */ - - /* - * Free memory for the page... - */ - - free(PixelBuffer); - - if (OutputMode == OUTPUT_DITHERED) - { - for (plane = 0; plane < PrinterPlanes; plane ++) - { - cupsDitherDelete(DitherStates[plane]); - cupsLutDelete(DitherLuts[plane]); - } - - free(DotBuffers[0]); - free(InputBuffer); - free(OutputBuffers[0]); - - cupsCMYKDelete(CMYK); - - if (RGB) - { - cupsRGBDelete(RGB); - free(CMYKBuffer); - } - } - - if (header->cupsCompression) - free(CompBuffer); - - if (header->cupsCompression >= 3) - free(SeedBuffer); -} - - -/* - * 'Shutdown()' - Shutdown a printer. - */ - -void -Shutdown(ppd_file_t *ppd, /* I - PPD file */ - int job_id, /* I - Job ID */ - const char *user, /* I - User printing job */ - const char *title, /* I - Title of job */ - int num_options,/* I - Number of command-line options */ - cups_option_t *options) /* I - Command-line options */ -{ - ppd_attr_t *attr; /* Attribute from PPD file */ - - - if ((attr = ppdFindAttr(ppd, "cupsPCL", "EndJob")) != NULL) - { - /* - * Tell the printer how many pages were in the job... - */ - - putchar(0x1b); - printf(attr->value, Page); - } - else - { - /* - * Return the printer to the default state... - */ - - pcl_reset(); - } - - if (ppd->model_number & PCL_PJL) - { - pjl_escape(); - - if ((attr = ppdFindAttr(ppd, "cupsPJL", "EndJob")) != NULL) - pjl_write(ppd, attr->value, NULL, job_id, user, title, num_options, - options); - else - printf("@PJL EOJ\r\n"); - - pjl_escape(); - } -} - - -/* - * 'CancelJob()' - Cancel the current job... - */ - -void -CancelJob(int sig) /* I - Signal */ -{ - (void)sig; - - Canceled = 1; -} - - -/* - * 'CompressData()' - Compress a line of graphics. - */ - -void -CompressData(unsigned char *line, /* I - Data to compress */ - int length, /* I - Number of bytes */ - int plane, /* I - Color plane */ - int pend, /* I - End character for data */ - int type) /* I - Type of compression */ -{ - unsigned char *line_ptr, /* Current byte pointer */ - *line_end, /* End-of-line byte pointer */ - *comp_ptr, /* Pointer into compression buffer */ - *start, /* Start of compression sequence */ - *seed; /* Seed buffer pointer */ - int count, /* Count of bytes for output */ - offset, /* Offset of bytes for output */ - temp; /* Temporary count */ - int r, g, b; /* RGB deltas for mode 10 compression */ - - - switch (type) - { - default : - /* - * Do no compression; with a mode-0 only printer, we can compress blank - * lines... - */ - - line_ptr = line; - - if (cupsCheckBytes(line, length)) - line_end = line; /* Blank line */ - else - line_end = line + length; /* Non-blank line */ - break; - - case 1 : - /* - * Do run-length encoding... - */ - - line_end = line + length; - for (line_ptr = line, comp_ptr = CompBuffer; - line_ptr < line_end; - comp_ptr += 2, line_ptr += count) - { - for (count = 1; - (line_ptr + count) < line_end && - line_ptr[0] == line_ptr[count] && - count < 256; - count ++); - - comp_ptr[0] = count - 1; - comp_ptr[1] = line_ptr[0]; - } - - line_ptr = CompBuffer; - line_end = comp_ptr; - break; - - case 2 : - /* - * Do TIFF pack-bits encoding... - */ - - line_ptr = line; - line_end = line + length; - comp_ptr = CompBuffer; - - while (line_ptr < line_end) - { - if ((line_ptr + 1) >= line_end) - { - /* - * Single byte on the end... - */ - - *comp_ptr++ = 0x00; - *comp_ptr++ = *line_ptr++; - } - else if (line_ptr[0] == line_ptr[1]) - { - /* - * Repeated sequence... - */ - - line_ptr ++; - count = 2; - - while (line_ptr < (line_end - 1) && - line_ptr[0] == line_ptr[1] && - count < 127) - { - line_ptr ++; - count ++; - } - - *comp_ptr++ = 257 - count; - *comp_ptr++ = *line_ptr++; - } - else - { - /* - * Non-repeated sequence... - */ - - start = line_ptr; - line_ptr ++; - count = 1; - - while (line_ptr < (line_end - 1) && - line_ptr[0] != line_ptr[1] && - count < 127) - { - line_ptr ++; - count ++; - } - - *comp_ptr++ = count - 1; - - memcpy(comp_ptr, start, count); - comp_ptr += count; - } - } - - line_ptr = CompBuffer; - line_end = comp_ptr; - break; - - case 3 : - /* - * Do delta-row compression... - */ - - line_ptr = line; - line_end = line + length; - - comp_ptr = CompBuffer; - seed = SeedBuffer + plane * length; - - while (line_ptr < line_end) - { - /* - * Find the next non-matching sequence... - */ - - start = line_ptr; - - if (SeedInvalid) - { - /* - * The seed buffer is invalid, so do the next 8 bytes, max... - */ - - offset = 0; - - if ((count = line_end - line_ptr) > 8) - count = 8; - - line_ptr += count; - } - else - { - /* - * The seed buffer is valid, so compare against it... - */ - - while (*line_ptr == *seed && - line_ptr < line_end) - { - line_ptr ++; - seed ++; - } - - if (line_ptr == line_end) - break; - - offset = line_ptr - start; - - /* - * Find up to 8 non-matching bytes... - */ - - start = line_ptr; - count = 0; - while (*line_ptr != *seed && - line_ptr < line_end && - count < 8) - { - line_ptr ++; - seed ++; - count ++; - } - } - - /* - * Place mode 3 compression data in the buffer; see HP manuals - * for details... - */ - - if (offset >= 31) - { - /* - * Output multi-byte offset... - */ - - *comp_ptr++ = ((count - 1) << 5) | 31; - - offset -= 31; - while (offset >= 255) - { - *comp_ptr++ = 255; - offset -= 255; - } - - *comp_ptr++ = offset; - } - else - { - /* - * Output single-byte offset... - */ - - *comp_ptr++ = ((count - 1) << 5) | offset; - } - - memcpy(comp_ptr, start, count); - comp_ptr += count; - } - - line_ptr = CompBuffer; - line_end = comp_ptr; - - memcpy(SeedBuffer + plane * length, line, length); - break; - - case 10 : - /* - * Mode 10 "near lossless" RGB compression... - */ - - line_ptr = line; - line_end = line + length; - - comp_ptr = CompBuffer; - seed = SeedBuffer; - - if (PrinterPlanes == 1) - { - /* - * Do grayscale compression to RGB... - */ - - while (line_ptr < line_end) - { - /* - * Find the next non-matching sequence... - */ - - start = line_ptr; - while (line_ptr < line_end && - *line_ptr == *seed) - { - line_ptr ++; - seed ++; - } - - if (line_ptr == line_end) - break; - - offset = line_ptr - start; - - /* - * Find non-matching grayscale pixels... - */ - - start = line_ptr; - while (line_ptr < line_end && - *line_ptr != *seed) - { - line_ptr ++; - seed ++; - } - - count = line_ptr - start; - -#if 0 - fprintf(stderr, "DEBUG: offset=%d, count=%d, comp_ptr=%p(%d of %d)...\n", - offset, count, comp_ptr, comp_ptr - CompBuffer, - BytesPerLine * 5); -#endif /* 0 */ - - /* - * Place mode 10 compression data in the buffer; each sequence - * starts with a command byte that looks like: - * - * CMD SRC SRC OFF OFF CNT CNT CNT - * - * For the purpose of this driver, CMD and SRC are always 0. - * - * If the offset >= 3 then additional offset bytes follow the - * first command byte, each byte == 255 until the last one. - * - * If the count >= 7, then additional count bytes follow each - * group of pixels, each byte == 255 until the last one. - * - * The offset and count are in RGB tuples (not bytes, as for - * Mode 3 and 9)... - */ - - if (offset >= 3) - { - /* - * Output multi-byte offset... - */ - - if (count > 7) - *comp_ptr++ = 0x1f; - else - *comp_ptr++ = 0x18 | (count - 1); - - offset -= 3; - while (offset >= 255) - { - *comp_ptr++ = 255; - offset -= 255; - } - - *comp_ptr++ = offset; - } - else - { - /* - * Output single-byte offset... - */ - - if (count > 7) - *comp_ptr++ = (offset << 3) | 0x07; - else - *comp_ptr++ = (offset << 3) | (count - 1); - } - - temp = count - 8; - seed -= count; - - while (count > 0) - { - if (count <= temp) - { - /* - * This is exceedingly lame... The replacement counts - * are intermingled with the data... - */ - - if (temp >= 255) - *comp_ptr++ = 255; - else - *comp_ptr++ = temp; - - temp -= 255; - } - - /* - * Get difference between current and see pixels... - */ - - r = *start - *seed; - g = r; - b = ((*start & 0xfe) - (*seed & 0xfe)) / 2; - - if (r < -16 || r > 15 || g < -16 || g > 15 || b < -16 || b > 15) - { - /* - * Pack 24-bit RGB into 23 bits... Lame... - */ - - g = *start; - - *comp_ptr++ = g >> 1; - - if (g & 1) - *comp_ptr++ = 0x80 | (g >> 1); - else - *comp_ptr++ = g >> 1; - - if (g & 1) - *comp_ptr++ = 0x80 | (g >> 1); - else - *comp_ptr++ = g >> 1; - } - else - { - /* - * Pack 15-bit RGB difference... - */ - - *comp_ptr++ = 0x80 | ((r << 2) & 0x7c) | ((g >> 3) & 0x03); - *comp_ptr++ = ((g << 5) & 0xe0) | (b & 0x1f); - } - - count --; - start ++; - seed ++; - } - - /* - * Make sure we have the ending count if the replacement count - * was exactly 8 + 255n... - */ - - if (temp == 0) - *comp_ptr++ = 0; - } - } - else - { - /* - * Do RGB compression... - */ - - while (line_ptr < line_end) - { - /* - * Find the next non-matching sequence... - */ - - start = line_ptr; - while (line_ptr[0] == seed[0] && - line_ptr[1] == seed[1] && - line_ptr[2] == seed[2] && - (line_ptr + 2) < line_end) - { - line_ptr += 3; - seed += 3; - } - - if (line_ptr == line_end) - break; - - offset = (line_ptr - start) / 3; - - /* - * Find non-matching RGB tuples... - */ - - start = line_ptr; - while ((line_ptr[0] != seed[0] || - line_ptr[1] != seed[1] || - line_ptr[2] != seed[2]) && - (line_ptr + 2) < line_end) - { - line_ptr += 3; - seed += 3; - } - - count = (line_ptr - start) / 3; - - /* - * Place mode 10 compression data in the buffer; each sequence - * starts with a command byte that looks like: - * - * CMD SRC SRC OFF OFF CNT CNT CNT - * - * For the purpose of this driver, CMD and SRC are always 0. - * - * If the offset >= 3 then additional offset bytes follow the - * first command byte, each byte == 255 until the last one. - * - * If the count >= 7, then additional count bytes follow each - * group of pixels, each byte == 255 until the last one. - * - * The offset and count are in RGB tuples (not bytes, as for - * Mode 3 and 9)... - */ - - if (offset >= 3) - { - /* - * Output multi-byte offset... - */ - - if (count > 7) - *comp_ptr++ = 0x1f; - else - *comp_ptr++ = 0x18 | (count - 1); - - offset -= 3; - while (offset >= 255) - { - *comp_ptr++ = 255; - offset -= 255; - } - - *comp_ptr++ = offset; - } - else - { - /* - * Output single-byte offset... - */ - - if (count > 7) - *comp_ptr++ = (offset << 3) | 0x07; - else - *comp_ptr++ = (offset << 3) | (count - 1); - } - - temp = count - 8; - seed -= count * 3; - - while (count > 0) - { - if (count <= temp) - { - /* - * This is exceedingly lame... The replacement counts - * are intermingled with the data... - */ - - if (temp >= 255) - *comp_ptr++ = 255; - else - *comp_ptr++ = temp; - - temp -= 255; - } - - /* - * Get difference between current and see pixels... - */ - - r = start[0] - seed[0]; - g = start[1] - seed[1]; - b = ((start[2] & 0xfe) - (seed[2] & 0xfe)) / 2; - - if (r < -16 || r > 15 || g < -16 || g > 15 || b < -16 || b > 15) - { - /* - * Pack 24-bit RGB into 23 bits... Lame... - */ - - *comp_ptr++ = start[0] >> 1; - - if (start[0] & 1) - *comp_ptr++ = 0x80 | (start[1] >> 1); - else - *comp_ptr++ = start[1] >> 1; - - if (start[1] & 1) - *comp_ptr++ = 0x80 | (start[2] >> 1); - else - *comp_ptr++ = start[2] >> 1; - } - else - { - /* - * Pack 15-bit RGB difference... - */ - - *comp_ptr++ = 0x80 | ((r << 2) & 0x7c) | ((g >> 3) & 0x03); - *comp_ptr++ = ((g << 5) & 0xe0) | (b & 0x1f); - } - - count --; - start += 3; - seed += 3; - } - - /* - * Make sure we have the ending count if the replacement count - * was exactly 8 + 255n... - */ - - if (temp == 0) - *comp_ptr++ = 0; - } - } - - line_ptr = CompBuffer; - line_end = comp_ptr; - - memcpy(SeedBuffer, line, length); - break; - } - - /* - * Set the length of the data and write a raster plane... - */ - - printf("\033*b%d%c", (int)(line_end - line_ptr), pend); - cupsWritePrintData(line_ptr, line_end - line_ptr); -} - - -/* - * 'OutputLine()' - Output the specified number of lines of graphics. - */ - -void -OutputLine(ppd_file_t *ppd, /* I - PPD file */ - cups_page_header2_t *header) /* I - Page header */ -{ - int i, j; /* Looping vars */ - int plane; /* Current plane */ - unsigned char bit; /* Current bit */ - int bytes; /* Number of bytes/plane */ - int width; /* Width of line in pixels */ - const int *order; /* Order to use */ - unsigned char *ptr; /* Pointer into buffer */ - - - /* - * Output whitespace as needed... - */ - - if (OutputFeed > 0) - { - if (header->cupsCompression < 3) - { - /* - * Send blank raster lines... - */ - - while (OutputFeed > 0) - { - printf("\033*b0W"); - OutputFeed --; - } - } - else - { - /* - * Send Y offset command and invalidate the seed buffer... - */ - - printf("\033*b%dY", OutputFeed); - OutputFeed = 0; - SeedInvalid = 1; - } - } - - /* - * Write bitmap data as needed... - */ - - switch (OutputMode) - { - case OUTPUT_BITMAP : /* Send 1-bit bitmap data... */ - order = ColorOrders[PrinterPlanes - 1]; - bytes = header->cupsBytesPerLine / PrinterPlanes; - - for (i = 0; i < PrinterPlanes; i ++) - { - plane = order[i]; - - CompressData(PixelBuffer + i * bytes, bytes, plane, - (i < (PrinterPlanes - 1)) ? 'V' : 'W', - header->cupsCompression); - } - break; - - case OUTPUT_INVERBIT : /* Send inverted 1-bit bitmap data... */ - order = ColorOrders[PrinterPlanes - 1]; - bytes = header->cupsBytesPerLine / PrinterPlanes; - - for (i = header->cupsBytesPerLine, ptr = PixelBuffer; - i > 0; - i --, ptr ++) - *ptr = ~*ptr; - - for (i = 0; i < PrinterPlanes; i ++) - { - plane = order[i]; - - CompressData(PixelBuffer + i * bytes, bytes, plane, - (i < (PrinterPlanes - 1)) ? 'V' : 'W', - header->cupsCompression); - } - break; - - case OUTPUT_RGB : /* Send 24-bit RGB data... */ - if (PrinterPlanes == 1 && !BlankValue) - { - /* - * Invert black to grayscale... - */ - - for (i = header->cupsBytesPerLine, ptr = PixelBuffer; - i > 0; - i --, ptr ++) - *ptr = ~*ptr; - } - - /* - * Compress the output... - */ - - CompressData(PixelBuffer, header->cupsBytesPerLine, 0, 'W', - header->cupsCompression); - break; - - default : - order = ColorOrders[PrinterPlanes - 1]; - width = header->cupsWidth; - - for (i = 0, j = 0; i < PrinterPlanes; i ++) - { - plane = order[i]; - bytes = DotBufferSizes[plane] / DotBits[plane]; - - for (bit = 1, ptr = DotBuffers[plane]; - bit <= DotBits[plane]; - bit <<= 1, ptr += bytes, j ++) - { - cupsPackHorizontalBit(OutputBuffers[plane], DotBuffers[plane], - width, 0, bit); - CompressData(ptr, bytes, j, - i == (PrinterPlanes - 1) && - bit == DotBits[plane] ? 'W' : 'V', - header->cupsCompression); - } - } - break; - } - - /* - * The seed buffer, if any, now should contain valid data... - */ - - SeedInvalid = 0; -} - - -/* - * 'ReadLine()' - Read graphics from the page stream. - */ - -int /* O - Number of lines (0 if blank) */ -ReadLine(cups_raster_t *ras, /* I - Raster stream */ - cups_page_header2_t *header) /* I - Page header */ -{ - int plane, /* Current color plane */ - width; /* Width of line */ - - - /* - * Read raster data... - */ - - cupsRasterReadPixels(ras, PixelBuffer, header->cupsBytesPerLine); - - /* - * See if it is blank; if so, return right away... - */ - - if (cupsCheckValue(PixelBuffer, header->cupsBytesPerLine, BlankValue)) - return (0); - - /* - * If we aren't dithering, return immediately... - */ - - if (OutputMode != OUTPUT_DITHERED) - return (1); - - /* - * Perform the color separation... - */ - - width = header->cupsWidth; - - switch (header->cupsColorSpace) - { - case CUPS_CSPACE_W : - if (RGB) - { - cupsRGBDoGray(RGB, PixelBuffer, CMYKBuffer, width); - - if (RGB->num_channels == 1) - cupsCMYKDoBlack(CMYK, CMYKBuffer, InputBuffer, width); - else - cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width); - } - else - cupsCMYKDoGray(CMYK, PixelBuffer, InputBuffer, width); - break; - - case CUPS_CSPACE_K : - cupsCMYKDoBlack(CMYK, PixelBuffer, InputBuffer, width); - break; - - default : - case CUPS_CSPACE_RGB : - if (RGB) - { - cupsRGBDoRGB(RGB, PixelBuffer, CMYKBuffer, width); - - if (RGB->num_channels == 1) - cupsCMYKDoBlack(CMYK, CMYKBuffer, InputBuffer, width); - else - cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width); - } - else - cupsCMYKDoRGB(CMYK, PixelBuffer, InputBuffer, width); - break; - - case CUPS_CSPACE_CMYK : - cupsCMYKDoCMYK(CMYK, PixelBuffer, InputBuffer, width); - break; - } - - /* - * Dither the pixels... - */ - - for (plane = 0; plane < PrinterPlanes; plane ++) - cupsDitherLine(DitherStates[plane], DitherLuts[plane], InputBuffer + plane, - PrinterPlanes, OutputBuffers[plane]); - - /* - * Return 1 to indicate that we have non-blank output... - */ - - return (1); -} - - -/* - * 'main()' - Main entry and processing of driver. - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments */ - char *argv[]) /* I - Command-line arguments */ -{ - int fd; /* File descriptor */ - cups_raster_t *ras; /* Raster stream for printing */ - cups_page_header2_t header; /* Page header from file */ - int y; /* Current line */ - ppd_file_t *ppd; /* PPD file */ - int job_id; /* Job ID */ - int num_options; /* Number of options */ - cups_option_t *options; /* Options */ -#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) - struct sigaction action; /* Actions for POSIX signals */ -#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ - - - /* - * Make sure status messages are not buffered... - */ - - setbuf(stderr, NULL); - - /* - * Check command-line... - */ - - if (argc < 6 || argc > 7) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("%s job-id user title copies options [file]"), - "rastertopclx"); - return (1); - } - - num_options = cupsParseOptions(argv[5], 0, &options); - - /* - * Open the PPD file... - */ - - ppd = ppdOpenFile(getenv("PPD")); - - if (!ppd) - { - ppd_status_t status; /* PPD error */ - int linenum; /* Line number */ - - _cupsLangPrintFilter(stderr, "ERROR", - _("The PPD file could not be opened.")); - - status = ppdLastError(&linenum); - - fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum); - - return (1); - } - - ppdMarkDefaults(ppd); - cupsMarkOptions(ppd, num_options, options); - - /* - * Open the page stream... - */ - - if (argc == 7) - { - if ((fd = open(argv[6], O_RDONLY)) == -1) - { - _cupsLangPrintError("ERROR", _("Unable to open raster file")); - return (1); - } - } - else - fd = 0; - - ras = cupsRasterOpen(fd, CUPS_RASTER_READ); - - /* - * Register a signal handler to eject the current page if the - * job is cancelled. - */ - - Canceled = 0; - -#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ - sigset(SIGTERM, CancelJob); -#elif defined(HAVE_SIGACTION) - memset(&action, 0, sizeof(action)); - - sigemptyset(&action.sa_mask); - action.sa_handler = CancelJob; - sigaction(SIGTERM, &action, NULL); -#else - signal(SIGTERM, CancelJob); -#endif /* HAVE_SIGSET */ - - /* - * Process pages as needed... - */ - - job_id = atoi(argv[1]); - - Page = 0; - - while (cupsRasterReadHeader2(ras, &header)) - { - /* - * Write a status message with the page number and number of copies. - */ - - if (Canceled) - break; - - Page ++; - - fprintf(stderr, "PAGE: %d %d\n", Page, header.NumCopies); - _cupsLangPrintFilter(stderr, "INFO", _("Starting page %d."), Page); - - StartPage(ppd, &header, atoi(argv[1]), argv[2], argv[3], - num_options, options); - - for (y = 0; y < (int)header.cupsHeight; y ++) - { - /* - * Let the user know how far we have progressed... - */ - - if (Canceled) - break; - - if ((y & 127) == 0) - { - _cupsLangPrintFilter(stderr, "INFO", - _("Printing page %d, %d%% complete."), - Page, 100 * y / header.cupsHeight); - fprintf(stderr, "ATTR: job-media-progress=%d\n", - 100 * y / header.cupsHeight); - } - - /* - * Read and write a line of graphics or whitespace... - */ - - if (ReadLine(ras, &header)) - OutputLine(ppd, &header); - else - OutputFeed ++; - } - - /* - * Eject the page... - */ - - _cupsLangPrintFilter(stderr, "INFO", _("Finished page %d."), Page); - - EndPage(ppd, &header); - - if (Canceled) - break; - } - - Shutdown(ppd, job_id, argv[2], argv[3], num_options, options); - - cupsFreeOptions(num_options, options); - - cupsRasterClose(ras); - - if (fd != 0) - close(fd); - - if (Page == 0) - { - _cupsLangPrintFilter(stderr, "ERROR", _("No pages were found.")); - return (1); - } - else - { - _cupsLangPrintFilter(stderr, "INFO", _("Ready to print.")); - return (0); - } -} - - -/* - * End of "$Id$". - */ diff --git a/driver/rgb.c b/driver/rgb.c deleted file mode 100644 index fd0b117a5..000000000 --- a/driver/rgb.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - * "$Id$" - * - * RGB color separation code for CUPS. - * - * Copyright 2007 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * cupsRGBDelete() - Delete a color separation. - * cupsRGBDoGray() - Do a grayscale separation... - * cupsRGBDoRGB() - Do a RGB separation... - * cupsRGBLoad() - Load a RGB color profile from a PPD file. - * cupsRGBNew() - Create a new RGB color separation. - */ - -/* - * Include necessary headers. - */ - -#include "driver.h" - - -/* - * 'cupsRGBDelete()' - Delete a color separation. - */ - -void -cupsRGBDelete(cups_rgb_t *rgbptr) /* I - Color separation */ -{ - if (rgbptr == NULL) - return; - - free(rgbptr->colors[0][0][0]); - free(rgbptr->colors[0][0]); - free(rgbptr->colors[0]); - free(rgbptr->colors); - free(rgbptr); -} - - -/* - * 'cupsRGBDoGray()' - Do a grayscale separation... - */ - -void -cupsRGBDoGray(cups_rgb_t *rgbptr, - /* I - Color separation */ - const unsigned char *input, - /* I - Input grayscale pixels */ - unsigned char *output, - /* O - Output Device-N pixels */ - int num_pixels) - /* I - Number of pixels */ -{ - int i; /* Looping var */ - int lastgray; /* Previous grayscale */ - int xs, ys, zs, /* Current RGB row offsets */ - g, gi, gm0, gm1;/* Current gray index and multipliers ... */ - const unsigned char *color; /* Current color data */ - int tempg; /* Current separation color */ - int rgbsize; /* Separation data size */ - - - /* - * Range check input... - */ - - if (!rgbptr || !input || !output || num_pixels <= 0) - return; - - /* - * Initialize variables used for the duration of the separation... - */ - - lastgray = -1; - rgbsize = rgbptr->num_channels; - xs = rgbptr->cube_size * rgbptr->cube_size * rgbptr->num_channels; - ys = rgbptr->cube_size * rgbptr->num_channels; - zs = rgbptr->num_channels; - - /* - * Loop through it all... - */ - - while (num_pixels > 0) - { - /* - * See if the next pixel is a cached value... - */ - - num_pixels --; - - g = cups_srgb_lut[*input++]; - - if (g == lastgray) - { - /* - * Copy previous color and continue... - */ - - memcpy(output, output - rgbptr->num_channels, rgbsize); - - output += rgbptr->num_channels; - continue; - } - else if (g == 0x00 && rgbptr->cache_init) - { - /* - * Copy black color and continue... - */ - - memcpy(output, rgbptr->black, rgbsize); - - output += rgbptr->num_channels; - continue; - } - else if (g == 0xff && rgbptr->cache_init) - { - /* - * Copy white color and continue... - */ - - memcpy(output, rgbptr->white, rgbsize); - - output += rgbptr->num_channels; - continue; - } - - /* - * Nope, figure this one out on our own... - */ - - gi = rgbptr->cube_index[g]; - gm0 = rgbptr->cube_mult[g]; - gm1 = 256 - gm0; - - color = rgbptr->colors[gi][gi][gi]; - - for (i = 0; i < rgbptr->num_channels; i ++, color ++) - { - tempg = (color[0] * gm0 + color[xs + ys + zs] * gm1) / 256; - - if (tempg > 255) - *output++ = 255; - else if (tempg < 0) - *output++ = 0; - else - *output++ = tempg; - } - } -} - - -/* - * 'cupsRGBDoRGB()' - Do a RGB separation... - */ - -void -cupsRGBDoRGB(cups_rgb_t *rgbptr, - /* I - Color separation */ - const unsigned char *input, - /* I - Input RGB pixels */ - unsigned char *output, - /* O - Output Device-N pixels */ - int num_pixels) - /* I - Number of pixels */ -{ - int i; /* Looping var */ - int rgb, /* Current RGB color */ - lastrgb; /* Previous RGB color */ - int r, ri, rm0, rm1, rs, - /* Current red index, multipliexs, and row offset */ - g, gi, gm0, gm1, gs, - /* Current green ... */ - b, bi, bm0, bm1, bs; - /* Current blue ... */ - const unsigned char *color; /* Current color data */ - int tempr, /* Current separation colors */ - tempg, /* ... */ - tempb ; /* ... */ - int rgbsize; /* Separation data size */ - - - /* - * Range check input... - */ - - if (!rgbptr || !input || !output || num_pixels <= 0) - return; - - /* - * Initialize variables used for the duration of the separation... - */ - - lastrgb = -1; - rgbsize = rgbptr->num_channels; - rs = rgbptr->cube_size * rgbptr->cube_size * rgbptr->num_channels; - gs = rgbptr->cube_size * rgbptr->num_channels; - bs = rgbptr->num_channels; - - /* - * Loop through it all... - */ - - while (num_pixels > 0) - { - /* - * See if the next pixel is a cached value... - */ - - num_pixels --; - - r = cups_srgb_lut[*input++]; - g = cups_srgb_lut[*input++]; - b = cups_srgb_lut[*input++]; - rgb = (((r << 8) | g) << 8) | b; - - if (rgb == lastrgb) - { - /* - * Copy previous color and continue... - */ - - memcpy(output, output - rgbptr->num_channels, rgbsize); - - output += rgbptr->num_channels; - continue; - } - else if (rgb == 0x000000 && rgbptr->cache_init) - { - /* - * Copy black color and continue... - */ - - memcpy(output, rgbptr->black, rgbsize); - - output += rgbptr->num_channels; - continue; - } - else if (rgb == 0xffffff && rgbptr->cache_init) - { - /* - * Copy white color and continue... - */ - - memcpy(output, rgbptr->white, rgbsize); - - output += rgbptr->num_channels; - continue; - } - - /* - * Nope, figure this one out on our own... - */ - - ri = rgbptr->cube_index[r]; - rm0 = rgbptr->cube_mult[r]; - rm1 = 256 - rm0; - - gi = rgbptr->cube_index[g]; - gm0 = rgbptr->cube_mult[g]; - gm1 = 256 - gm0; - - bi = rgbptr->cube_index[b]; - bm0 = rgbptr->cube_mult[b]; - bm1 = 256 - bm0; - - color = rgbptr->colors[ri][gi][bi]; - - for (i = rgbptr->num_channels; i > 0; i --, color ++) - { - tempb = (color[0] * bm0 + color[bs] * bm1) / 256; - tempg = tempb * gm0; - tempb = (color[gs] * gm0 + color[gs + bs] * bm1) / 256; - tempg = (tempg + tempb * gm1) / 256; - - tempr = tempg * rm0; - - tempb = (color[rs] * bm0 + color[rs + bs] * bm1) / 256; - tempg = tempb * gm0; - tempb = (color[rs + gs] * bm0 + color[rs + gs + bs] * bm1) / 256; - tempg = (tempg + tempb * gm1) / 256; - - tempr = (tempr + tempg * rm1) / 256; - - if (tempr > 255) - *output++ = 255; - else if (tempr < 0) - *output++ = 0; - else - *output++ = tempr; - } - } -} - - -/* - * 'cupsRGBLoad()' - Load a RGB color profile from a PPD file. - */ - -cups_rgb_t * /* O - New color profile */ -cupsRGBLoad(ppd_file_t *ppd, /* I - PPD file */ - const char *colormodel, /* I - Color model */ - const char *media, /* I - Media type */ - const char *resolution) /* I - Resolution */ -{ - int i, /* Looping var */ - cube_size, /* Size of color lookup cube */ - num_channels, /* Number of color channels */ - num_samples; /* Number of color samples */ - cups_sample_t *samples; /* Color samples */ - float values[7]; /* Color sample values */ - char spec[PPD_MAX_NAME]; /* Profile name */ - ppd_attr_t *attr; /* Attribute from PPD file */ - cups_rgb_t *rgbptr; /* RGB color profile */ - - - /* - * Find the following attributes: - * - * cupsRGBProfile - Specifies the cube size, number of channels, and - * number of samples - * cupsRGBSample - Specifies an RGB to CMYK color sample - */ - - if ((attr = cupsFindAttr(ppd, "cupsRGBProfile", colormodel, media, - resolution, spec, sizeof(spec))) == NULL) - { - fputs("DEBUG2: No cupsRGBProfile attribute found for the current settings!\n", stderr); - return (NULL); - } - - if (!attr->value || sscanf(attr->value, "%d%d%d", &cube_size, &num_channels, - &num_samples) != 3) - { - fprintf(stderr, "ERROR: Bad cupsRGBProfile attribute \'%s\'!\n", - attr->value ? attr->value : "(null)"); - return (NULL); - } - - if (cube_size < 2 || cube_size > 16 || - num_channels < 1 || num_channels > CUPS_MAX_RGB || - num_samples != (cube_size * cube_size * cube_size)) - { - fprintf(stderr, "ERROR: Bad cupsRGBProfile attribute \'%s\'!\n", - attr->value); - return (NULL); - } - - /* - * Allocate memory for the samples and read them... - */ - - if ((samples = calloc(num_samples, sizeof(cups_sample_t))) == NULL) - { - fputs("ERROR: Unable to allocate memory for RGB profile!\n", stderr); - return (NULL); - } - - /* - * Read all of the samples... - */ - - for (i = 0; i < num_samples; i ++) - if ((attr = ppdFindNextAttr(ppd, "cupsRGBSample", spec)) == NULL) - break; - else if (!attr->value) - { - fputs("ERROR: Bad cupsRGBSample value!\n", stderr); - break; - } - else if (sscanf(attr->value, "%f%f%f%f%f%f%f", values + 0, - values + 1, values + 2, values + 3, values + 4, values + 5, - values + 6) != (3 + num_channels)) - { - fputs("ERROR: Bad cupsRGBSample value!\n", stderr); - break; - } - else - { - samples[i].rgb[0] = (int)(255.0 * values[0] + 0.5); - samples[i].rgb[1] = (int)(255.0 * values[1] + 0.5); - samples[i].rgb[2] = (int)(255.0 * values[2] + 0.5); - samples[i].colors[0] = (int)(255.0 * values[3] + 0.5); - if (num_channels > 1) - samples[i].colors[1] = (int)(255.0 * values[4] + 0.5); - if (num_channels > 2) - samples[i].colors[2] = (int)(255.0 * values[5] + 0.5); - if (num_channels > 3) - samples[i].colors[3] = (int)(255.0 * values[6] + 0.5); - } - - /* - * If everything went OK, create the color profile... - */ - - if (i == num_samples) - rgbptr = cupsRGBNew(num_samples, samples, cube_size, num_channels); - else - rgbptr = NULL; - - /* - * Free the temporary sample array and return... - */ - - free(samples); - - return (rgbptr); -} - - -/* - * 'cupsRGBNew()' - Create a new RGB color separation. - */ - -cups_rgb_t * /* O - New color separation or NULL */ -cupsRGBNew(int num_samples, /* I - Number of samples */ - cups_sample_t *samples, /* I - Samples */ - int cube_size, /* I - Size of LUT cube */ - int num_channels) /* I - Number of color components */ -{ - cups_rgb_t *rgbptr; /* New color separation */ - int i; /* Looping var */ - int r, g, b; /* Current RGB */ - int tempsize; /* Sibe of main arrays */ - unsigned char *tempc; /* Pointer for C arrays */ - unsigned char **tempb ; /* Pointer for Z arrays */ - unsigned char ***tempg; /* Pointer for Y arrays */ - unsigned char ****tempr; /* Pointer for X array */ - unsigned char rgb[3]; /* Temporary RGB value */ - - - /* - * Range-check the input... - */ - - if (!samples || num_samples != (cube_size * cube_size * cube_size) || - num_channels <= 0 || num_channels > CUPS_MAX_RGB) - return (NULL); - - /* - * Allocate memory for the separation... - */ - - if ((rgbptr = calloc(1, sizeof(cups_rgb_t))) == NULL) - return (NULL); - - /* - * Allocate memory for the samples and the LUT cube... - */ - - tempsize = cube_size * cube_size * cube_size; /* FUTURE: num_samples < cs^3 */ - - tempc = calloc(tempsize, num_channels); - tempb = calloc(tempsize, sizeof(unsigned char *)); - tempg = calloc(cube_size * cube_size, sizeof(unsigned char **)); - tempr = calloc(cube_size, sizeof(unsigned char ***)); - - if (tempc == NULL || tempb == NULL || tempg == NULL || tempr == NULL) - { - free(rgbptr); - - if (tempc) - free(tempc); - - if (tempb) - free(tempb); - - if (tempg) - free(tempg); - - if (tempr) - free(tempr); - - return (NULL); - } - - /* - * Fill in the arrays... - */ - - for (i = 0, r = 0; r < cube_size; r ++) - { - tempr[r] = tempg + r * cube_size; - - for (g = 0; g < cube_size; g ++) - { - tempr[r][g] = tempb + i; - - for (b = 0; b < cube_size; b ++, i ++) - tempr[r][g][b] = tempc + i * num_channels; - } - } - - for (i = 0; i < num_samples; i ++) - { - r = samples[i].rgb[0] * (cube_size - 1) / 255; - g = samples[i].rgb[1] * (cube_size - 1) / 255; - b = samples[i].rgb[2] * (cube_size - 1) / 255; - - memcpy(tempr[r][g][b], samples[i].colors, num_channels); - } - - rgbptr->cube_size = cube_size; - rgbptr->num_channels = num_channels; - rgbptr->colors = tempr; - - /* - * Generate the lookup tables for the cube indices and multipliers... - */ - - for (i = 0; i < 256; i ++) - { - rgbptr->cube_index[i] = i * (cube_size - 1) / 256; - - if (i == 0) - rgbptr->cube_mult[i] = 256; - else - rgbptr->cube_mult[i] = 255 - ((i * (cube_size - 1)) & 255); - } - - /* - * Generate the black and white cache values for the separation... - */ - - rgb[0] = 0; - rgb[1] = 0; - rgb[2] = 0; - - cupsRGBDoRGB(rgbptr, rgb, rgbptr->black, 1); - - rgb[0] = 255; - rgb[1] = 255; - rgb[2] = 255; - - cupsRGBDoRGB(rgbptr, rgb, rgbptr->white, 1); - - rgbptr->cache_init = 1; - - /* - * Return the separation... - */ - - return (rgbptr); -} - - -/* - * End of "$Id$". - */ diff --git a/driver/srgb.c b/driver/srgb.c deleted file mode 100644 index 0354f23e5..000000000 --- a/driver/srgb.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * "$Id$" - * - * sRGB lookup tables for CUPS. - * - * Copyright 2007 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - */ - -/* - * Include necessary headers. - */ - -#include "driver.h" - - -/* - * sRGB gamma lookup table. - */ - -const unsigned char cups_srgb_lut[256] = -{ - 0, 20, 28, 33, 38, 42, 46, 49, 52, 55, 58, 61, 63, 65, 68, - 70, 72, 74, 76, 78, 80, 81, 83, 85, 87, 88, 90, 91, 93, 94, - 96, 97, 99, 100, 102, 103, 104, 106, 107, 108, 109, 111, 112, 113, 114, - 115, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 128, 129, 130, 131, - 132, 133, 134, 135, 136, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 147, 148, 149, 150, 151, 152, 153, 153, 154, 155, 156, 157, 158, - 158, 159, 160, 161, 162, 162, 163, 164, 165, 165, 166, 167, 168, 168, 169, - 170, 171, 171, 172, 173, 174, 174, 175, 176, 176, 177, 178, 178, 179, 180, - 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 189, 189, 190, - 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 197, 198, 199, 199, - 200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 207, 208, 208, - 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 216, 216, 217, - 217, 218, 218, 219, 219, 220, 220, 221, 222, 222, 223, 223, 224, 224, 225, - 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, - 233, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239, 239, 240, - 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, 247, - 248, 248, 249, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, - 255 -}; - - -/* - * sRGB gamma lookup table (inverted output to map to CMYK...) - */ - -const unsigned char cups_scmy_lut[256] = -{ - 255, 235, 227, 222, 217, 213, 209, 206, 203, 200, 197, 194, 192, 190, 187, - 185, 183, 181, 179, 177, 175, 174, 172, 170, 168, 167, 165, 164, 162, 161, - 159, 158, 156, 155, 153, 152, 151, 149, 148, 147, 146, 144, 143, 142, 141, - 140, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 127, 126, 125, 124, - 123, 122, 121, 120, 119, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, - 109, 108, 108, 107, 106, 105, 104, 103, 102, 102, 101, 100, 99, 98, 97, - 97, 96, 95, 94, 93, 93, 92, 91, 90, 90, 89, 88, 87, 87, 86, - 85, 84, 84, 83, 82, 81, 81, 80, 79, 79, 78, 77, 77, 76, 75, - 74, 74, 73, 72, 72, 71, 70, 70, 69, 68, 68, 67, 66, 66, 65, - 65, 64, 63, 63, 62, 61, 61, 60, 59, 59, 58, 58, 57, 56, 56, - 55, 55, 54, 53, 53, 52, 52, 51, 50, 50, 49, 49, 48, 47, 47, - 46, 46, 45, 45, 44, 43, 43, 42, 42, 41, 41, 40, 39, 39, 38, - 38, 37, 37, 36, 36, 35, 35, 34, 33, 33, 32, 32, 31, 31, 30, - 30, 29, 29, 28, 28, 27, 27, 26, 26, 25, 25, 24, 24, 23, 23, - 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 15, - 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, - 7, 7, 6, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, - 0 -}; - - -/* - * End of "$Id$". - */ diff --git a/driver/testcmyk.c b/driver/testcmyk.c deleted file mode 100644 index 97bac6f47..000000000 --- a/driver/testcmyk.c +++ /dev/null @@ -1,437 +0,0 @@ -/* - * "$Id$" - * - * Test the CMYK color separation code for CUPS. - * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1993-2006 by Easy Software Products, All Rights Reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * test_gray() - Test grayscale separations... - * test_rgb() - Test color separations... - * main() - Do color separation tests. - */ - -/* - * Include necessary headers. - */ - -#include -#include "driver.h" -#include - - -void test_gray(int num_comps, const char *basename); -void test_rgb(int num_comps, const char *basename); - - -/* - * 'main()' - Do color separation tests. - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments */ - char *argv[]) /* I - Command-line arguments */ -{ - /* - * Make the test directory... - */ - - mkdir("test", 0755); - - /* - * Run tests for K, Kk, CMY, CMYK, CcMmYK, and CcMmYKk separations... - */ - - test_rgb(1, "test/K-rgb"); - test_rgb(2, "test/Kk-rgb"); - test_rgb(3, "test/CMY-rgb"); - test_rgb(4, "test/CMYK-rgb"); - test_rgb(6, "test/CcMmYK-rgb"); - test_rgb(7, "test/CcMmYKk-rgb"); - - test_gray(1, "test/K-gray"); - test_gray(2, "test/Kk-gray"); - test_gray(3, "test/CMY-gray"); - test_gray(4, "test/CMYK-gray"); - test_gray(6, "test/CcMmYK-gray"); - test_gray(7, "test/CcMmYKk-gray"); - - /* - * Return with no errors... - */ - - return (0); -} - - -/* - * 'test_gray()' - Test grayscale separations... - */ - -void -test_gray(int num_comps, /* I - Number of components */ - const char *basename) /* I - Base filename of output */ -{ - int i; /* Looping var */ - char filename[255]; /* Output filename */ - char line[255]; /* Line from PGM file */ - int width, height; /* Width and height of test image */ - int x, y; /* Current coordinate in image */ - int r, g, b; /* Current RGB color */ - unsigned char input[7000]; /* Line to separate */ - short output[48000], /* Output separation data */ - *outptr; /* Pointer in output */ - FILE *in; /* Input PPM file */ - FILE *out[CUPS_MAX_CHAN]; - /* Output PGM files */ - FILE *comp; /* Composite output */ - cups_cmyk_t *cmyk; /* Color separation */ - - - /* - * Open the test image... - */ - - in = fopen("image.pgm", "rb"); - while (fgets(line, sizeof(line), in) != NULL) - if (isdigit(line[0])) - break; - - sscanf(line, "%d%d", &width, &height); - - fgets(line, sizeof(line), in); - - /* - * Create the color separation... - */ - - cmyk = cupsCMYKNew(num_comps); - - switch (num_comps) - { - case 2 : /* Kk */ - cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0); - break; - - case 4 : - cupsCMYKSetGamma(cmyk, 2, 1.0, 0.9); - cupsCMYKSetBlack(cmyk, 0.5, 1.0); - break; - - case 6 : /* CcMmYK */ - cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0); - cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0); - cupsCMYKSetGamma(cmyk, 4, 1.0, 0.9); - cupsCMYKSetBlack(cmyk, 0.5, 1.0); - break; - - case 7 : /* CcMmYKk */ - cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0); - cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0); - cupsCMYKSetGamma(cmyk, 4, 1.0, 0.9); - cupsCMYKSetLtDk(cmyk, 5, 0.5, 1.0); - break; - } - - /* - * Open the color separation files... - */ - - for (i = 0; i < num_comps; i ++) - { - sprintf(filename, "%s%d.pgm", basename, i); - out[i] = fopen(filename, "wb"); - - fprintf(out[i], "P5\n%d %d 255\n", width, height); - } - - sprintf(filename, "%s.ppm", basename); - comp = fopen(filename, "wb"); - - fprintf(comp, "P6\n%d %d 255\n", width, height); - - /* - * Read the image and do the separations... - */ - - for (y = 0; y < height; y ++) - { - fread(input, width, 1, in); - - cupsCMYKDoGray(cmyk, input, output, width); - - for (x = 0, outptr = output; x < width; x ++, outptr += num_comps) - { - for (i = 0; i < num_comps; i ++) - putc(255 - 255 * outptr[i] / 4095, out[i]); - - r = 4095; - g = 4095; - b = 4095; - - switch (num_comps) - { - case 1 : - r -= outptr[0]; - g -= outptr[0]; - b -= outptr[0]; - break; - case 2 : - r -= outptr[0]; - g -= outptr[0]; - b -= outptr[0]; - - r -= outptr[1] / 2; - g -= outptr[1] / 2; - b -= outptr[1] / 2; - break; - case 3 : - r -= outptr[0]; - g -= outptr[1]; - b -= outptr[2]; - break; - case 4 : - r -= outptr[0]; - g -= outptr[1]; - b -= outptr[2]; - - r -= outptr[3]; - g -= outptr[3]; - b -= outptr[3]; - break; - case 6 : - r -= outptr[0] + outptr[1] / 2; - g -= outptr[2] + outptr[3] / 3; - b -= outptr[4]; - - r -= outptr[5]; - g -= outptr[5]; - b -= outptr[5]; - break; - case 7 : - r -= outptr[0] + outptr[1] / 2; - g -= outptr[2] + outptr[3] / 3; - b -= outptr[4]; - - r -= outptr[5] + outptr[6] / 2; - g -= outptr[5] + outptr[6] / 2; - b -= outptr[5] + outptr[6] / 2; - break; - } - - if (r < 0) - putc(0, comp); - else - putc(255 * r / 4095, comp); - - if (g < 0) - putc(0, comp); - else - putc(255 * g / 4095, comp); - - if (b < 0) - putc(0, comp); - else - putc(255 * b / 4095, comp); - } - } - - for (i = 0; i < num_comps; i ++) - fclose(out[i]); - - fclose(comp); - fclose(in); - - cupsCMYKDelete(cmyk); -} - - -/* - * 'test_rgb()' - Test color separations... - */ - -void -test_rgb(int num_comps, /* I - Number of components */ - const char *basename) /* I - Base filename of output */ -{ - int i; /* Looping var */ - char filename[255]; /* Output filename */ - char line[255]; /* Line from PPM file */ - int width, height; /* Width and height of test image */ - int x, y; /* Current coordinate in image */ - int r, g, b; /* Current RGB color */ - unsigned char input[7000]; /* Line to separate */ - short output[48000], /* Output separation data */ - *outptr; /* Pointer in output */ - FILE *in; /* Input PPM file */ - FILE *out[CUPS_MAX_CHAN]; - /* Output PGM files */ - FILE *comp; /* Composite output */ - cups_cmyk_t *cmyk; /* Color separation */ - - - /* - * Open the test image... - */ - - in = fopen("image.ppm", "rb"); - while (fgets(line, sizeof(line), in) != NULL) - if (isdigit(line[0])) - break; - - sscanf(line, "%d%d", &width, &height); - - fgets(line, sizeof(line), in); - - /* - * Create the color separation... - */ - - cmyk = cupsCMYKNew(num_comps); - - cupsCMYKSetBlack(cmyk, 0.5, 1.0); - - switch (num_comps) - { - case 2 : /* Kk */ - cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0); - break; - case 6 : /* CcMmYK */ - cupsCMYKSetGamma(cmyk, 0, 1.0, 0.8); - cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0); - cupsCMYKSetGamma(cmyk, 2, 1.0, 0.8); - cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0); - break; - case 7 : /* CcMmYKk */ - cupsCMYKSetGamma(cmyk, 0, 1.0, 0.8); - cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0); - cupsCMYKSetGamma(cmyk, 2, 1.0, 0.8); - cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0); - cupsCMYKSetLtDk(cmyk, 5, 0.5, 1.0); - break; - } - - /* - * Open the color separation files... - */ - - for (i = 0; i < num_comps; i ++) - { - sprintf(filename, "%s%d.pgm", basename, i); - out[i] = fopen(filename, "wb"); - - fprintf(out[i], "P5\n%d %d 255\n", width, height); - } - - sprintf(filename, "%s.ppm", basename); - comp = fopen(filename, "wb"); - - fprintf(comp, "P6\n%d %d 255\n", width, height); - - /* - * Read the image and do the separations... - */ - - for (y = 0; y < height; y ++) - { - fread(input, width, 3, in); - - cupsCMYKDoRGB(cmyk, input, output, width); - - for (x = 0, outptr = output; x < width; x ++, outptr += num_comps) - { - for (i = 0; i < num_comps; i ++) - putc(255 - 255 * outptr[i] / 4095, out[i]); - - r = 4095; - g = 4095; - b = 4095; - - switch (num_comps) - { - case 1 : - r -= outptr[0]; - g -= outptr[0]; - b -= outptr[0]; - break; - case 2 : - r -= outptr[0]; - g -= outptr[0]; - b -= outptr[0]; - - r -= outptr[1] / 2; - g -= outptr[1] / 2; - b -= outptr[1] / 2; - break; - case 3 : - r -= outptr[0]; - g -= outptr[1]; - b -= outptr[2]; - break; - case 4 : - r -= outptr[0]; - g -= outptr[1]; - b -= outptr[2]; - - r -= outptr[3]; - g -= outptr[3]; - b -= outptr[3]; - break; - case 6 : - r -= outptr[0] + outptr[1] / 2; - g -= outptr[2] + outptr[3] / 3; - b -= outptr[4]; - - r -= outptr[5]; - g -= outptr[5]; - b -= outptr[5]; - break; - case 7 : - r -= outptr[0] + outptr[1] / 2; - g -= outptr[2] + outptr[3] / 3; - b -= outptr[4]; - - r -= outptr[5] + outptr[6] / 2; - g -= outptr[5] + outptr[6] / 2; - b -= outptr[5] + outptr[6] / 2; - break; - } - - if (r < 0) - putc(0, comp); - else - putc(255 * r / 4095, comp); - - if (g < 0) - putc(0, comp); - else - putc(255 * g / 4095, comp); - - if (b < 0) - putc(0, comp); - else - putc(255 * b / 4095, comp); - } - } - - for (i = 0; i < num_comps; i ++) - fclose(out[i]); - - fclose(comp); - fclose(in); - - cupsCMYKDelete(cmyk); -} - - -/* - * End of "$Id$". - */ diff --git a/driver/testdither.c b/driver/testdither.c deleted file mode 100644 index 547e47d05..000000000 --- a/driver/testdither.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * "$Id$" - * - * Dither test program for CUPS. - * - * Try the following: - * - * testdither 0 255 > filename.ppm - * testdither 0 127 255 > filename.ppm - * testdither 0 85 170 255 > filename.ppm - * testdither 0 63 127 170 198 227 255 > filename.ppm - * testdither 0 210 383 > filename.ppm - * testdither 0 82 255 > filename.ppm - * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * main() - Test dithering and output a PPM file. - * usage() - Show program usage... - */ - -/* - * Include necessary headers. - */ - -#include "driver.h" -#include - - -/* - * Local functions... - */ - -void usage(void); - - -/* - * 'main()' - Test dithering and output a PPM file. - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments */ - char *argv[]) /* I - Command-line arguments */ -{ - int x, y; /* Current coordinate in image */ - short line[512]; /* Line to dither */ - unsigned char pixels[512], /* Dither pixels */ - *pixptr; /* Pointer in line */ - int output; /* Output pixel */ - cups_lut_t *lut; /* Dither lookup table */ - cups_dither_t *dither; /* Dither state */ - int nlutvals; /* Number of lookup values */ - float lutvals[16]; /* Lookup values */ - int pixvals[16]; /* Pixel values */ - - - /* - * See if we have lookup table values on the command-line... - */ - - if (argc > 1) - { - /* - * Yes, collect them... - */ - - nlutvals = 0; - - for (x = 1; x < argc; x ++) - if (isdigit(argv[x][0]) && nlutvals < 16) - { - pixvals[nlutvals] = atoi(argv[x]); - lutvals[nlutvals] = atof(argv[x]) / 255.0; - nlutvals ++; - } - else - usage(); - - /* - * See if we have at least 2 values... - */ - - if (nlutvals < 2) - usage(); - } - else - { - /* - * Otherwise use the default 2-entry LUT with values of 0 and 255... - */ - - nlutvals = 2; - lutvals[0] = 0.0; - lutvals[1] = 1.0; - pixvals[0] = 0; - pixvals[1] = 255; - } - - /* - * Create the lookup table and dither state... - */ - - lut = cupsLutNew(nlutvals, lutvals); - dither = cupsDitherNew(512); - - /* - * Put out the PGM header for a raw 256x256x8-bit grayscale file... - */ - - puts("P5\n512\n512\n255"); - - /* - * Dither 512 lines, which are written out in 256 image lines... - */ - - for (y = 0; y < 512; y ++) - { - /* - * Create the grayscale data for the current line... - */ - - for (x = 0; x < 512; x ++) - line[x] = 4095 * ((y / 32) * 16 + x / 32) / 255; - - /* - * Dither the line... - */ - - cupsDitherLine(dither, lut, line, 1, pixels); - - if (y == 0) - { - fputs("DEBUG: pixels =", stderr); - for (x = 0; x < 512; x ++) - fprintf(stderr, " %d", pixels[x]); - fputs("\n", stderr); - } - - /* - * Add or set the output pixel values... - */ - - for (x = 0, pixptr = pixels; x < 512; x ++, pixptr ++) - { - output = 255 - pixvals[*pixptr]; - - if (output < 0) - putchar(0); - else - putchar(output); - } - } - - /* - * Free the dither state and lookup table... - */ - - cupsDitherDelete(dither); - cupsLutDelete(lut); - - /* - * Return with no errors... - */ - - return (0); -} - - -/* - * 'usage()' - Show program usage... - */ - -void -usage(void) -{ - puts("Usage: testdither [val1 val2 [... val16]] >filename.ppm"); - exit(1); -} - - -/* - * End of "$Id$". - */ diff --git a/driver/testdriver.c b/driver/testdriver.c deleted file mode 100644 index 4263920e0..000000000 --- a/driver/testdriver.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * "$Id: testdriver.c 7306 2008-02-15 00:52:38Z mike $" - * - * Sample/test driver interface program for CUPS. - * - * This program handles listing and installing both static PPD files - * in CUPS_DATADIR/model and dynamically generated PPD files using - * the driver helper programs in CUPS_SERVERBIN/driver. - * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * main() - Enumerate or display PPD files. - * cat_ppd() - Display a PPD file. - * list_ppds() - List PPDs. - */ - -/* - * Include necessary headers... - */ - -#include -#include - - -/* - * Local functions... - */ - -static int cat_ppd(const char *uri); -static int list_ppds(const char *name); - - -/* - * Sample data... - */ - -static const char *models[][2] = - { - { "foojet.ppd", "Foo Printer" }, - { "barjet.ppd", "Bar Printer" }, - { "foobar.ppd", "Foo/Bar Multifunction Printer" } - }; - - -/* - * 'main()' - Enumerate or display PPD files. - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line args */ - char *argv[]) /* I - Command-line arguments */ -{ - if (argc == 2 && !strcmp(argv[1], "list")) - return (list_ppds(argv[0])); - else if (argc == 3 && !strcmp(argv[1], "cat")) - return (cat_ppd(argv[2])); - - fprintf(stderr, "ERROR: Usage: %s cat URI\n", argv[0]); - fprintf(stderr, "ERROR: Usage: %s list\n", argv[0]); - return (1); -} - - -/* - * 'cat_ppd()' - Display a PPD file. - */ - -static int /* O - Exit status */ -cat_ppd(const char *uri) /* I - PPD URI */ -{ - int i; /* Looping var */ - char scheme[255], /* URI scheme */ - userpass[255], /* Username/password (unused) */ - hostname[255], /* Hostname (unused) */ - resource[1024]; /* Resource name */ - int port; /* Port (unused) */ - const char *name; /* Pointer to name in URI */ - - - if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), - userpass, sizeof(userpass), hostname, sizeof(hostname), - &port, resource, sizeof(resource)) < HTTP_URI_OK) - { - fprintf(stderr, "ERROR: Bad URI \"%s\"!\n", uri); - return (1); - } - - name = resource + 1; - - for (i = 0 ; i < (int)(sizeof(models) / sizeof(models[0])); i ++) - if (!strcmp(name, models[i][0])) - { - /* - * Actually display the PPD file... - */ - puts("*PPD-Adobe: \"4.3\""); - - puts("*LanguageEncoding: ISOLatin1"); - puts("*LanguageVersion: English"); - puts("*Manufacturer: \"Test\""); - puts("*FileVersion: \"1.0\""); - puts("*FormatVersion: \"4.3\""); - puts("*PSVersion: \"(3010) 1\""); - printf("*PCFileName: \"%s\"\n", models[i][0]); - - printf("*Product: \"(%s)\"\n", models[i][1]); - printf("*ModelName: \"Test %s\"\n", models[i][1]); - printf("*NickName: \"Test %s\"\n", models[i][1]); - printf("*ShortNickName: \"Test %s\"\n", models[i][1]); - - puts("*OpenUI PageSize: PickOne"); - puts("*OrderDependency: 10 AnySetup *PageSetup"); - puts("*DefaultPageSize: Letter"); - puts("*PageSize Letter: \"<>setpagedevice\""); - puts("*PageSize A4: \"<>setpagedevice\""); - puts("*CloseUI: *PageSize"); - - puts("*OpenUI PageRegion: PickOne"); - puts("*OrderDependency: 10 AnySetup *PageRegion"); - puts("*DefaultPageRegion: Letter"); - puts("*PageRegion Letter: \"<>setpagedevice\""); - puts("*PageRegion A4: \"<>setpagedevice\""); - puts("*CloseUI: *PageRegion"); - - puts("*DefaultImageableArea: Letter"); - puts("*ImageableArea Letter: \"0 0 612 792\""); - puts("*ImageableArea A4: \"0 0 595 842\""); - - puts("*DefaultPaperDimension: Letter"); - puts("*PaperDimension Letter: \"612 792\""); - puts("*PaperDimension A4: \"595 842\""); - - return (0); - } - - fprintf(stderr, "ERROR: Unknown URI \"%s\"!\n", uri); - return (1); -} - - -/* - * 'list_ppds()' - List PPDs. - */ - -static int /* O - Exit status */ -list_ppds(const char *name) /* I - Program name */ -{ - int i; /* Looping var */ - const char *base; /* Base name of program */ - - - if ((base = strrchr(name, '/')) != NULL) - base ++; - else - base = name; - - for (i = 0; i < (int)(sizeof(models) / sizeof(models[0])); i ++) - printf("\"%s:///%s\" en \"Test\" \"Test %s\" \"1284 device id\"\n", - base, models[i][0], models[i][1]); - - return (0); -} - - -/* - * End of "$Id: testdriver.c 7306 2008-02-15 00:52:38Z mike $". - */ diff --git a/driver/testrgb.c b/driver/testrgb.c deleted file mode 100644 index b2bd27031..000000000 --- a/driver/testrgb.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * "$Id$" - * - * Test the new RGB color separation code for CUPS. - * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1993-2006 by Easy Software Products, All Rights Reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * main() - Do color rgb tests. - * test_gray() - Test grayscale rgbs... - * test_rgb() - Test color rgbs... - */ - -/* - * Include necessary headers. - */ - -#include -#include "driver.h" -#include - -#ifdef HAVE_LIBLCMS -# include -#endif /* HAVE_LIBLCMS */ - - -void test_gray(cups_sample_t *samples, int num_samples, - int cube_size, int num_comps, const char *basename); -void test_rgb(cups_sample_t *samples, int num_samples, - int cube_size, int num_comps, - const char *basename); - - -/* - * 'main()' - Do color rgb tests. - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments */ - char *argv[]) /* I - Command-line arguments */ -{ - static cups_sample_t CMYK[] = /* Basic 4-color sep */ - { - /*{ r, g, b }, { C, M, Y, K }*/ - { { 0, 0, 0 }, { 0, 0, 0, 255 } }, - { { 255, 0, 0 }, { 0, 255, 240, 0 } }, - { { 0, 255, 0 }, { 200, 0, 200, 0 } }, - { { 255, 255, 0 }, { 0, 0, 240, 0 } }, - { { 0, 0, 255 }, { 200, 200, 0, 0 } }, - { { 255, 0, 255 }, { 0, 200, 0, 0 } }, - { { 0, 255, 255 }, { 200, 0, 0, 0 } }, - { { 255, 255, 255 }, { 0, 0, 0, 0 } } - }; - - - /* - * Make the test directory... - */ - - mkdir("test", 0755); - - /* - * Run tests for CMYK and CMYK separations... - */ - - test_rgb(CMYK, 8, 2, 4, "test/rgb-cmyk"); - - test_gray(CMYK, 8, 2, 4, "test/gray-cmyk"); - - /* - * Return with no errors... - */ - - return (0); -} - - -/* - * 'test_gray()' - Test grayscale rgbs... - */ - -void -test_gray(cups_sample_t *samples, /* I - Sample values */ - int num_samples, /* I - Number of samples */ - int cube_size, /* I - Cube size */ - int num_comps, /* I - Number of components */ - const char *basename) /* I - Base filename of output */ -{ - int i; /* Looping var */ - char filename[255]; /* Output filename */ - char line[255]; /* Line from PPM file */ - int width, height; /* Width and height of test image */ - int x, y; /* Current coordinate in image */ - int r, g, b; /* Current RGB color */ - unsigned char input[7000]; /* Line to rgbarate */ - unsigned char output[48000], /* Output rgb data */ - *outptr; /* Pointer in output */ - FILE *in; /* Input PPM file */ - FILE *out[CUPS_MAX_CHAN]; - /* Output PGM files */ - FILE *comp; /* Composite output */ - cups_rgb_t *rgb; /* Color separation */ - - - /* - * Open the test image... - */ - - in = fopen("image.pgm", "rb"); - while (fgets(line, sizeof(line), in) != NULL) - if (isdigit(line[0])) - break; - - sscanf(line, "%d%d", &width, &height); - - fgets(line, sizeof(line), in); - - /* - * Create the color rgb... - */ - - rgb = cupsRGBNew(num_samples, samples, cube_size, num_comps); - - /* - * Open the color rgb files... - */ - - for (i = 0; i < num_comps; i ++) - { - sprintf(filename, "%s%d.pgm", basename, i); - out[i] = fopen(filename, "wb"); - - fprintf(out[i], "P5\n%d %d 255\n", width, height); - } - - sprintf(filename, "%s.ppm", basename); - comp = fopen(filename, "wb"); - - fprintf(comp, "P6\n%d %d 255\n", width, height); - - /* - * Read the image and do the rgbs... - */ - - for (y = 0; y < height; y ++) - { - fread(input, width, 1, in); - - cupsRGBDoGray(rgb, input, output, width); - - for (x = 0, outptr = output; x < width; x ++, outptr += num_comps) - { - for (i = 0; i < num_comps; i ++) - putc(255 - outptr[i], out[i]); - - r = 255; - g = 255; - b = 255; - - r -= outptr[0]; - g -= outptr[1]; - b -= outptr[2]; - - r -= outptr[3]; - g -= outptr[3]; - b -= outptr[3]; - - if (num_comps > 4) - { - r -= outptr[4] / 2; - g -= outptr[5] / 2; - } - - if (num_comps > 6) - { - r -= outptr[6] / 2; - g -= outptr[6] / 2; - b -= outptr[6] / 2; - } - - if (r < 0) - putc(0, comp); - else - putc(r, comp); - - if (g < 0) - putc(0, comp); - else - putc(g, comp); - - if (b < 0) - putc(0, comp); - else - putc(b, comp); - } - } - - for (i = 0; i < num_comps; i ++) - fclose(out[i]); - - fclose(comp); - fclose(in); - - cupsRGBDelete(rgb); -} - - -/* - * 'test_rgb()' - Test color rgbs... - */ - -void -test_rgb(cups_sample_t *samples, /* I - Sample values */ - int num_samples, /* I - Number of samples */ - int cube_size, /* I - Cube size */ - int num_comps, /* I - Number of components */ - const char *basename) /* I - Base filename of output */ -{ - int i; /* Looping var */ - char filename[255]; /* Output filename */ - char line[255]; /* Line from PPM file */ - int width, height; /* Width and height of test image */ - int x, y; /* Current coordinate in image */ - int r, g, b; /* Current RGB color */ - unsigned char input[7000]; /* Line to rgbarate */ - unsigned char output[48000], /* Output rgb data */ - *outptr; /* Pointer in output */ - FILE *in; /* Input PPM file */ - FILE *out[CUPS_MAX_CHAN]; - /* Output PGM files */ - FILE *comp; /* Composite output */ - cups_rgb_t *rgb; /* Color separation */ - - - /* - * Open the test image... - */ - - in = fopen("image.ppm", "rb"); - while (fgets(line, sizeof(line), in) != NULL) - if (isdigit(line[0])) - break; - - sscanf(line, "%d%d", &width, &height); - - fgets(line, sizeof(line), in); - - /* - * Create the color rgb... - */ - - rgb = cupsRGBNew(num_samples, samples, cube_size, num_comps); - - /* - * Open the color rgb files... - */ - - for (i = 0; i < num_comps; i ++) - { - sprintf(filename, "%s%d.pgm", basename, i); - out[i] = fopen(filename, "wb"); - - fprintf(out[i], "P5\n%d %d 255\n", width, height); - } - - sprintf(filename, "%s.ppm", basename); - comp = fopen(filename, "wb"); - - fprintf(comp, "P6\n%d %d 255\n", width, height); - - /* - * Read the image and do the rgbs... - */ - - for (y = 0; y < height; y ++) - { - fread(input, width, 3, in); - - cupsRGBDoRGB(rgb, input, output, width); - - for (x = 0, outptr = output; x < width; x ++, outptr += num_comps) - { - for (i = 0; i < num_comps; i ++) - putc(255 - outptr[i], out[i]); - - r = 255; - g = 255; - b = 255; - - r -= outptr[0]; - g -= outptr[1]; - b -= outptr[2]; - - r -= outptr[3]; - g -= outptr[3]; - b -= outptr[3]; - - if (num_comps > 4) - { - r -= outptr[4] / 2; - g -= outptr[5] / 2; - } - - if (num_comps > 6) - { - r -= outptr[6] / 2; - g -= outptr[6] / 2; - b -= outptr[6] / 2; - } - - if (r < 0) - putc(0, comp); - else - putc(r, comp); - - if (g < 0) - putc(0, comp); - else - putc(g, comp); - - if (b < 0) - putc(0, comp); - else - putc(b, comp); - } - } - - for (i = 0; i < num_comps; i ++) - fclose(out[i]); - - fclose(comp); - fclose(in); - - cupsRGBDelete(rgb); -} - - -/* - * End of "$Id$". - */ diff --git a/filter/Dependencies b/filter/Dependencies index f4a4c5b89..d51a06c8f 100644 --- a/filter/Dependencies +++ b/filter/Dependencies @@ -1,81 +1,17 @@ # DO NOT DELETE -image-bmp.o: image-private.h image.h ../cups/raster.h ../cups/cups.h -image-bmp.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-bmp.o: ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-bmp.o: ../cups/debug-private.h ../cups/string-private.h ../config.h -image-colorspace.o: image-private.h image.h ../cups/raster.h ../cups/cups.h -image-colorspace.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-colorspace.o: ../cups/http.h ../cups/array.h ../cups/language.h -image-colorspace.o: ../cups/ppd.h ../cups/cups.h ../cups/debug-private.h -image-colorspace.o: ../cups/string-private.h ../config.h -image-gif.o: image-private.h image.h ../cups/raster.h ../cups/cups.h -image-gif.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-gif.o: ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-gif.o: ../cups/debug-private.h ../cups/string-private.h ../config.h -image-jpeg.o: image-private.h image.h ../cups/raster.h ../cups/cups.h -image-jpeg.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-jpeg.o: ../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h -image-jpeg.o: ../cups/cups.h ../cups/debug-private.h ../cups/string-private.h -image-jpeg.o: ../config.h -image-photocd.o: image-private.h image.h ../cups/raster.h ../cups/cups.h -image-photocd.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-photocd.o: ../cups/http.h ../cups/array.h ../cups/language.h -image-photocd.o: ../cups/ppd.h ../cups/cups.h ../cups/debug-private.h -image-photocd.o: ../cups/string-private.h ../config.h -image-pix.o: image-private.h image.h ../cups/raster.h ../cups/cups.h -image-pix.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-pix.o: ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-pix.o: ../cups/debug-private.h ../cups/string-private.h ../config.h -image-png.o: image-private.h image.h ../cups/raster.h ../cups/cups.h -image-png.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-png.o: ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-png.o: ../cups/debug-private.h ../cups/string-private.h ../config.h -image-pnm.o: image-private.h image.h ../cups/raster.h ../cups/cups.h -image-pnm.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-pnm.o: ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-pnm.o: ../cups/debug-private.h ../cups/string-private.h ../config.h -image-sgi.o: image-private.h image.h ../cups/raster.h ../cups/cups.h -image-sgi.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-sgi.o: ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-sgi.o: ../cups/debug-private.h ../cups/string-private.h ../config.h -image-sgi.o: image-sgi.h -image-sgilib.o: image-sgi.h -image-sun.o: image-private.h image.h ../cups/raster.h ../cups/cups.h -image-sun.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-sun.o: ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-sun.o: ../cups/debug-private.h ../cups/string-private.h ../config.h -image-tiff.o: image-private.h image.h ../cups/raster.h ../cups/cups.h -image-tiff.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-tiff.o: ../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h -image-tiff.o: ../cups/cups.h ../cups/debug-private.h ../cups/string-private.h -image-tiff.o: ../config.h -image-zoom.o: image-private.h image.h ../cups/raster.h ../cups/cups.h -image-zoom.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-zoom.o: ../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h -image-zoom.o: ../cups/cups.h ../cups/debug-private.h ../cups/string-private.h -image-zoom.o: ../config.h -image.o: image-private.h image.h ../cups/raster.h ../cups/cups.h -image.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image.o: ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image.o: ../cups/debug-private.h ../cups/string-private.h ../config.h -error.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +error.o: ../cups/raster-private.h ../cups/raster.h ../cups/cups.h error.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h error.o: ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h error.o: ../cups/debug-private.h ../cups/string-private.h ../config.h -interpret.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +interpret.o: ../cups/raster-private.h ../cups/raster.h ../cups/cups.h interpret.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h interpret.o: ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h interpret.o: ../cups/debug-private.h ../cups/string-private.h ../config.h -raster.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +raster.o: ../cups/raster-private.h ../cups/raster.h ../cups/cups.h raster.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h raster.o: ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h raster.o: ../cups/debug-private.h ../cups/string-private.h ../config.h -bannertops.o: pstext.h common.h ../cups/string-private.h ../config.h -bannertops.o: ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -bannertops.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h -bannertops.o: ../cups/array.h ../cups/language.h ../cups/transcode.h image.h -bannertops.o: ../cups/raster.h ../cups/ppd.h ../cups/language-private.h commandtops.o: ../cups/cups-private.h ../cups/cups.h ../cups/string-private.h commandtops.o: ../config.h ../cups/debug-private.h ../cups/ppd-private.h commandtops.o: ../cups/ppd.h ../cups/cups.h ../cups/file.h @@ -93,28 +29,9 @@ gziptoany.o: ../cups/pwg-private.h ../cups/http-private.h ../cups/http.h gziptoany.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h gziptoany.o: ../cups/language-private.h ../cups/transcode.h gziptoany.o: ../cups/thread-private.h -imagetops.o: common.h ../cups/string-private.h ../config.h ../cups/cups.h -imagetops.o: ../cups/ppd.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -imagetops.o: ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -imagetops.o: image.h ../cups/raster.h ../cups/ppd.h -imagetops.o: ../cups/language-private.h ../cups/transcode.h -imagetoraster.o: common.h ../cups/string-private.h ../config.h ../cups/cups.h -imagetoraster.o: ../cups/ppd.h ../cups/cups.h ../cups/file.h -imagetoraster.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h -imagetoraster.o: ../cups/array.h ../cups/language.h image-private.h image.h -imagetoraster.o: ../cups/raster.h ../cups/ppd.h ../cups/debug-private.h -imagetoraster.o: ../cups/language-private.h ../cups/transcode.h common.o: common.h ../cups/string-private.h ../config.h ../cups/cups.h common.o: ../cups/ppd.h ../cups/cups.h ../cups/file.h ../cups/versioning.h common.o: ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -pdftops.o: ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -pdftops.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h -pdftops.o: ../cups/language.h ../cups/string-private.h ../config.h -pdftops.o: ../cups/language-private.h ../cups/transcode.h -pstext.o: pstext.h common.h ../cups/string-private.h ../config.h -pstext.o: ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -pstext.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h -pstext.o: ../cups/language.h ../cups/transcode.h ../cups/language-private.h pstops.o: common.h ../cups/string-private.h ../config.h ../cups/cups.h pstops.o: ../cups/ppd.h ../cups/cups.h ../cups/file.h ../cups/versioning.h pstops.o: ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h @@ -143,101 +60,25 @@ rastertopwg.o: ../cups/language.h ../cups/array.h ../cups/versioning.h rastertopwg.o: ../cups/raster.h ../cups/cups.h ../cups/file.h ../cups/ipp.h rastertopwg.o: ../cups/http.h ../cups/ppd.h ../cups/string-private.h rastertopwg.o: ../config.h -testimage.o: image.h ../cups/raster.h ../cups/cups.h ../cups/file.h -testimage.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h -testimage.o: ../cups/array.h ../cups/language.h ../cups/ppd.h -testraster.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +testraster.o: ../cups/raster-private.h ../cups/raster.h ../cups/cups.h testraster.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h testraster.o: ../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h testraster.o: ../cups/cups.h ../cups/debug-private.h ../cups/string-private.h testraster.o: ../config.h -textcommon.o: textcommon.h common.h ../cups/string-private.h ../config.h -textcommon.o: ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -textcommon.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h -textcommon.o: ../cups/array.h ../cups/language.h ../cups/language-private.h -textcommon.o: ../cups/transcode.h -texttops.o: textcommon.h common.h ../cups/string-private.h ../config.h -texttops.o: ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -texttops.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h -texttops.o: ../cups/language.h ../cups/language-private.h ../cups/transcode.h # DO NOT DELETE -image-bmp.32.o: image-bmp.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-bmp.32.o: image-bmp.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-bmp.32.o: image-bmp.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-bmp.32.o: image-bmp.c ../cups/debug-private.h ../cups/string-private.h ../config.h -image-colorspace.32.o: image-colorspace.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-colorspace.32.o: image-colorspace.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-colorspace.32.o: image-colorspace.c ../cups/http.h ../cups/array.h ../cups/language.h -image-colorspace.32.o: image-colorspace.c ../cups/ppd.h ../cups/cups.h ../cups/debug-private.h -image-colorspace.32.o: image-colorspace.c ../cups/string-private.h ../config.h -image-gif.32.o: image-gif.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-gif.32.o: image-gif.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-gif.32.o: image-gif.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-gif.32.o: image-gif.c ../cups/debug-private.h ../cups/string-private.h ../config.h -image-jpeg.32.o: image-jpeg.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-jpeg.32.o: image-jpeg.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-jpeg.32.o: image-jpeg.c ../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h -image-jpeg.32.o: image-jpeg.c ../cups/cups.h ../cups/debug-private.h ../cups/string-private.h -image-jpeg.32.o: image-jpeg.c ../config.h -image-photocd.32.o: image-photocd.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-photocd.32.o: image-photocd.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-photocd.32.o: image-photocd.c ../cups/http.h ../cups/array.h ../cups/language.h -image-photocd.32.o: image-photocd.c ../cups/ppd.h ../cups/cups.h ../cups/debug-private.h -image-photocd.32.o: image-photocd.c ../cups/string-private.h ../config.h -image-pix.32.o: image-pix.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-pix.32.o: image-pix.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-pix.32.o: image-pix.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-pix.32.o: image-pix.c ../cups/debug-private.h ../cups/string-private.h ../config.h -image-png.32.o: image-png.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-png.32.o: image-png.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-png.32.o: image-png.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-png.32.o: image-png.c ../cups/debug-private.h ../cups/string-private.h ../config.h -image-pnm.32.o: image-pnm.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-pnm.32.o: image-pnm.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-pnm.32.o: image-pnm.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-pnm.32.o: image-pnm.c ../cups/debug-private.h ../cups/string-private.h ../config.h -image-sgi.32.o: image-sgi.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-sgi.32.o: image-sgi.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-sgi.32.o: image-sgi.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-sgi.32.o: image-sgi.c ../cups/debug-private.h ../cups/string-private.h ../config.h -image-sgi.32.o: image-sgi.c image-sgi.h -image-sgilib.32.o: image-sgilib.c image-sgi.h -image-sun.32.o: image-sun.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-sun.32.o: image-sun.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-sun.32.o: image-sun.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-sun.32.o: image-sun.c ../cups/debug-private.h ../cups/string-private.h ../config.h -image-tiff.32.o: image-tiff.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-tiff.32.o: image-tiff.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-tiff.32.o: image-tiff.c ../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h -image-tiff.32.o: image-tiff.c ../cups/cups.h ../cups/debug-private.h ../cups/string-private.h -image-tiff.32.o: image-tiff.c ../config.h -image-zoom.32.o: image-zoom.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-zoom.32.o: image-zoom.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-zoom.32.o: image-zoom.c ../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h -image-zoom.32.o: image-zoom.c ../cups/cups.h ../cups/debug-private.h ../cups/string-private.h -image-zoom.32.o: image-zoom.c ../config.h -image.32.o: image.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image.32.o: image.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image.32.o: image.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image.32.o: image.c ../cups/debug-private.h ../cups/string-private.h ../config.h -error.32.o: error.c image-private.h image.h ../cups/raster.h ../cups/cups.h +error.32.o: error.c ../cups/raster-private.h ../cups/raster.h ../cups/cups.h error.32.o: error.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h error.32.o: error.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h error.32.o: error.c ../cups/debug-private.h ../cups/string-private.h ../config.h -interpret.32.o: interpret.c image-private.h image.h ../cups/raster.h ../cups/cups.h +interpret.32.o: interpret.c ../cups/raster-private.h ../cups/raster.h ../cups/cups.h interpret.32.o: interpret.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h interpret.32.o: interpret.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h interpret.32.o: interpret.c ../cups/debug-private.h ../cups/string-private.h ../config.h -raster.32.o: raster.c image-private.h image.h ../cups/raster.h ../cups/cups.h +raster.32.o: raster.c ../cups/raster-private.h ../cups/raster.h ../cups/cups.h raster.32.o: raster.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h raster.32.o: raster.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h raster.32.o: raster.c ../cups/debug-private.h ../cups/string-private.h ../config.h -bannertops.32.o: bannertops.c pstext.h common.h ../cups/string-private.h ../config.h -bannertops.32.o: bannertops.c ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -bannertops.32.o: bannertops.c ../cups/versioning.h ../cups/ipp.h ../cups/http.h -bannertops.32.o: bannertops.c ../cups/array.h ../cups/language.h ../cups/transcode.h image.h -bannertops.32.o: bannertops.c ../cups/raster.h ../cups/ppd.h ../cups/language-private.h commandtops.32.o: commandtops.c ../cups/cups-private.h ../cups/cups.h ../cups/string-private.h commandtops.32.o: commandtops.c ../config.h ../cups/debug-private.h ../cups/ppd-private.h commandtops.32.o: commandtops.c ../cups/ppd.h ../cups/cups.h ../cups/file.h @@ -255,28 +96,9 @@ gziptoany.32.o: gziptoany.c ../cups/pwg-private.h ../cups/http-private.h ../cup gziptoany.32.o: gziptoany.c ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h gziptoany.32.o: gziptoany.c ../cups/language-private.h ../cups/transcode.h gziptoany.32.o: gziptoany.c ../cups/thread-private.h -imagetops.32.o: imagetops.c common.h ../cups/string-private.h ../config.h ../cups/cups.h -imagetops.32.o: imagetops.c ../cups/ppd.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -imagetops.32.o: imagetops.c ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -imagetops.32.o: imagetops.c image.h ../cups/raster.h ../cups/ppd.h -imagetops.32.o: imagetops.c ../cups/language-private.h ../cups/transcode.h -imagetoraster.32.o: imagetoraster.c common.h ../cups/string-private.h ../config.h ../cups/cups.h -imagetoraster.32.o: imagetoraster.c ../cups/ppd.h ../cups/cups.h ../cups/file.h -imagetoraster.32.o: imagetoraster.c ../cups/versioning.h ../cups/ipp.h ../cups/http.h -imagetoraster.32.o: imagetoraster.c ../cups/array.h ../cups/language.h image-private.h image.h -imagetoraster.32.o: imagetoraster.c ../cups/raster.h ../cups/ppd.h ../cups/debug-private.h -imagetoraster.32.o: imagetoraster.c ../cups/language-private.h ../cups/transcode.h common.32.o: common.c common.h ../cups/string-private.h ../config.h ../cups/cups.h common.32.o: common.c ../cups/ppd.h ../cups/cups.h ../cups/file.h ../cups/versioning.h common.32.o: common.c ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -pdftops.32.o: pdftops.c ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -pdftops.32.o: pdftops.c ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h -pdftops.32.o: pdftops.c ../cups/language.h ../cups/string-private.h ../config.h -pdftops.32.o: pdftops.c ../cups/language-private.h ../cups/transcode.h -pstext.32.o: pstext.c pstext.h common.h ../cups/string-private.h ../config.h -pstext.32.o: pstext.c ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -pstext.32.o: pstext.c ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h -pstext.32.o: pstext.c ../cups/language.h ../cups/transcode.h ../cups/language-private.h pstops.32.o: pstops.c common.h ../cups/string-private.h ../config.h ../cups/cups.h pstops.32.o: pstops.c ../cups/ppd.h ../cups/cups.h ../cups/file.h ../cups/versioning.h pstops.32.o: pstops.c ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h @@ -305,101 +127,25 @@ rastertopwg.32.o: rastertopwg.c ../cups/language.h ../cups/array.h ../cups/vers rastertopwg.32.o: rastertopwg.c ../cups/raster.h ../cups/cups.h ../cups/file.h ../cups/ipp.h rastertopwg.32.o: rastertopwg.c ../cups/http.h ../cups/ppd.h ../cups/string-private.h rastertopwg.32.o: rastertopwg.c ../config.h -testimage.32.o: testimage.c image.h ../cups/raster.h ../cups/cups.h ../cups/file.h -testimage.32.o: testimage.c ../cups/versioning.h ../cups/ipp.h ../cups/http.h -testimage.32.o: testimage.c ../cups/array.h ../cups/language.h ../cups/ppd.h -testraster.32.o: testraster.c image-private.h image.h ../cups/raster.h ../cups/cups.h +testraster.32.o: testraster.c ../cups/raster-private.h ../cups/raster.h ../cups/cups.h testraster.32.o: testraster.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h testraster.32.o: testraster.c ../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h testraster.32.o: testraster.c ../cups/cups.h ../cups/debug-private.h ../cups/string-private.h testraster.32.o: testraster.c ../config.h -textcommon.32.o: textcommon.c textcommon.h common.h ../cups/string-private.h ../config.h -textcommon.32.o: textcommon.c ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -textcommon.32.o: textcommon.c ../cups/versioning.h ../cups/ipp.h ../cups/http.h -textcommon.32.o: textcommon.c ../cups/array.h ../cups/language.h ../cups/language-private.h -textcommon.32.o: textcommon.c ../cups/transcode.h -texttops.32.o: texttops.c textcommon.h common.h ../cups/string-private.h ../config.h -texttops.32.o: texttops.c ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -texttops.32.o: texttops.c ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h -texttops.32.o: texttops.c ../cups/language.h ../cups/language-private.h ../cups/transcode.h # DO NOT DELETE -image-bmp.64.o: image-bmp.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-bmp.64.o: image-bmp.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-bmp.64.o: image-bmp.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-bmp.64.o: image-bmp.c ../cups/debug-private.h ../cups/string-private.h ../config.h -image-colorspace.64.o: image-colorspace.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-colorspace.64.o: image-colorspace.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-colorspace.64.o: image-colorspace.c ../cups/http.h ../cups/array.h ../cups/language.h -image-colorspace.64.o: image-colorspace.c ../cups/ppd.h ../cups/cups.h ../cups/debug-private.h -image-colorspace.64.o: image-colorspace.c ../cups/string-private.h ../config.h -image-gif.64.o: image-gif.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-gif.64.o: image-gif.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-gif.64.o: image-gif.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-gif.64.o: image-gif.c ../cups/debug-private.h ../cups/string-private.h ../config.h -image-jpeg.64.o: image-jpeg.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-jpeg.64.o: image-jpeg.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-jpeg.64.o: image-jpeg.c ../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h -image-jpeg.64.o: image-jpeg.c ../cups/cups.h ../cups/debug-private.h ../cups/string-private.h -image-jpeg.64.o: image-jpeg.c ../config.h -image-photocd.64.o: image-photocd.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-photocd.64.o: image-photocd.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-photocd.64.o: image-photocd.c ../cups/http.h ../cups/array.h ../cups/language.h -image-photocd.64.o: image-photocd.c ../cups/ppd.h ../cups/cups.h ../cups/debug-private.h -image-photocd.64.o: image-photocd.c ../cups/string-private.h ../config.h -image-pix.64.o: image-pix.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-pix.64.o: image-pix.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-pix.64.o: image-pix.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-pix.64.o: image-pix.c ../cups/debug-private.h ../cups/string-private.h ../config.h -image-png.64.o: image-png.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-png.64.o: image-png.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-png.64.o: image-png.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-png.64.o: image-png.c ../cups/debug-private.h ../cups/string-private.h ../config.h -image-pnm.64.o: image-pnm.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-pnm.64.o: image-pnm.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-pnm.64.o: image-pnm.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-pnm.64.o: image-pnm.c ../cups/debug-private.h ../cups/string-private.h ../config.h -image-sgi.64.o: image-sgi.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-sgi.64.o: image-sgi.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-sgi.64.o: image-sgi.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-sgi.64.o: image-sgi.c ../cups/debug-private.h ../cups/string-private.h ../config.h -image-sgi.64.o: image-sgi.c image-sgi.h -image-sgilib.64.o: image-sgilib.c image-sgi.h -image-sun.64.o: image-sun.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-sun.64.o: image-sun.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image-sun.64.o: image-sun.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image-sun.64.o: image-sun.c ../cups/debug-private.h ../cups/string-private.h ../config.h -image-tiff.64.o: image-tiff.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-tiff.64.o: image-tiff.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-tiff.64.o: image-tiff.c ../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h -image-tiff.64.o: image-tiff.c ../cups/cups.h ../cups/debug-private.h ../cups/string-private.h -image-tiff.64.o: image-tiff.c ../config.h -image-zoom.64.o: image-zoom.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image-zoom.64.o: image-zoom.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h -image-zoom.64.o: image-zoom.c ../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h -image-zoom.64.o: image-zoom.c ../cups/cups.h ../cups/debug-private.h ../cups/string-private.h -image-zoom.64.o: image-zoom.c ../config.h -image.64.o: image.c image-private.h image.h ../cups/raster.h ../cups/cups.h -image.64.o: image.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -image.64.o: image.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h -image.64.o: image.c ../cups/debug-private.h ../cups/string-private.h ../config.h -error.64.o: error.c image-private.h image.h ../cups/raster.h ../cups/cups.h +error.64.o: error.c ../cups/raster-private.h ../cups/raster.h ../cups/cups.h error.64.o: error.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h error.64.o: error.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h error.64.o: error.c ../cups/debug-private.h ../cups/string-private.h ../config.h -interpret.64.o: interpret.c image-private.h image.h ../cups/raster.h ../cups/cups.h +interpret.64.o: interpret.c ../cups/raster-private.h ../cups/raster.h ../cups/cups.h interpret.64.o: interpret.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h interpret.64.o: interpret.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h interpret.64.o: interpret.c ../cups/debug-private.h ../cups/string-private.h ../config.h -raster.64.o: raster.c image-private.h image.h ../cups/raster.h ../cups/cups.h +raster.64.o: raster.c ../cups/raster-private.h ../cups/raster.h ../cups/cups.h raster.64.o: raster.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h raster.64.o: raster.c ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/cups.h raster.64.o: raster.c ../cups/debug-private.h ../cups/string-private.h ../config.h -bannertops.64.o: bannertops.c pstext.h common.h ../cups/string-private.h ../config.h -bannertops.64.o: bannertops.c ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -bannertops.64.o: bannertops.c ../cups/versioning.h ../cups/ipp.h ../cups/http.h -bannertops.64.o: bannertops.c ../cups/array.h ../cups/language.h ../cups/transcode.h image.h -bannertops.64.o: bannertops.c ../cups/raster.h ../cups/ppd.h ../cups/language-private.h commandtops.64.o: commandtops.c ../cups/cups-private.h ../cups/cups.h ../cups/string-private.h commandtops.64.o: commandtops.c ../config.h ../cups/debug-private.h ../cups/ppd-private.h commandtops.64.o: commandtops.c ../cups/ppd.h ../cups/cups.h ../cups/file.h @@ -417,28 +163,9 @@ gziptoany.64.o: gziptoany.c ../cups/pwg-private.h ../cups/http-private.h ../cup gziptoany.64.o: gziptoany.c ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h gziptoany.64.o: gziptoany.c ../cups/language-private.h ../cups/transcode.h gziptoany.64.o: gziptoany.c ../cups/thread-private.h -imagetops.64.o: imagetops.c common.h ../cups/string-private.h ../config.h ../cups/cups.h -imagetops.64.o: imagetops.c ../cups/ppd.h ../cups/cups.h ../cups/file.h ../cups/versioning.h -imagetops.64.o: imagetops.c ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -imagetops.64.o: imagetops.c image.h ../cups/raster.h ../cups/ppd.h -imagetops.64.o: imagetops.c ../cups/language-private.h ../cups/transcode.h -imagetoraster.64.o: imagetoraster.c common.h ../cups/string-private.h ../config.h ../cups/cups.h -imagetoraster.64.o: imagetoraster.c ../cups/ppd.h ../cups/cups.h ../cups/file.h -imagetoraster.64.o: imagetoraster.c ../cups/versioning.h ../cups/ipp.h ../cups/http.h -imagetoraster.64.o: imagetoraster.c ../cups/array.h ../cups/language.h image-private.h image.h -imagetoraster.64.o: imagetoraster.c ../cups/raster.h ../cups/ppd.h ../cups/debug-private.h -imagetoraster.64.o: imagetoraster.c ../cups/language-private.h ../cups/transcode.h common.64.o: common.c common.h ../cups/string-private.h ../config.h ../cups/cups.h common.64.o: common.c ../cups/ppd.h ../cups/cups.h ../cups/file.h ../cups/versioning.h common.64.o: common.c ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h -pdftops.64.o: pdftops.c ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -pdftops.64.o: pdftops.c ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h -pdftops.64.o: pdftops.c ../cups/language.h ../cups/string-private.h ../config.h -pdftops.64.o: pdftops.c ../cups/language-private.h ../cups/transcode.h -pstext.64.o: pstext.c pstext.h common.h ../cups/string-private.h ../config.h -pstext.64.o: pstext.c ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -pstext.64.o: pstext.c ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h -pstext.64.o: pstext.c ../cups/language.h ../cups/transcode.h ../cups/language-private.h pstops.64.o: pstops.c common.h ../cups/string-private.h ../config.h ../cups/cups.h pstops.64.o: pstops.c ../cups/ppd.h ../cups/cups.h ../cups/file.h ../cups/versioning.h pstops.64.o: pstops.c ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h @@ -467,20 +194,8 @@ rastertopwg.64.o: rastertopwg.c ../cups/language.h ../cups/array.h ../cups/vers rastertopwg.64.o: rastertopwg.c ../cups/raster.h ../cups/cups.h ../cups/file.h ../cups/ipp.h rastertopwg.64.o: rastertopwg.c ../cups/http.h ../cups/ppd.h ../cups/string-private.h rastertopwg.64.o: rastertopwg.c ../config.h -testimage.64.o: testimage.c image.h ../cups/raster.h ../cups/cups.h ../cups/file.h -testimage.64.o: testimage.c ../cups/versioning.h ../cups/ipp.h ../cups/http.h -testimage.64.o: testimage.c ../cups/array.h ../cups/language.h ../cups/ppd.h -testraster.64.o: testraster.c image-private.h image.h ../cups/raster.h ../cups/cups.h +testraster.64.o: testraster.c ../cups/raster-private.h ../cups/raster.h ../cups/cups.h testraster.64.o: testraster.c ../cups/file.h ../cups/versioning.h ../cups/ipp.h testraster.64.o: testraster.c ../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h testraster.64.o: testraster.c ../cups/cups.h ../cups/debug-private.h ../cups/string-private.h testraster.64.o: testraster.c ../config.h -textcommon.64.o: textcommon.c textcommon.h common.h ../cups/string-private.h ../config.h -textcommon.64.o: textcommon.c ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -textcommon.64.o: textcommon.c ../cups/versioning.h ../cups/ipp.h ../cups/http.h -textcommon.64.o: textcommon.c ../cups/array.h ../cups/language.h ../cups/language-private.h -textcommon.64.o: textcommon.c ../cups/transcode.h -texttops.64.o: texttops.c textcommon.h common.h ../cups/string-private.h ../config.h -texttops.64.o: texttops.c ../cups/cups.h ../cups/ppd.h ../cups/cups.h ../cups/file.h -texttops.64.o: texttops.c ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h -texttops.64.o: texttops.c ../cups/language.h ../cups/language-private.h ../cups/transcode.h diff --git a/filter/Makefile b/filter/Makefile index 104d4cda6..e7440eefe 100644 --- a/filter/Makefile +++ b/filter/Makefile @@ -19,13 +19,9 @@ include ../Makedefs FILTERS = \ - $(BANNERTOPS) \ commandtops \ gziptoany \ - $(TEXTTOPS) \ pstops \ - $(IMGFILTERS) \ - $(PDFTOPS) \ rastertoepson \ rastertohp \ rastertolabel \ @@ -37,23 +33,18 @@ LIBTARGETS = \ $(LIB64CUPSIMAGE) UNITTARGETS = \ rasterbench \ - testimage \ testraster TARGETS = \ $(LIBTARGETS) \ $(FILTERS) -IMAGEOBJS = image-bmp.o image-colorspace.o image-gif.o image-jpeg.o \ - image-photocd.o image-pix.o image-png.o image-pnm.o \ - image-sgi.o image-sgilib.o image-sun.o image-tiff.o \ - image-zoom.o image.o error.o interpret.o raster.o +IMAGEOBJS = error.o interpret.o raster.o IMAGE32OBJS = $(IMAGEOBJS:.o=.32.o) IMAGE64OBJS = $(IMAGEOBJS:.o=.64.o) OBJS = $(IMAGEOBJS) \ - bannertops.o commandtops.o gziptoany.o imagetops.o \ - imagetoraster.o common.o pdftops.o pstext.o pstops.o \ + commandtops.o gziptoany.o common.o pstops.o \ rasterbench.o rastertoepson.o rastertohp.o rastertolabel.o \ - rastertopwg.o testimage.o testraster.o textcommon.o texttops.o + rastertopwg.o testraster.o # @@ -139,8 +130,6 @@ install-exec: # install-headers: - $(INSTALL_DIR) -m 755 $(INCLUDEDIR)/cups - $(INSTALL_DATA) image.h $(INCLUDEDIR)/cups # @@ -200,8 +189,6 @@ uninstall: $(UNINSTALL32) $(UNINSTALL64) $(RM) $(LIBDIR)/libcupsimage.so $(RM) $(LIBDIR)/libcupsimage.so.2 -$(RMDIR) $(LIBDIR) - $(RM) $(INCLUDEDIR)/cups/image.h - -$(RMDIR) $(INCLUDEDIR)/cups uninstall32bit: $(RM) $(LIB32DIR)/libcupsimage.so @@ -286,16 +273,6 @@ framedhelp: --intro spec-ppd.shtml \ -# -# bannertops -# - -bannertops: bannertops.o pstext.o common.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE) - echo Linking $@... - $(CC) $(LDFLAGS) -o $@ bannertops.o pstext.o common.o $(LINKCUPSIMAGE) \ - $(IMGLIBS) $(LIBS) - - # # commandtops # @@ -397,38 +374,6 @@ libcupsimage.a: $(IMAGEOBJS) $(RANLIB) $@ -# -# testimage -# - -testimage: testimage.o libcupsimage.a ../Makedefs - echo Linking $@... - $(CC) $(LDFLAGS) -o $@ testimage.o libcupsimage.a \ - $(IMGLIBS) $(DSOLIBS) $(LIBS) - - -# -# imagetops -# - -imagetops: imagetops.o common.o $(LIBCUPSIMAGE) \ - ../cups/$(LIBCUPS) - echo Linking $@... - $(CC) $(LDFLAGS) -o $@ imagetops.o common.o $(LINKCUPSIMAGE) \ - $(IMGLIBS) $(LIBS) - - -# -# imagetoraster -# - -imagetoraster: imagetoraster.o common.o $(LIBCUPSIMAGE) \ - ../cups/$(LIBCUPS) - echo Linking $@... - $(CC) $(LDFLAGS) -o $@ imagetoraster.o common.o $(LINKCUPSIMAGE) \ - $(IMGLIBS) $(LIBS) - - # # pstops # @@ -438,15 +383,6 @@ pstops: pstops.o common.o ../cups/$(LIBCUPS) $(CC) $(LDFLAGS) -o $@ pstops.o common.o $(LIBS) -lm -# -# pdftops -# - -pdftops: pdftops.o common.o ../cups/$(LIBCUPS) - echo Linking $@... - $(CC) $(LDFLAGS) -o $@ pdftops.o common.o $(LIBS) - - # # rastertoepson # @@ -505,16 +441,6 @@ rasterbench: rasterbench.o libcupsimage.a $(CC) $(LDFLAGS) -o $@ rasterbench.o libcupsimage.a $(LIBS) -# -# texttops -# - -texttops: texttops.o textcommon.o common.o \ - ../cups/$(LIBCUPS) - echo Linking $@... - $(CC) $(LDFLAGS) -o $@ texttops.o textcommon.o common.o $(LIBS) - - # # Dependencies... # diff --git a/filter/bannertops.c b/filter/bannertops.c deleted file mode 100644 index 467980e99..000000000 --- a/filter/bannertops.c +++ /dev/null @@ -1,1094 +0,0 @@ -/* - * "$Id$" - * - * Banner to PostScript filter for CUPS. - * - * Copyright 2008-2011 by Apple Inc. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * main() - Generate PostScript cover pages. - * load_banner() - Load the banner file. - * ps_ascii85() - Print binary data as a series of base-85 numbers. - * write_banner() - Write a banner page... - * write_epilogue() - Write the PostScript file epilogue. - * write_prolog() - Write the PostScript file prolog with options. - */ - -/* - * Include necessary headers... - */ - -#include "pstext.h" -#include "image.h" -#include - - -/* - * Constants... - */ - -#define SHOW_IMAGEABLE_AREA 1 /* Show imageable area */ -#define SHOW_JOB_BILLING 2 /* Show billing string */ -#define SHOW_JOB_ID 4 /* Show job ID */ -#define SHOW_JOB_NAME 8 /* Show job title */ -#define SHOW_JOB_ORIGINATING_USER_NAME 16 /* Show owner of job */ -#define SHOW_JOB_ORIGINATING_HOST_NAME 32 /* Show submitting system */ -#define SHOW_JOB_UUID 64 /* Show job UUID */ -#define SHOW_OPTIONS 128 /* Show print options */ -#define SHOW_PAPER_NAME 256 /* Show paper size name */ -#define SHOW_PAPER_SIZE 512 /* Show paper dimensions */ -#define SHOW_PRINTER_DRIVER_NAME 1024 /* Show printer driver name */ -#define SHOW_PRINTER_DRIVER_VERSION 2048 /* Show printer driver version */ -#define SHOW_PRINTER_INFO 4096 /* Show printer description */ -#define SHOW_PRINTER_LOCATION 8192 /* Show printer location */ -#define SHOW_PRINTER_MAKE_AND_MODEL 16384 /* Show printer make and model */ -#define SHOW_PRINTER_NAME 32768 /* Show printer queue ID */ -#define SHOW_TIME_AT_CREATION 65536 /* Show date/time when submitted */ -#define SHOW_TIME_AT_PROCESSING 131072 /* Show date/time when printed */ - - -/* - * Structures... - */ - -typedef struct banner_file_s /**** Banner file data ****/ -{ - int show; /* What to show */ - char *header, /* Header text */ - *footer; /* Footer text */ - cups_array_t *notices, /* Notices to show */ - *images; /* Images to show */ -} banner_file_t; - - -/* - * Local functions... - */ - -static banner_file_t *load_banner(const char *filename); -static int write_banner(banner_file_t *banner, ppd_file_t *ppd, - ps_text_t *fonts, int job_id, - const char *title, const char *username, - int num_options, cups_option_t *options); -static void write_epilogue(int num_pages); -static ps_text_t *write_prolog(const char *title, const char *user); - - -/* - * 'main()' - Generate PostScript cover pages. - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line args */ - char *argv[]) /* I - Command-line arguments */ -{ - banner_file_t *banner; /* Banner file data */ - int num_options; /* Number of print options */ - cups_option_t *options; /* Print options */ - ppd_file_t *ppd; /* PPD file */ - ps_text_t *fonts; /* Fonts for output */ - int job_id; /* Job ID from command-line */ - const char *title, /* Title from command-line */ - *username; /* Username from command-line */ - int num_pages; /* Number of pages printed */ - - - /* - * Make sure status messages are not buffered... - */ - - setbuf(stderr, NULL); - - /* - * Check command-line... - */ - - if (argc < 6 || argc > 7) - { - _cupsLangPrintf(stderr, - _("Usage: %s job-id user title copies options file"), - argv[0]); - return (1); - } - - /* - * Get stuff from command-line... - */ - - job_id = atoi(argv[1]); - username = argv[2]; - title = argv[3]; - options = NULL; - num_options = cupsParseOptions(argv[5], 0, &options); - banner = load_banner(argv[6]); - - /* - * Set standard options and get the PPD file for this printer... - */ - - ppd = SetCommonOptions(num_options, options, 1); - - /* - * Write a PostScript banner document and return... - */ - - fonts = write_prolog(title, username); - num_pages = write_banner(banner, ppd, fonts, job_id, title, username, - num_options, options); - - write_epilogue(num_pages); - - return (0); -} - - -/* - * 'load_banner()' - Load the banner file. - */ - -static banner_file_t * /* O - Banner file data */ -load_banner(const char *filename) /* I - Filename or NULL for stdin */ -{ - cups_file_t *fp; /* File */ - char line[2048], /* Line buffer */ - *ptr; /* Pointer into line */ - int linenum; /* Current line number */ - banner_file_t *banner; /* Banner file data */ - const char *cups_docroot; /* CUPS_DOCROOT environment variable */ - - - fprintf(stderr, "DEBUG: load_banner(filename=\"%s\")\n", - filename ? filename : "(stdin)"); - - /* - * Open the banner file... - */ - - if (filename) - fp = cupsFileOpen(filename, "r"); - else - fp = cupsFileStdin(); - - if (!fp) - { - _cupsLangPrintError("ERROR", _("Unable to open print file")); - exit(1); - } - - /* - * Read the banner file... - */ - - if ((cups_docroot = getenv("CUPS_DOCROOT")) == NULL) - cups_docroot = CUPS_DOCROOT; - - banner = calloc(1, sizeof(banner_file_t)); - linenum = 0; - - while (cupsFileGets(fp, line, sizeof(line))) - { - /* - * Skip blank and comment lines... - */ - - linenum ++; - - fprintf(stderr, "DEBUG: %4d %s\n", linenum, line); - - if (line[0] == '#' || !line[0]) - continue; - - /* - * Break the line into keyword and value parts... - */ - - for (ptr = line; *ptr && !isspace(*ptr & 255); ptr ++); - - while (isspace(*ptr & 255)) - *ptr++ = '\0'; - - if (!*ptr) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Missing value on line %d of banner file."), - linenum); - continue; - } - - /* - * Save keyword values in the appropriate places... - */ - - if (!_cups_strcasecmp(line, "Footer")) - { - if (banner->footer) - fprintf(stderr, "DEBUG: Extra \"Footer\" on line %d of banner file\n", - linenum); - else - banner->footer = strdup(ptr); - } - else if (!_cups_strcasecmp(line, "Header")) - { - if (banner->header) - fprintf(stderr, "DEBUG: Extra \"Header\" on line %d of banner file\n", - linenum); - else - banner->header = strdup(ptr); - } - else if (!_cups_strcasecmp(line, "Image")) - { - char imagefile[1024]; /* Image filename */ - - - if (ptr[0] == '/') - strlcpy(imagefile, ptr, sizeof(imagefile)); - else - snprintf(imagefile, sizeof(imagefile), "%s/%s", cups_docroot, ptr); - - if (access(imagefile, R_OK)) - { - fprintf(stderr, "DEBUG: Image \"%s\" on line %d of banner file: %s\n", - ptr, linenum, strerror(errno)); - } - else - { - if (!banner->images) - banner->images = cupsArrayNew(NULL, NULL); - - cupsArrayAdd(banner->images, strdup(imagefile)); - } - } - else if (!_cups_strcasecmp(line, "Notice")) - { - if (!banner->notices) - banner->notices = cupsArrayNew(NULL, NULL); - - cupsArrayAdd(banner->notices, strdup(ptr)); - } - else if (!_cups_strcasecmp(line, "Show")) - { - char *value; /* Current value */ - - - for (value = ptr; *value; value = ptr) - { - /* - * Find the end of the current value - */ - - while (*ptr && !isspace(*ptr & 255)) - ptr ++; - - while (*ptr && isspace(*ptr & 255)) - *ptr++ = '\0'; - - /* - * Add the value to the show flags... - */ - if (!_cups_strcasecmp(value, "imageable-area")) - banner->show |= SHOW_IMAGEABLE_AREA; - else if (!_cups_strcasecmp(value, "job-billing")) - banner->show |= SHOW_JOB_BILLING; - else if (!_cups_strcasecmp(value, "job-id")) - banner->show |= SHOW_JOB_ID; - else if (!_cups_strcasecmp(value, "job-name")) - banner->show |= SHOW_JOB_NAME; - else if (!_cups_strcasecmp(value, "job-originating-host-name")) - banner->show |= SHOW_JOB_ORIGINATING_HOST_NAME; - else if (!_cups_strcasecmp(value, "job-originating-user-name")) - banner->show |= SHOW_JOB_ORIGINATING_USER_NAME; - else if (!_cups_strcasecmp(value, "job-uuid")) - banner->show |= SHOW_JOB_UUID; - else if (!_cups_strcasecmp(value, "options")) - banner->show |= SHOW_OPTIONS; - else if (!_cups_strcasecmp(value, "paper-name")) - banner->show |= SHOW_PAPER_NAME; - else if (!_cups_strcasecmp(value, "paper-size")) - banner->show |= SHOW_PAPER_SIZE; - else if (!_cups_strcasecmp(value, "printer-driver-name")) - banner->show |= SHOW_PRINTER_DRIVER_NAME; - else if (!_cups_strcasecmp(value, "printer-driver-version")) - banner->show |= SHOW_PRINTER_DRIVER_VERSION; - else if (!_cups_strcasecmp(value, "printer-info")) - banner->show |= SHOW_PRINTER_INFO; - else if (!_cups_strcasecmp(value, "printer-location")) - banner->show |= SHOW_PRINTER_LOCATION; - else if (!_cups_strcasecmp(value, "printer-make-and-model")) - banner->show |= SHOW_PRINTER_MAKE_AND_MODEL; - else if (!_cups_strcasecmp(value, "printer-name")) - banner->show |= SHOW_PRINTER_NAME; - else if (!_cups_strcasecmp(value, "time-at-creation")) - banner->show |= SHOW_TIME_AT_CREATION; - else if (!_cups_strcasecmp(value, "time-at-processing")) - banner->show |= SHOW_TIME_AT_PROCESSING; - else - { - fprintf(stderr, - "DEBUG: Unknown \"Show\" value \"%s\" on line %d of banner " - "file\n", value, linenum); - } - } - } - else - fprintf(stderr, "DEBUG: Unknown key \"%s\" on line %d of banner file\n", - line, linenum); - } - - if (filename) - cupsFileClose(fp); - - return (banner); -} - - -/* - * 'ps_ascii85()' - Print binary data as a series of base-85 numbers. - */ - -static void -ps_ascii85(cups_ib_t *data, /* I - Data to print */ - int length, /* I - Number of bytes to print */ - int last_line) /* I - Last line of raster data? */ -{ - unsigned b; /* Binary data word */ - unsigned char c[5]; /* ASCII85 encoded chars */ - static int col = 0; /* Current column */ - - - while (length > 3) - { - b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3]; - - if (b == 0) - { - putchar('z'); - col ++; - } - else - { - c[4] = (b % 85) + '!'; - b /= 85; - c[3] = (b % 85) + '!'; - b /= 85; - c[2] = (b % 85) + '!'; - b /= 85; - c[1] = (b % 85) + '!'; - b /= 85; - c[0] = b + '!'; - - fwrite(c, 5, 1, stdout); - col += 5; - } - - data += 4; - length -= 4; - - if (col >= 75) - { - putchar('\n'); - col = 0; - } - } - - if (last_line) - { - if (length > 0) - { - memset(data + length, 0, 4 - length); - b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3]; - - c[4] = (b % 85) + '!'; - b /= 85; - c[3] = (b % 85) + '!'; - b /= 85; - c[2] = (b % 85) + '!'; - b /= 85; - c[1] = (b % 85) + '!'; - b /= 85; - c[0] = b + '!'; - - fwrite(c, length + 1, 1, stdout); - } - - puts("~>"); - col = 0; - } -} - - -/* - * 'write_banner()' - Write a banner page... - */ - -static int /* O - Number of pages */ -write_banner(banner_file_t *banner, /* I - Banner file */ - ppd_file_t *ppd, /* I - PPD file */ - ps_text_t *fonts, /* I - Fonts */ - int job_id, /* I - Job ID */ - const char *title, /* I - Title of job */ - const char *username, /* I - Owner of job */ - int num_options, /* I - Number of options */ - cups_option_t *options) /* I - Options */ -{ - char *notice; /* Current notice */ - char *imagefile; /* Current image file */ - cups_array_t *images; /* Images */ - cups_image_t *image; /* Current image */ - const char *option; /* Option value */ - int i, j; /* Looping vars */ - float x, /* Current X position */ - y; /* Current Y position */ - cups_lang_t *language; /* Default language */ - int showlines; /* Number of lines to show */ - float fontsize; /* Font size to use */ - int num_pages; /* Number of pages */ - float print_width, /* Printable width of page */ - print_height, /* Printable height of page */ - info_top, /* Top of info fields */ - info_height, /* Height of info fields */ - line_height, /* Height of info lines */ - notices_height, /* Height of all notices */ - images_width, /* Width of all images */ - images_height, /* Height of all images */ - total_height; /* Height of all content */ - char text[1024]; /* Formatted field text */ - - - /* - * Figure out how many lines of text will be shown... - */ - - showlines = 0; - if (banner->show & SHOW_IMAGEABLE_AREA) - showlines += 2; - if (banner->show & SHOW_JOB_BILLING) - showlines ++; - if (banner->show & SHOW_JOB_ID) - showlines ++; - if (banner->show & SHOW_JOB_NAME) - showlines ++; - if (banner->show & SHOW_JOB_ORIGINATING_USER_NAME) - showlines ++; - if (banner->show & SHOW_JOB_ORIGINATING_HOST_NAME) - showlines ++; - if (banner->show & SHOW_JOB_UUID) - showlines ++; - if (banner->show & SHOW_OPTIONS) - { - for (j = 0; j < num_options; j ++) - { - if (_cups_strcasecmp("media", options[j].name) && - _cups_strcasecmp("PageSize", options[j].name) && - _cups_strcasecmp("PageRegion", options[j].name) && - _cups_strcasecmp("InputSlot", options[j].name) && - _cups_strcasecmp("MediaType", options[j].name) && - _cups_strcasecmp("finishings", options[j].name) && - _cups_strcasecmp("sides", options[j].name) && - _cups_strcasecmp("Duplex", options[j].name) && - _cups_strcasecmp("orientation-requested", options[j].name) && - _cups_strcasecmp("landscape", options[j].name) && - _cups_strcasecmp("number-up", options[j].name) && - _cups_strcasecmp("OutputOrder", options[j].name)) - continue; - - showlines ++; - } - } - if (banner->show & SHOW_PAPER_NAME) - showlines ++; - if (banner->show & SHOW_PAPER_SIZE) - showlines += 2; - if (banner->show & SHOW_PRINTER_DRIVER_NAME) - showlines ++; - if (banner->show & SHOW_PRINTER_DRIVER_VERSION) - showlines ++; - if (banner->show & SHOW_PRINTER_INFO) - showlines ++; - if (banner->show & SHOW_PRINTER_LOCATION) - showlines ++; - if (banner->show & SHOW_PRINTER_MAKE_AND_MODEL) - showlines ++; - if (banner->show & SHOW_PRINTER_NAME) - showlines ++; - if (banner->show & SHOW_TIME_AT_CREATION) - showlines ++; - if (banner->show & SHOW_TIME_AT_PROCESSING) - showlines ++; - - /* - * Figure out the dimensions and positions of everything... - */ - - print_width = PageRight - PageLeft; - print_height = PageTop - PageBottom; - fontsize = print_height / 60; /* Nominally 12pts */ - line_height = 1.2 * fontsize; - info_height = showlines * line_height; - notices_height = cupsArrayCount(banner->notices) * line_height; - - if (cupsArrayCount(banner->images)) - { - images = cupsArrayNew(NULL, NULL); - images_height = print_height / 10; /* Nominally 1" */ - - for (imagefile = (char *)cupsArrayFirst(banner->images), images_width = 0.0; - imagefile; - imagefile = (char *)cupsArrayNext(banner->images)) - { - if ((image = cupsImageOpen(imagefile, ColorDevice ? CUPS_IMAGE_RGB_CMYK : - CUPS_IMAGE_WHITE, - CUPS_IMAGE_WHITE, 100, 0, NULL)) == NULL) - { - fprintf(stderr, "DEBUG: Unable to open image file \"%s\"\n", - imagefile); - continue; - } - - images_width += cupsImageGetWidth(image) * images_height / - cupsImageGetHeight(image); - cupsArrayAdd(images, image); - } - } - else - { - images = NULL; - images_height = 0; - images_width = 0; - } - - total_height = info_height + notices_height + images_height; - if (cupsArrayCount(banner->notices) && showlines) - total_height += 2 * line_height; - if (cupsArrayCount(banner->images) && - (showlines || cupsArrayCount(banner->notices))) - total_height += 2 * line_height; - - info_top = 0.5 * (print_height + total_height); - - /* - * Write the page(s)... - */ - - language = cupsLangDefault(); - num_pages = Duplex ? 2 : 1; - - for (i = 1; i <= num_pages; i ++) - { - /* - * Start the page... - */ - - printf("%%%%Page: %s %d\n", i == 1 ? "coverpage" : "coverback", i); - puts("gsave"); - if (i == 1) - printf("%.1f %.1f translate\n", PageLeft, PageBottom); - else - printf("%.1f %.1f translate\n", PageWidth - PageRight, - PageLength - PageTop); - puts("0 setgray"); - - y = info_top; - - /* - * Information... - */ - - if (banner->show) - { - x = 0.33 * print_width; - - if (banner->show & SHOW_PRINTER_NAME) - { - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Printer Name: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, getenv("PRINTER")); - } - if (banner->show & SHOW_JOB_ID) - { - snprintf(text, sizeof(text), "%s-%d", getenv("PRINTER"), job_id); - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Job ID: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); - } - if (banner->show & SHOW_JOB_UUID) - { - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Job UUID: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, - cupsGetOption("job-uuid", num_options, options)); - } - if (banner->show & SHOW_JOB_NAME) - { - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Title: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, title); - } - if (banner->show & SHOW_JOB_ORIGINATING_USER_NAME) - { - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Printed For: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, username); - } - if (banner->show & SHOW_JOB_ORIGINATING_HOST_NAME) - { - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Printed From: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, - cupsGetOption("job-originating-host-name", num_options, - options)); - } - if (banner->show & SHOW_JOB_BILLING) - { - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Billing Information: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, - cupsGetOption("job-billing", num_options, options)); - } - if (banner->show & SHOW_OPTIONS) - { - printf("%.1f %.1f moveto", x, y); - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Options: "))); - - for (j = 0; j < num_options; j ++) - { - if (_cups_strcasecmp("media", options[j].name) && - _cups_strcasecmp("PageSize", options[j].name) && - _cups_strcasecmp("PageRegion", options[j].name) && - _cups_strcasecmp("InputSlot", options[j].name) && - _cups_strcasecmp("MediaType", options[j].name) && - _cups_strcasecmp("finishings", options[j].name) && - _cups_strcasecmp("sides", options[j].name) && - _cups_strcasecmp("Duplex", options[j].name) && - _cups_strcasecmp("orientation-requested", options[j].name) && - _cups_strcasecmp("landscape", options[j].name) && - _cups_strcasecmp("number-up", options[j].name) && - _cups_strcasecmp("OutputOrder", options[j].name)) - continue; - - if (!_cups_strcasecmp("landscape", options[j].name)) - strlcpy(text, "orientation-requested=landscape", sizeof(text)); - else if (!_cups_strcasecmp("orientation-requested", options[j].name)) - { - switch (atoi(options[j].value)) - { - default : - case IPP_PORTRAIT : - strlcpy(text, "orientation-requested=portrait", - sizeof(text)); - break; - - case IPP_LANDSCAPE : - strlcpy(text, "orientation-requested=landscape", - sizeof(text)); - break; - - case IPP_REVERSE_PORTRAIT : - strlcpy(text, "orientation-requested=reverse-portrait", - sizeof(text)); - break; - - case IPP_REVERSE_LANDSCAPE : - strlcpy(text, "orientation-requested=reverse-landscape", - sizeof(text)); - break; - } - } - else - snprintf(text, sizeof(text), "%s=%s", options[j].name, - options[j].value); - - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); - } - } - - if (banner->show & SHOW_PRINTER_INFO) - { - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Description: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, - getenv("PRINTER_INFO")); - } - if (banner->show & SHOW_PRINTER_LOCATION) - { - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Location: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, - getenv("PRINTER_LOCATION")); - } - if (banner->show & SHOW_PRINTER_MAKE_AND_MODEL) - { - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Make and Model: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, - ppd ? ppd->nickname : NULL); - } - - if (banner->show & SHOW_PAPER_NAME) - { - if ((option = cupsGetOption("media", num_options, options)) == NULL) - if ((option = cupsGetOption("PageSize", num_options, options)) == NULL) - if ((option = cupsGetOption("PageRegion", num_options, - options)) == NULL) - option = "Default"; - - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Media Name: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, option); - } - if (banner->show & SHOW_PAPER_SIZE) - { - snprintf(text, sizeof(text), - _cupsLangString(language, _("%.2f x %.2f inches")), - PageWidth / 72.0, PageLength / 72.0); - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Media Dimensions: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); - - snprintf(text, sizeof(text), - _cupsLangString(language, _("%.0f x %.0f millimeters")), - PageWidth * 25.4 / 72.0, PageLength * 25.4 / 72.0); - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); - } - if (banner->show & SHOW_IMAGEABLE_AREA) - { - snprintf(text, sizeof(text), - _cupsLangString(language, - _("%.2f x %.2f to %.2f x %.2f inches")), - PageLeft / 72.0, PageBottom / 72.0, - PageRight / 72.0, PageTop / 72.0); - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Media Limits: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); - - snprintf(text, sizeof(text), - _cupsLangString(language, - _("%.0f x %.0f to %.0f x %.0f millimeters")), - PageLeft * 25.4 / 72.0, PageBottom * 25.4 / 72.0, - PageRight * 25.4 / 72.0, PageTop * 25.4 / 72.0); - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); - - printf("gsave 2 setlinewidth 1 1 %.1f %.1f rectstroke grestore\n", - print_width - 2.0, print_height - 2.0); - } - if (banner->show & SHOW_PRINTER_DRIVER_NAME) - { - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Driver Name: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, - ppd ? ppd->pcfilename : NULL); - } - if (banner->show & SHOW_PRINTER_DRIVER_VERSION) - { - ppd_attr_t *file_version = ppdFindAttr(ppd, "FileVersion", NULL); - - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Driver Version: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, - file_version ? file_version->value : NULL); - } - if (banner->show & SHOW_TIME_AT_CREATION) - { - if ((option = cupsGetOption("time-at-creation", num_options, - options)) != NULL) - { - time_t curtime; /* Current time */ - struct tm *curdate; /* Current date */ - - curtime = (time_t)atoi(option); - curdate = localtime(&curtime); - - strftime(text, sizeof(text), "%c", curdate); - } - else - strlcpy(text, "?", sizeof(text)); - - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Created On: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); - } - if (banner->show & SHOW_TIME_AT_PROCESSING) - { - if ((option = cupsGetOption("time-at-processing", num_options, - options)) != NULL) - { - time_t curtime; /* Current time */ - struct tm *curdate; /* Current date */ - - curtime = (time_t)atoi(option); - curdate = localtime(&curtime); - - strftime(text, sizeof(text), "%c", curdate); - } - else - strlcpy(text, "?", sizeof(text)); - - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, - _cupsLangString(language, _("Printed On: "))); - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); - } - } - - /* - * Notices... - */ - - if (cupsArrayCount(banner->notices)) - { - if (banner->show) - y -= 2 * line_height; - - x = 0.5 * print_width; - - for (notice = (char *)cupsArrayFirst(banner->notices); - notice; - notice = (char *)cupsArrayNext(banner->notices)) - { - printf("%.1f %.1f moveto", x, y); - y -= line_height; - psTextUTF8(fonts, fontsize, PS_NORMAL, PS_CENTER, notice); - } - } - - /* - * Images... - */ - - if (cupsArrayCount(images)) - { - if (banner->show || cupsArrayCount(banner->notices)) - y -= 2 * line_height; - - x = 0.5 * (print_width - images_width); - - for (image = (cups_image_t *)cupsArrayFirst(images); - image; - image = (cups_image_t *)cupsArrayNext(images)) - { - float temp_width; /* Width of this image */ - int depth, /* Bytes per pixel */ - num_cols, /* Number of columns */ - row, /* Current row */ - num_rows, /* Number of rows */ - out_length, /* Length of data to write */ - out_offset; /* Offset in line buffer */ - unsigned char *line; /* Data for current row */ - - - depth = cupsImageGetDepth(image); - num_cols = cupsImageGetWidth(image); - num_rows = cupsImageGetHeight(image); - line = malloc(depth * num_cols + 3); - temp_width = num_cols * images_height / num_rows; - - printf("gsave %.1f %.1f translate %.3f %.3f scale\n", x, y, - temp_width / num_cols, images_height / num_rows); - x += temp_width; - - switch (cupsImageGetColorSpace(image)) - { - default : - case CUPS_IMAGE_WHITE : - printf("/DeviceGray setcolorspace" - "<<" - "/ImageType 1" - "/Width %d" - "/Height %d" - "/BitsPerComponent 8" - "/Decode[0 1]\n", - num_cols, num_rows); - break; - - case CUPS_IMAGE_RGB : - printf("/DeviceRGB setcolorspace" - "<<" - "/ImageType 1" - "/Width %d" - "/Height %d" - "/BitsPerComponent 8" - "/Decode[0 1 0 1 0 1]\n", - num_cols, num_rows); - break; - - case CUPS_IMAGE_CMYK : - printf("/DeviceCMYK setcolorspace" - "<<" - "/ImageType 1" - "/Width %d" - "/Height %d" - "/BitsPerComponent 8" - "/Decode[0 1 0 1 0 1 0 1]\n", - num_cols, num_rows); - break; - } - - puts("/DataSource currentfile" - "/ASCII85Decode filter" - "/ImageMatrix[1 0 0 -1 0 1]>>image"); - - for (row = 0, out_offset = 0; row < num_rows; row ++) - { - cupsImageGetRow(image, 0, row, num_cols, line + out_offset); - - out_length = num_cols * depth + out_offset; - out_offset = out_length & 3; - - ps_ascii85(line, out_length, row == (num_rows - 1)); - - if (out_offset > 0) - memcpy(line, line + out_length - out_offset, out_offset); - } - - puts("grestore"); - - if (i == num_pages) - cupsImageClose(image); - - free(line); - } - } - - /* - * Header and footer... - */ - - x = 0.5 * print_width; - - if (banner->header) - { - printf("%.1f %.1f moveto", x, print_height - 2 * fontsize); - psTextUTF8(fonts, 2 * fontsize, PS_BOLD, PS_CENTER, banner->header); - } - - if (banner->footer) - { - printf("%.1f %.1f moveto", x, fontsize); - psTextUTF8(fonts, 2 * fontsize, PS_BOLD, PS_CENTER, banner->footer); - } - - /* - * Show the page... - */ - - puts("grestore"); - puts("showpage"); - } - - return (num_pages); -} - - -/* - * 'write_epilogue()' - Write the PostScript file epilogue. - */ - -static void -write_epilogue(int num_pages) /* I - Number of pages */ -{ - puts("%%Trailer"); - printf("%%%%Pages: %d\n", num_pages); - puts("%%EOF"); -} - - -/* - * 'write_prolog()' - Write the PostScript file prolog with options. - */ - -ps_text_t * /* O - Fonts */ -write_prolog(const char *title, /* I - Title of job */ - const char *username) /* I - Username */ -{ - time_t curtime; /* Current time */ - struct tm *curtm; /* Current date */ - char curdate[255]; /* Current date (text format) */ - ps_text_t *fonts; /* Fonts */ - - - /* - * Get the fonts we'll need... - */ - - fonts = psTextInitialize(); - - /* - * Output the DSC header... - */ - - curtime = time(NULL); - curtm = localtime(&curtime); - strftime(curdate, sizeof(curdate), "%c", curtm); - - puts("%!PS-Adobe-3.0"); - printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", PageLeft, PageBottom, - PageRight, PageTop); - printf("%%cupsRotation: %d\n", (Orientation & 3) * 90); - puts("%%Creator: bannertops/" CUPS_SVERSION); - printf("%%%%CreationDate: %s\n", curdate); - puts("%%LanguageLevel: 2"); - puts("%%DocumentData: Clean7Bit"); - WriteTextComment("Title", title); - WriteTextComment("For", username); - printf("%%%%Pages: %d\n", Duplex ? 2 : 1); - psTextListFonts(fonts); - puts("%%EndComments"); - puts("%%BeginProlog"); - psTextEmbedFonts(fonts); - puts("%%EndProlog"); - - return (fonts); -} - - -/* - * End of "$Id$". - */ diff --git a/filter/error.c b/filter/error.c index 8a00964a8..a73186926 100644 --- a/filter/error.c +++ b/filter/error.c @@ -28,8 +28,7 @@ * Include necessary headers... */ -#include "image-private.h" -#include +#include /* diff --git a/filter/image-bmp.c b/filter/image-bmp.c deleted file mode 100644 index b93c1c500..000000000 --- a/filter/image-bmp.c +++ /dev/null @@ -1,545 +0,0 @@ -/* - * "$Id: image-bmp.c 7221 2008-01-16 22:20:08Z mike $" - * - * BMP image routines for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * _cupsImageReadBMP() - Read a BMP image file. - * read_word() - Read a 16-bit unsigned integer. - * read_dword() - Read a 32-bit unsigned integer. - * read_long() - Read a 32-bit signed integer. - */ - -/* - * Include necessary headers... - */ - -#include "image-private.h" - - -/* - * Constants for the bitmap compression... - */ - -# define BI_RGB 0 /* No compression - straight BGR data */ -# define BI_RLE8 1 /* 8-bit run-length compression */ -# define BI_RLE4 2 /* 4-bit run-length compression */ -# define BI_BITFIELDS 3 /* RGB bitmap with RGB masks */ - - -/* - * Local functions... - */ - -static unsigned short read_word(FILE *fp); -static unsigned int read_dword(FILE *fp); -static int read_long(FILE *fp); - - -/* - * '_cupsImageReadBMP()' - Read a BMP image file. - */ - -int /* O - Read status */ -_cupsImageReadBMP( - cups_image_t *img, /* IO - cupsImage */ - FILE *fp, /* I - cupsImage file */ - cups_icspace_t primary, /* I - Primary choice for colorspace */ - cups_icspace_t secondary, /* I - Secondary choice for colorspace */ - int saturation, /* I - Color saturation (%) */ - int hue, /* I - Color hue (degrees) */ - const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */ -{ - int offset, /* Offset to bitmap data */ - info_size, /* Size of info header */ - planes, /* Number of planes (always 1) */ - depth, /* Depth of image (bits) */ - compression, /* Type of compression */ - image_size, /* Size of image in bytes */ - colors_used, /* Number of colors used */ - colors_important, /* Number of important colors */ - bpp, /* Bytes per pixel */ - x, y, /* Looping vars */ - color, /* Color of RLE pixel */ - count, /* Number of times to repeat */ - temp, /* Temporary color */ - align; /* Alignment bytes */ - cups_ib_t bit, /* Bit in image */ - byte; /* Byte in image */ - cups_ib_t *in, /* Input pixels */ - *out, /* Output pixels */ - *ptr; /* Pointer into pixels */ - cups_ib_t colormap[256][4]; /* Colormap */ - - - (void)secondary; - - /* - * Get the header... - */ - - getc(fp); /* Skip "BM" sync chars */ - getc(fp); - read_dword(fp); /* Skip size */ - read_word(fp); /* Skip reserved stuff */ - read_word(fp); - offset = read_dword(fp); - - fprintf(stderr, "DEBUG: offset = %d\n", offset); - - if (offset < 0) - { - fprintf(stderr, "DEBUG: Bad BMP offset %d\n", offset); - fclose(fp); - return (1); - } - - /* - * Then the bitmap information... - */ - - info_size = read_dword(fp); - img->xsize = read_long(fp); - img->ysize = read_long(fp); - planes = read_word(fp); - depth = read_word(fp); - compression = read_dword(fp); - image_size = read_dword(fp); - img->xppi = read_long(fp) * 0.0254 + 0.5; - img->yppi = read_long(fp) * 0.0254 + 0.5; - colors_used = read_dword(fp); - colors_important = read_dword(fp); - - if (img->xsize == 0 || img->xsize > CUPS_IMAGE_MAX_WIDTH || - img->ysize == 0 || img->ysize > CUPS_IMAGE_MAX_HEIGHT || - (depth != 1 && depth != 4 && depth != 8 && depth != 24)) - { - fprintf(stderr, "DEBUG: Bad BMP dimensions %ux%ux%d\n", - img->xsize, img->ysize, depth); - fclose(fp); - return (1); - } - - if (colors_used < 0 || colors_used > 256) - { - fprintf(stderr, "DEBUG: Bad BMP colormap size %d\n", colors_used); - fclose(fp); - return (1); - } - - if (img->xppi == 0 || img->yppi == 0) - { - fprintf(stderr, "DEBUG: Bad BMP resolution %dx%d PPI.\n", - img->xppi, img->yppi); - img->xppi = img->yppi = 128; - } - - /* - * Make sure the resolution info is valid... - */ - - fprintf(stderr, "info_size = %d, xsize = %d, ysize = %d, planes = %d, depth = %d\n", - info_size, img->xsize, img->ysize, planes, depth); - fprintf(stderr, "compression = %d, image_size = %d, xppi = %d, yppi = %d\n", - compression, image_size, img->xppi, img->yppi); - fprintf(stderr, "colors_used = %d, colors_important = %d\n", colors_used, - colors_important); - - if (info_size > 40) - for (info_size -= 40; info_size > 0; info_size --) - getc(fp); - - /* - * Get colormap... - */ - - if (colors_used == 0 && depth <= 8) - colors_used = 1 << depth; - - if (colors_used > 0) - fread(colormap, colors_used, 4, fp); - else - memset(colormap, 0, sizeof(colormap)); - - /* - * Setup image and buffers... - */ - - img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary; - - cupsImageSetMaxTiles(img, 0); - - bpp = cupsImageGetDepth(img); - - if ((in = malloc(img->xsize * 3)) == NULL) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - fclose(fp); - return (1); - } - - if ((out = malloc(img->xsize * bpp)) == NULL) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - free(in); - fclose(fp); - return (1); - } - - /* - * Read the image data... - */ - - color = 0; - count = 0; - align = 0; - - for (y = img->ysize - 1; y >= 0; y --) - { - ptr = in; - - switch (depth) - { - case 1 : /* Bitmap */ - for (x = img->xsize, bit = 128, byte = 0; x > 0; x --) - { - if (bit == 128) - byte = getc(fp); - - if (byte & bit) - { - *ptr++ = colormap[1][2]; - *ptr++ = colormap[1][1]; - *ptr++ = colormap[1][0]; - } - else - { - *ptr++ = colormap[0][2]; - *ptr++ = colormap[0][1]; - *ptr++ = colormap[0][0]; - } - - if (bit > 1) - bit >>= 1; - else - bit = 128; - } - - /* - * Read remaining bytes to align to 32 bits... - */ - - for (temp = (img->xsize + 7) / 8; temp & 3; temp ++) - getc(fp); - break; - - case 4 : /* 16-color */ - for (x = img->xsize, bit = 0xf0, temp = 0; x > 0; x --) - { - /* - * Get a new count as needed... - */ - - if (compression != BI_RLE4 && count == 0) - { - count = 2; - color = -1; - } - - if (count == 0) - { - while (align > 0) - { - align --; - getc(fp); - } - - if ((count = getc(fp)) == 0) - { - if ((count = getc(fp)) == 0) - { - /* - * End of line... - */ - - x ++; - continue; - } - else if (count == 1) - { - /* - * End of image... - */ - - break; - } - else if (count == 2) - { - /* - * Delta... - */ - - count = getc(fp) * getc(fp) * img->xsize; - color = 0; - } - else - { - /* - * Absolute... - */ - - color = -1; - align = ((4 - (count & 3)) / 2) & 1; - } - } - else - color = getc(fp); - } - - /* - * Get a new color as needed... - */ - - count --; - - if (bit == 0xf0) - { - if (color < 0) - temp = getc(fp); - else - temp = color; - - /* - * Copy the color value... - */ - - *ptr++ = colormap[temp >> 4][2]; - *ptr++ = colormap[temp >> 4][1]; - *ptr++ = colormap[temp >> 4][0]; - bit = 0x0f; - } - else - { - /* - * Copy the color value... - */ - - *ptr++ = colormap[temp & 15][2]; - *ptr++ = colormap[temp & 15][1]; - *ptr++ = colormap[temp & 15][0]; - bit = 0xf0; - } - } - break; - - case 8 : /* 256-color */ - for (x = img->xsize; x > 0; x --) - { - /* - * Get a new count as needed... - */ - - if (compression != BI_RLE8) - { - count = 1; - color = -1; - } - - if (count == 0) - { - while (align > 0) - { - align --; - getc(fp); - } - - if ((count = getc(fp)) == 0) - { - if ((count = getc(fp)) == 0) - { - /* - * End of line... - */ - - x ++; - continue; - } - else if (count == 1) - { - /* - * End of image... - */ - - break; - } - else if (count == 2) - { - /* - * Delta... - */ - - count = getc(fp) * getc(fp) * img->xsize; - color = 0; - } - else - { - /* - * Absolute... - */ - - color = -1; - align = (2 - (count & 1)) & 1; - } - } - else - color = getc(fp); - } - - /* - * Get a new color as needed... - */ - - if (color < 0) - temp = getc(fp); - else - temp = color; - - count --; - - /* - * Copy the color value... - */ - - *ptr++ = colormap[temp][2]; - *ptr++ = colormap[temp][1]; - *ptr++ = colormap[temp][0]; - } - break; - - case 24 : /* 24-bit RGB */ - for (x = img->xsize; x > 0; x --, ptr += 3) - { - ptr[2] = getc(fp); - ptr[1] = getc(fp); - ptr[0] = getc(fp); - } - - /* - * Read remaining bytes to align to 32 bits... - */ - - for (temp = img->xsize * 3; temp & 3; temp ++) - getc(fp); - break; - } - - if (saturation != 100 || hue != 0) - cupsImageRGBAdjust(in, img->xsize, saturation, hue); - - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_WHITE : - cupsImageRGBToWhite(in, out, img->xsize); - break; - - case CUPS_IMAGE_RGB : - cupsImageRGBToRGB(in, out, img->xsize); - break; - - case CUPS_IMAGE_BLACK : - cupsImageRGBToBlack(in, out, img->xsize); - break; - - case CUPS_IMAGE_CMY : - cupsImageRGBToCMY(in, out, img->xsize); - break; - - case CUPS_IMAGE_CMYK : - cupsImageRGBToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * bpp, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, out); - } - - fclose(fp); - free(in); - free(out); - - return (0); -} - - -/* - * 'read_word()' - Read a 16-bit unsigned integer. - */ - -static unsigned short /* O - 16-bit unsigned integer */ -read_word(FILE *fp) /* I - File to read from */ -{ - unsigned char b0, b1; /* Bytes from file */ - - b0 = getc(fp); - b1 = getc(fp); - - return ((b1 << 8) | b0); -} - - -/* - * 'read_dword()' - Read a 32-bit unsigned integer. - */ - -static unsigned int /* O - 32-bit unsigned integer */ -read_dword(FILE *fp) /* I - File to read from */ -{ - unsigned char b0, b1, b2, b3; /* Bytes from file */ - - b0 = getc(fp); - b1 = getc(fp); - b2 = getc(fp); - b3 = getc(fp); - - return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0); -} - - -/* - * 'read_long()' - Read a 32-bit signed integer. - */ - -static int /* O - 32-bit signed integer */ -read_long(FILE *fp) /* I - File to read from */ -{ - unsigned char b0, b1, b2, b3; /* Bytes from file */ - - b0 = getc(fp); - b1 = getc(fp); - b2 = getc(fp); - b3 = getc(fp); - - return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0); -} - - -/* - * End of "$Id: image-bmp.c 7221 2008-01-16 22:20:08Z mike $". - */ diff --git a/filter/image-colorspace.c b/filter/image-colorspace.c deleted file mode 100644 index 8c25568d5..000000000 --- a/filter/image-colorspace.c +++ /dev/null @@ -1,1567 +0,0 @@ -/* - * "$Id: image-colorspace.c 7720 2008-07-11 22:46:21Z mike $" - * - * Colorspace conversions for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2006 by Easy Software Products. - * - * The color saturation/hue matrix stuff is provided thanks to Mr. Paul - * Haeberli at "http://www.sgi.com/grafica/matrix/index.html". - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * cupsImageCMYKToBlack() - Convert CMYK data to black. - * cupsImageCMYKToCMY() - Convert CMYK colors to CMY. - * cupsImageCMYKToCMYK() - Convert CMYK colors to CMYK. - * cupsImageCMYKToRGB() - Convert CMYK colors to device-dependent - * RGB. - * cupsImageCMYKToWhite() - Convert CMYK colors to luminance. - * cupsImageLut() - Adjust all pixel values with the given - * LUT. - * cupsImageRGBAdjust() - Adjust the hue and saturation of the - * given RGB colors. - * cupsImageRGBToBlack() - Convert RGB data to black. - * cupsImageRGBToCMY() - Convert RGB colors to CMY. - * cupsImageRGBToCMYK() - Convert RGB colors to CMYK. - * cupsImageRGBToRGB() - Convert RGB colors to device-dependent - * RGB. - * cupsImageRGBToWhite() - Convert RGB colors to luminance. - * cupsImageSetProfile() - Set the device color profile. - * cupsImageSetRasterColorSpace() - Set the destination colorspace. - * cupsImageWhiteToBlack() - Convert luminance colors to black. - * cupsImageWhiteToCMY() - Convert luminance colors to CMY. - * cupsImageWhiteToCMYK() - Convert luminance colors to CMYK. - * cupsImageWhiteToRGB() - Convert luminance data to RGB. - * cupsImageWhiteToWhite() - Convert luminance colors to device- - * dependent luminance. - * cielab() - Map CIE Lab transformation... - * huerotate() - Rotate the hue, maintaining luminance. - * ident() - Make an identity matrix. - * mult() - Multiply two matrices. - * rgb_to_lab() - Convert an RGB color to CIE Lab. - * rgb_to_xyz() - Convert an RGB color to CIE XYZ. - * saturate() - Make a saturation matrix. - * xform() - Transform a 3D point using a matrix... - * xrotate() - Rotate about the x (red) axis... - * yrotate() - Rotate about the y (green) axis... - * zrotate() - Rotate about the z (blue) axis... - * zshear() - Shear z using x and y... - */ - -/* - * Include necessary headers... - */ - -#include "image-private.h" - - -/* - * Define some math constants that are required... - */ - -#ifndef M_PI -# define M_PI 3.14159265358979323846 -#endif /* !M_PI */ - -#ifndef M_SQRT2 -# define M_SQRT2 1.41421356237309504880 -#endif /* !M_SQRT2 */ - -#ifndef M_SQRT1_2 -# define M_SQRT1_2 0.70710678118654752440 -#endif /* !M_SQRT1_2 */ - -/* - * CIE XYZ whitepoint... - */ - -#define D65_X (0.412453 + 0.357580 + 0.180423) -#define D65_Y (0.212671 + 0.715160 + 0.072169) -#define D65_Z (0.019334 + 0.119193 + 0.950227) - - -/* - * Lookup table structure... - */ - -typedef int cups_clut_t[3][256]; - - -/* - * Local globals... - */ - -static int cupsImageHaveProfile = 0; - /* Do we have a color profile? */ -static int *cupsImageDensity; - /* Ink/marker density LUT */ -static cups_clut_t *cupsImageMatrix; - /* Color transform matrix LUT */ -static cups_cspace_t cupsImageColorSpace = CUPS_CSPACE_RGB; - /* Destination colorspace */ - - -/* - * Local functions... - */ - -static float cielab(float x, float xn); -static void huerotate(float [3][3], float); -static void ident(float [3][3]); -static void mult(float [3][3], float [3][3], float [3][3]); -static void rgb_to_lab(cups_ib_t *val); -static void rgb_to_xyz(cups_ib_t *val); -static void saturate(float [3][3], float); -static void xform(float [3][3], float, float, float, float *, float *, float *); -static void xrotate(float [3][3], float, float); -static void yrotate(float [3][3], float, float); -static void zrotate(float [3][3], float, float); -static void zshear(float [3][3], float, float); - - -/* - * 'cupsImageCMYKToBlack()' - Convert CMYK data to black. - */ - -void -cupsImageCMYKToBlack( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - int k; /* Black value */ - - - if (cupsImageHaveProfile) - while (count > 0) - { - k = (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100 + in[3]; - - if (k < 255) - *out++ = cupsImageDensity[k]; - else - *out++ = cupsImageDensity[255]; - - in += 4; - count --; - } - else - while (count > 0) - { - k = (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100 + in[3]; - - if (k < 255) - *out++ = k; - else - *out++ = 255; - - in += 4; - count --; - } -} - - -/* - * 'cupsImageCMYKToCMY()' - Convert CMYK colors to CMY. - */ - -void -cupsImageCMYKToCMY( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - int c, m, y, k; /* CMYK values */ - int cc, cm, cy; /* Calibrated CMY values */ - - - if (cupsImageHaveProfile) - while (count > 0) - { - c = *in++; - m = *in++; - y = *in++; - k = *in++; - - cc = cupsImageMatrix[0][0][c] + - cupsImageMatrix[0][1][m] + - cupsImageMatrix[0][2][y] + k; - cm = cupsImageMatrix[1][0][c] + - cupsImageMatrix[1][1][m] + - cupsImageMatrix[1][2][y] + k; - cy = cupsImageMatrix[2][0][c] + - cupsImageMatrix[2][1][m] + - cupsImageMatrix[2][2][y] + k; - - if (cc < 0) - *out++ = 0; - else if (cc > 255) - *out++ = cupsImageDensity[255]; - else - *out++ = cupsImageDensity[cc]; - - if (cm < 0) - *out++ = 0; - else if (cm > 255) - *out++ = cupsImageDensity[255]; - else - *out++ = cupsImageDensity[cm]; - - if (cy < 0) - *out++ = 0; - else if (cy > 255) - *out++ = cupsImageDensity[255]; - else - *out++ = cupsImageDensity[cy]; - - count --; - } - else - while (count > 0) - { - c = *in++; - m = *in++; - y = *in++; - k = *in++; - - c += k; - m += k; - y += k; - - if (c < 255) - *out++ = c; - else - *out++ = 255; - - if (m < 255) - *out++ = y; - else - *out++ = 255; - - if (y < 255) - *out++ = y; - else - *out++ = 255; - - count --; - } -} - - -/* - * 'cupsImageCMYKToCMYK()' - Convert CMYK colors to CMYK. - */ - -void -cupsImageCMYKToCMYK( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - int c, m, y, k; /* CMYK values */ - int cc, cm, cy; /* Calibrated CMY values */ - - - if (cupsImageHaveProfile) - while (count > 0) - { - c = *in++; - m = *in++; - y = *in++; - k = *in++; - - cc = (cupsImageMatrix[0][0][c] + - cupsImageMatrix[0][1][m] + - cupsImageMatrix[0][2][y]); - cm = (cupsImageMatrix[1][0][c] + - cupsImageMatrix[1][1][m] + - cupsImageMatrix[1][2][y]); - cy = (cupsImageMatrix[2][0][c] + - cupsImageMatrix[2][1][m] + - cupsImageMatrix[2][2][y]); - - if (cc < 0) - *out++ = 0; - else if (cc > 255) - *out++ = cupsImageDensity[255]; - else - *out++ = cupsImageDensity[cc]; - - if (cm < 0) - *out++ = 0; - else if (cm > 255) - *out++ = cupsImageDensity[255]; - else - *out++ = cupsImageDensity[cm]; - - if (cy < 0) - *out++ = 0; - else if (cy > 255) - *out++ = cupsImageDensity[255]; - else - *out++ = cupsImageDensity[cy]; - - *out++ = cupsImageDensity[k]; - - count --; - } - else if (in != out) - { - while (count > 0) - { - *out++ = *in++; - *out++ = *in++; - *out++ = *in++; - *out++ = *in++; - - count --; - } - } -} - - -/* - * 'cupsImageCMYKToRGB()' - Convert CMYK colors to device-dependent RGB. - */ - -void -cupsImageCMYKToRGB( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - int c, m, y, k; /* CMYK values */ - int cr, cg, cb; /* Calibrated RGB values */ - - - if (cupsImageHaveProfile) - { - while (count > 0) - { - c = *in++; - m = *in++; - y = *in++; - k = *in++; - - cr = cupsImageMatrix[0][0][c] + - cupsImageMatrix[0][1][m] + - cupsImageMatrix[0][2][y] + k; - cg = cupsImageMatrix[1][0][c] + - cupsImageMatrix[1][1][m] + - cupsImageMatrix[1][2][y] + k; - cb = cupsImageMatrix[2][0][c] + - cupsImageMatrix[2][1][m] + - cupsImageMatrix[2][2][y] + k; - - if (cr < 0) - *out++ = 255; - else if (cr > 255) - *out++ = 255 - cupsImageDensity[255]; - else - *out++ = 255 - cupsImageDensity[cr]; - - if (cg < 0) - *out++ = 255; - else if (cg > 255) - *out++ = 255 - cupsImageDensity[255]; - else - *out++ = 255 - cupsImageDensity[cg]; - - if (cb < 0) - *out++ = 255; - else if (cb > 255) - *out++ = 255 - cupsImageDensity[255]; - else - *out++ = 255 - cupsImageDensity[cb]; - - count --; - } - } - else - { - while (count > 0) - { - c = 255 - *in++; - m = 255 - *in++; - y = 255 - *in++; - k = *in++; - - c -= k; - m -= k; - y -= k; - - if (c > 0) - *out++ = c; - else - *out++ = 0; - - if (m > 0) - *out++ = m; - else - *out++ = 0; - - if (y > 0) - *out++ = y; - else - *out++ = 0; - - if (cupsImageColorSpace == CUPS_CSPACE_CIELab || - cupsImageColorSpace >= CUPS_CSPACE_ICC1) - rgb_to_lab(out - 3); - else if (cupsImageColorSpace == CUPS_CSPACE_CIEXYZ) - rgb_to_xyz(out - 3); - - count --; - } - } -} - - -/* - * 'cupsImageCMYKToWhite()' - Convert CMYK colors to luminance. - */ - -void -cupsImageCMYKToWhite( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - int w; /* White value */ - - - if (cupsImageHaveProfile) - { - while (count > 0) - { - w = 255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100 - in[3]; - - if (w > 0) - *out++ = cupsImageDensity[w]; - else - *out++ = cupsImageDensity[0]; - - in += 4; - count --; - } - } - else - { - while (count > 0) - { - w = 255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100 - in[3]; - - if (w > 0) - *out++ = w; - else - *out++ = 0; - - in += 4; - count --; - } - } -} - - -/* - * 'cupsImageLut()' - Adjust all pixel values with the given LUT. - */ - -void -cupsImageLut(cups_ib_t *pixels, /* IO - Input/output pixels */ - int count, /* I - Number of pixels/bytes to adjust */ - const cups_ib_t *lut) /* I - Lookup table */ -{ - while (count > 0) - { - *pixels = lut[*pixels]; - pixels ++; - count --; - } -} - - -/* - * 'cupsImageRGBAdjust()' - Adjust the hue and saturation of the given RGB colors. - */ - -void -cupsImageRGBAdjust(cups_ib_t *pixels, /* IO - Input/output pixels */ - int count, /* I - Number of pixels to adjust */ - int saturation,/* I - Color saturation (%) */ - int hue) /* I - Color hue (degrees) */ -{ - int i, j, k; /* Looping vars */ - float mat[3][3]; /* Color adjustment matrix */ - static int last_sat = 100, /* Last saturation used */ - last_hue = 0; /* Last hue used */ - static cups_clut_t *lut = NULL; /* Lookup table for matrix */ - - - if (saturation != last_sat || hue != last_hue || !lut) - { - /* - * Build the color adjustment matrix... - */ - - ident(mat); - saturate(mat, saturation * 0.01); - huerotate(mat, (float)hue); - - /* - * Allocate memory for the lookup table... - */ - - if (lut == NULL) - lut = calloc(3, sizeof(cups_clut_t)); - - if (lut == NULL) - return; - - /* - * Convert the matrix into a 3x3 array of lookup tables... - */ - - for (i = 0; i < 3; i ++) - for (j = 0; j < 3; j ++) - for (k = 0; k < 256; k ++) - lut[i][j][k] = mat[i][j] * k + 0.5; - - /* - * Save the saturation and hue to compare later... - */ - - last_sat = saturation; - last_hue = hue; - } - - /* - * Adjust each pixel in the given buffer. - */ - - while (count > 0) - { - i = lut[0][0][pixels[0]] + - lut[1][0][pixels[1]] + - lut[2][0][pixels[2]]; - if (i < 0) - pixels[0] = 0; - else if (i > 255) - pixels[0] = 255; - else - pixels[0] = i; - - i = lut[0][1][pixels[0]] + - lut[1][1][pixels[1]] + - lut[2][1][pixels[2]]; - if (i < 0) - pixels[1] = 0; - else if (i > 255) - pixels[1] = 255; - else - pixels[1] = i; - - i = lut[0][2][pixels[0]] + - lut[1][2][pixels[1]] + - lut[2][2][pixels[2]]; - if (i < 0) - pixels[2] = 0; - else if (i > 255) - pixels[2] = 255; - else - pixels[2] = i; - - count --; - pixels += 3; - } -} - - -/* - * 'cupsImageRGBToBlack()' - Convert RGB data to black. - */ - -void -cupsImageRGBToBlack( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - if (cupsImageHaveProfile) - while (count > 0) - { - *out++ = cupsImageDensity[255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100]; - in += 3; - count --; - } - else - while (count > 0) - { - *out++ = 255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100; - in += 3; - count --; - } -} - - -/* - * 'cupsImageRGBToCMY()' - Convert RGB colors to CMY. - */ - -void -cupsImageRGBToCMY( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - int c, m, y, k; /* CMYK values */ - int cc, cm, cy; /* Calibrated CMY values */ - - - if (cupsImageHaveProfile) - while (count > 0) - { - c = 255 - *in++; - m = 255 - *in++; - y = 255 - *in++; - k = min(c, min(m, y)); - c -= k; - m -= k; - y -= k; - - cc = cupsImageMatrix[0][0][c] + - cupsImageMatrix[0][1][m] + - cupsImageMatrix[0][2][y] + k; - cm = cupsImageMatrix[1][0][c] + - cupsImageMatrix[1][1][m] + - cupsImageMatrix[1][2][y] + k; - cy = cupsImageMatrix[2][0][c] + - cupsImageMatrix[2][1][m] + - cupsImageMatrix[2][2][y] + k; - - if (cc < 0) - *out++ = 0; - else if (cc > 255) - *out++ = cupsImageDensity[255]; - else - *out++ = cupsImageDensity[cc]; - - if (cm < 0) - *out++ = 0; - else if (cm > 255) - *out++ = cupsImageDensity[255]; - else - *out++ = cupsImageDensity[cm]; - - if (cy < 0) - *out++ = 0; - else if (cy > 255) - *out++ = cupsImageDensity[255]; - else - *out++ = cupsImageDensity[cy]; - - count --; - } - else - while (count > 0) - { - c = 255 - in[0]; - m = 255 - in[1]; - y = 255 - in[2]; - k = min(c, min(m, y)); - - *out++ = (255 - in[1] / 4) * (c - k) / 255 + k; - *out++ = (255 - in[2] / 4) * (m - k) / 255 + k; - *out++ = (255 - in[0] / 4) * (y - k) / 255 + k; - in += 3; - count --; - } -} - - -/* - * 'cupsImageRGBToCMYK()' - Convert RGB colors to CMYK. - */ - -void -cupsImageRGBToCMYK( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - int c, m, y, k, /* CMYK values */ - km; /* Maximum K value */ - int cc, cm, cy; /* Calibrated CMY values */ - - - if (cupsImageHaveProfile) - while (count > 0) - { - c = 255 - *in++; - m = 255 - *in++; - y = 255 - *in++; - k = min(c, min(m, y)); - - if ((km = max(c, max(m, y))) > k) - k = k * k * k / (km * km); - - c -= k; - m -= k; - y -= k; - - cc = (cupsImageMatrix[0][0][c] + - cupsImageMatrix[0][1][m] + - cupsImageMatrix[0][2][y]); - cm = (cupsImageMatrix[1][0][c] + - cupsImageMatrix[1][1][m] + - cupsImageMatrix[1][2][y]); - cy = (cupsImageMatrix[2][0][c] + - cupsImageMatrix[2][1][m] + - cupsImageMatrix[2][2][y]); - - if (cc < 0) - *out++ = 0; - else if (cc > 255) - *out++ = cupsImageDensity[255]; - else - *out++ = cupsImageDensity[cc]; - - if (cm < 0) - *out++ = 0; - else if (cm > 255) - *out++ = cupsImageDensity[255]; - else - *out++ = cupsImageDensity[cm]; - - if (cy < 0) - *out++ = 0; - else if (cy > 255) - *out++ = cupsImageDensity[255]; - else - *out++ = cupsImageDensity[cy]; - - *out++ = cupsImageDensity[k]; - - count --; - } - else - while (count > 0) - { - c = 255 - *in++; - m = 255 - *in++; - y = 255 - *in++; - k = min(c, min(m, y)); - - if ((km = max(c, max(m, y))) > k) - k = k * k * k / (km * km); - - c -= k; - m -= k; - y -= k; - - *out++ = c; - *out++ = m; - *out++ = y; - *out++ = k; - - count --; - } -} - - -/* - * 'cupsImageRGBToRGB()' - Convert RGB colors to device-dependent RGB. - */ - -void -cupsImageRGBToRGB( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - int c, m, y, k; /* CMYK values */ - int cr, cg, cb; /* Calibrated RGB values */ - - - if (cupsImageHaveProfile) - { - while (count > 0) - { - c = 255 - *in++; - m = 255 - *in++; - y = 255 - *in++; - k = min(c, min(m, y)); - c -= k; - m -= k; - y -= k; - - cr = cupsImageMatrix[0][0][c] + - cupsImageMatrix[0][1][m] + - cupsImageMatrix[0][2][y] + k; - cg = cupsImageMatrix[1][0][c] + - cupsImageMatrix[1][1][m] + - cupsImageMatrix[1][2][y] + k; - cb = cupsImageMatrix[2][0][c] + - cupsImageMatrix[2][1][m] + - cupsImageMatrix[2][2][y] + k; - - if (cr < 0) - *out++ = 255; - else if (cr > 255) - *out++ = 255 - cupsImageDensity[255]; - else - *out++ = 255 - cupsImageDensity[cr]; - - if (cg < 0) - *out++ = 255; - else if (cg > 255) - *out++ = 255 - cupsImageDensity[255]; - else - *out++ = 255 - cupsImageDensity[cg]; - - if (cb < 0) - *out++ = 255; - else if (cb > 255) - *out++ = 255 - cupsImageDensity[255]; - else - *out++ = 255 - cupsImageDensity[cb]; - - count --; - } - } - else - { - if (in != out) - memcpy(out, in, count * 3); - - if (cupsImageColorSpace == CUPS_CSPACE_CIELab || - cupsImageColorSpace >= CUPS_CSPACE_ICC1) - { - while (count > 0) - { - rgb_to_lab(out); - - out += 3; - count --; - } - } - else if (cupsImageColorSpace == CUPS_CSPACE_CIEXYZ) - { - while (count > 0) - { - rgb_to_xyz(out); - - out += 3; - count --; - } - } - } -} - - -/* - * 'cupsImageRGBToWhite()' - Convert RGB colors to luminance. - */ - -void -cupsImageRGBToWhite( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - if (cupsImageHaveProfile) - { - while (count > 0) - { - *out++ = 255 - cupsImageDensity[255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100]; - in += 3; - count --; - } - } - else - { - while (count > 0) - { - *out++ = (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100; - in += 3; - count --; - } - } -} - - -/* - * 'cupsImageSetProfile()' - Set the device color profile. - */ - -void -cupsImageSetProfile(float d, /* I - Ink/marker density */ - float g, /* I - Ink/marker gamma */ - float matrix[3][3]) /* I - Color transform matrix */ -{ - int i, j, k; /* Looping vars */ - float m; /* Current matrix value */ - int *im; /* Pointer into cupsImageMatrix */ - - - /* - * Allocate memory for the profile data... - */ - - if (cupsImageMatrix == NULL) - cupsImageMatrix = calloc(3, sizeof(cups_clut_t)); - - if (cupsImageMatrix == NULL) - return; - - if (cupsImageDensity == NULL) - cupsImageDensity = calloc(256, sizeof(int)); - - if (cupsImageDensity == NULL) - return; - - /* - * Populate the profile lookup tables... - */ - - cupsImageHaveProfile = 1; - - for (i = 0, im = cupsImageMatrix[0][0]; i < 3; i ++) - for (j = 0; j < 3; j ++) - for (k = 0, m = matrix[i][j]; k < 256; k ++) - *im++ = (int)(k * m + 0.5); - - for (k = 0, im = cupsImageDensity; k < 256; k ++) - *im++ = 255.0 * d * pow((float)k / 255.0, g) + 0.5; -} - - -/* - * 'cupsImageSetRasterColorSpace()' - Set the destination colorspace. - */ - -void -cupsImageSetRasterColorSpace( - cups_cspace_t cs) /* I - Destination colorspace */ -{ - /* - * Set the destination colorspace... - */ - - cupsImageColorSpace = cs; - - /* - * Don't use color profiles in colorimetric colorspaces... - */ - - if (cs == CUPS_CSPACE_CIEXYZ || - cs == CUPS_CSPACE_CIELab || - cs >= CUPS_CSPACE_ICC1) - cupsImageHaveProfile = 0; -} - - -/* - * 'cupsImageWhiteToBlack()' - Convert luminance colors to black. - */ - -void -cupsImageWhiteToBlack( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - if (cupsImageHaveProfile) - while (count > 0) - { - *out++ = cupsImageDensity[255 - *in++]; - count --; - } - else - while (count > 0) - { - *out++ = 255 - *in++; - count --; - } -} - - -/* - * 'cupsImageWhiteToCMY()' - Convert luminance colors to CMY. - */ - -void -cupsImageWhiteToCMY( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - if (cupsImageHaveProfile) - while (count > 0) - { - out[0] = cupsImageDensity[255 - *in++]; - out[1] = out[0]; - out[2] = out[0]; - out += 3; - count --; - } - else - while (count > 0) - { - *out++ = 255 - *in; - *out++ = 255 - *in; - *out++ = 255 - *in++; - count --; - } -} - - -/* - * 'cupsImageWhiteToCMYK()' - Convert luminance colors to CMYK. - */ - -void -cupsImageWhiteToCMYK( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - if (cupsImageHaveProfile) - while (count > 0) - { - *out++ = 0; - *out++ = 0; - *out++ = 0; - *out++ = cupsImageDensity[255 - *in++]; - count --; - } - else - while (count > 0) - { - *out++ = 0; - *out++ = 0; - *out++ = 0; - *out++ = 255 - *in++; - count --; - } -} - - -/* - * 'cupsImageWhiteToRGB()' - Convert luminance data to RGB. - */ - -void -cupsImageWhiteToRGB( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - if (cupsImageHaveProfile) - { - while (count > 0) - { - out[0] = 255 - cupsImageDensity[255 - *in++]; - out[1] = out[0]; - out[2] = out[0]; - out += 3; - count --; - } - } - else - { - while (count > 0) - { - *out++ = *in; - *out++ = *in; - *out++ = *in++; - - if (cupsImageColorSpace == CUPS_CSPACE_CIELab || - cupsImageColorSpace >= CUPS_CSPACE_ICC1) - rgb_to_lab(out - 3); - else if (cupsImageColorSpace == CUPS_CSPACE_CIEXYZ) - rgb_to_xyz(out - 3); - - count --; - } - } -} - - -/* - * 'cupsImageWhiteToWhite()' - Convert luminance colors to device-dependent - * luminance. - */ - -void -cupsImageWhiteToWhite( - const cups_ib_t *in, /* I - Input pixels */ - cups_ib_t *out, /* I - Output pixels */ - int count) /* I - Number of pixels */ -{ - if (cupsImageHaveProfile) - while (count > 0) - { - *out++ = 255 - cupsImageDensity[255 - *in++]; - count --; - } - else if (in != out) - memcpy(out, in, count); -} - - -/* - * 'cielab()' - Map CIE Lab transformation... - */ - -static float /* O - Adjusted color value */ -cielab(float x, /* I - Raw color value */ - float xn) /* I - Whitepoint color value */ -{ - float x_xn; /* Fraction of whitepoint */ - - - x_xn = x / xn; - - if (x_xn > 0.008856) - return (cbrt(x_xn)); - else - return (7.787 * x_xn + 16.0 / 116.0); -} - - -/* - * 'huerotate()' - Rotate the hue, maintaining luminance. - */ - -static void -huerotate(float mat[3][3], /* I - Matrix to append to */ - float rot) /* I - Hue rotation in degrees */ -{ - float hmat[3][3]; /* Hue matrix */ - float lx, ly, lz; /* Luminance vector */ - float xrs, xrc; /* X rotation sine/cosine */ - float yrs, yrc; /* Y rotation sine/cosine */ - float zrs, zrc; /* Z rotation sine/cosine */ - float zsx, zsy; /* Z shear x/y */ - - - /* - * Load the identity matrix... - */ - - ident(hmat); - - /* - * Rotate the grey vector into positive Z... - */ - - xrs = M_SQRT1_2; - xrc = M_SQRT1_2; - xrotate(hmat,xrs,xrc); - - yrs = -1.0 / sqrt(3.0); - yrc = -M_SQRT2 * yrs; - yrotate(hmat,yrs,yrc); - - /* - * Shear the space to make the luminance plane horizontal... - */ - - xform(hmat, 0.3086, 0.6094, 0.0820, &lx, &ly, &lz); - zsx = lx / lz; - zsy = ly / lz; - zshear(hmat, zsx, zsy); - - /* - * Rotate the hue... - */ - - zrs = sin(rot * M_PI / 180.0); - zrc = cos(rot * M_PI / 180.0); - - zrotate(hmat, zrs, zrc); - - /* - * Unshear the space to put the luminance plane back... - */ - - zshear(hmat, -zsx, -zsy); - - /* - * Rotate the grey vector back into place... - */ - - yrotate(hmat, -yrs, yrc); - xrotate(hmat, -xrs, xrc); - - /* - * Append it to the current matrix... - */ - - mult(hmat, mat, mat); -} - - -/* - * 'ident()' - Make an identity matrix. - */ - -static void -ident(float mat[3][3]) /* I - Matrix to identify */ -{ - mat[0][0] = 1.0; - mat[0][1] = 0.0; - mat[0][2] = 0.0; - mat[1][0] = 0.0; - mat[1][1] = 1.0; - mat[1][2] = 0.0; - mat[2][0] = 0.0; - mat[2][1] = 0.0; - mat[2][2] = 1.0; -} - - -/* - * 'mult()' - Multiply two matrices. - */ - -static void -mult(float a[3][3], /* I - First matrix */ - float b[3][3], /* I - Second matrix */ - float c[3][3]) /* I - Destination matrix */ -{ - int x, y; /* Looping vars */ - float temp[3][3]; /* Temporary matrix */ - - - /* - * Multiply a and b, putting the result in temp... - */ - - for (y = 0; y < 3; y ++) - for (x = 0; x < 3; x ++) - temp[y][x] = b[y][0] * a[0][x] + - b[y][1] * a[1][x] + - b[y][2] * a[2][x]; - - /* - * Copy temp to c (that way c can be a pointer to a or b). - */ - - memcpy(c, temp, sizeof(temp)); -} - - -/* - * 'rgb_to_lab()' - Convert an RGB color to CIE Lab. - */ - -static void -rgb_to_lab(cups_ib_t *val) /* IO - Color value */ -{ - float r, /* Red value */ - g, /* Green value */ - b, /* Blue value */ - ciex, /* CIE X value */ - ciey, /* CIE Y value */ - ciez, /* CIE Z value */ - ciey_yn, /* Normalized luminance */ - ciel, /* CIE L value */ - ciea, /* CIE a value */ - cieb; /* CIE b value */ - - - /* - * Convert sRGB to linear RGB... - */ - - r = pow((val[0] / 255.0 + 0.055) / 1.055, 2.4); - g = pow((val[1] / 255.0 + 0.055) / 1.055, 2.4); - b = pow((val[2] / 255.0 + 0.055) / 1.055, 2.4); - - /* - * Convert to CIE XYZ... - */ - - ciex = 0.412453 * r + 0.357580 * g + 0.180423 * b; - ciey = 0.212671 * r + 0.715160 * g + 0.072169 * b; - ciez = 0.019334 * r + 0.119193 * g + 0.950227 * b; - - /* - * Normalize and convert to CIE Lab... - */ - - ciey_yn = ciey / D65_Y; - - if (ciey_yn > 0.008856) - ciel = 116 * cbrt(ciey_yn) - 16; - else - ciel = 903.3 * ciey_yn; - -/*ciel = ciel;*/ - ciea = 500 * (cielab(ciex, D65_X) - cielab(ciey, D65_Y)); - cieb = 200 * (cielab(ciey, D65_Y) - cielab(ciez, D65_Z)); - - /* - * Scale the L value and bias the a and b values by 128 so that all - * numbers are from 0 to 255. - */ - - ciel = ciel * 2.55 + 0.5; - ciea += 128.5; - cieb += 128.5; - - /* - * Output 8-bit values... - */ - - if (ciel < 0.0) - val[0] = 0; - else if (ciel < 255.0) - val[0] = (int)ciel; - else - val[0] = 255; - - if (ciea < 0.0) - val[1] = 0; - else if (ciea < 255.0) - val[1] = (int)ciea; - else - val[1] = 255; - - if (cieb < 0.0) - val[2] = 0; - else if (cieb < 255.0) - val[2] = (int)cieb; - else - val[2] = 255; -} - - -/* - * 'rgb_to_xyz()' - Convert an RGB color to CIE XYZ. - */ - -static void -rgb_to_xyz(cups_ib_t *val) /* IO - Color value */ -{ - float r, /* Red value */ - g, /* Green value */ - b, /* Blue value */ - ciex, /* CIE X value */ - ciey, /* CIE Y value */ - ciez; /* CIE Z value */ - - - /* - * Convert sRGB to linear RGB... - */ - - r = pow((val[0] / 255.0 + 0.055) / 1.055, 2.4); - g = pow((val[1] / 255.0 + 0.055) / 1.055, 2.4); - b = pow((val[2] / 255.0 + 0.055) / 1.055, 2.4); - - /* - * Convert to CIE XYZ... - */ - - ciex = 0.412453 * r + 0.357580 * g + 0.180423 * b; - ciey = 0.212671 * r + 0.715160 * g + 0.072169 * b; - ciez = 0.019334 * r + 0.119193 * g + 0.950227 * b; - - /* - * Encode as 8-bit XYZ... - */ - - if (ciex < 0.0f) - val[0] = 0; - else if (ciex < 1.1f) - val[0] = (int)(231.8181f * ciex + 0.5); - else - val[0] = 255; - - if (ciey < 0.0f) - val[1] = 0; - else if (ciey < 1.1f) - val[1] = (int)(231.8181f * ciey + 0.5); - else - val[1] = 255; - - if (ciez < 0.0f) - val[2] = 0; - else if (ciez < 1.1f) - val[2] = (int)(231.8181f * ciez + 0.5); - else - val[2] = 255; -} - - -/* - * 'saturate()' - Make a saturation matrix. - */ - -static void -saturate(float mat[3][3], /* I - Matrix to append to */ - float sat) /* I - Desired color saturation */ -{ - float smat[3][3]; /* Saturation matrix */ - - - smat[0][0] = (1.0 - sat) * 0.3086 + sat; - smat[0][1] = (1.0 - sat) * 0.3086; - smat[0][2] = (1.0 - sat) * 0.3086; - smat[1][0] = (1.0 - sat) * 0.6094; - smat[1][1] = (1.0 - sat) * 0.6094 + sat; - smat[1][2] = (1.0 - sat) * 0.6094; - smat[2][0] = (1.0 - sat) * 0.0820; - smat[2][1] = (1.0 - sat) * 0.0820; - smat[2][2] = (1.0 - sat) * 0.0820 + sat; - - mult(smat, mat, mat); -} - - -/* - * 'xform()' - Transform a 3D point using a matrix... - */ - -static void -xform(float mat[3][3], /* I - Matrix */ - float x, /* I - Input X coordinate */ - float y, /* I - Input Y coordinate */ - float z, /* I - Input Z coordinate */ - float *tx, /* O - Output X coordinate */ - float *ty, /* O - Output Y coordinate */ - float *tz) /* O - Output Z coordinate */ -{ - *tx = x * mat[0][0] + y * mat[1][0] + z * mat[2][0]; - *ty = x * mat[0][1] + y * mat[1][1] + z * mat[2][1]; - *tz = x * mat[0][2] + y * mat[1][2] + z * mat[2][2]; -} - - -/* - * 'xrotate()' - Rotate about the x (red) axis... - */ - -static void -xrotate(float mat[3][3], /* I - Matrix */ - float rs, /* I - Rotation angle sine */ - float rc) /* I - Rotation angle cosine */ -{ - float rmat[3][3]; /* I - Rotation matrix */ - - - rmat[0][0] = 1.0; - rmat[0][1] = 0.0; - rmat[0][2] = 0.0; - - rmat[1][0] = 0.0; - rmat[1][1] = rc; - rmat[1][2] = rs; - - rmat[2][0] = 0.0; - rmat[2][1] = -rs; - rmat[2][2] = rc; - - mult(rmat, mat, mat); -} - - -/* - * 'yrotate()' - Rotate about the y (green) axis... - */ - -static void -yrotate(float mat[3][3], /* I - Matrix */ - float rs, /* I - Rotation angle sine */ - float rc) /* I - Rotation angle cosine */ -{ - float rmat[3][3]; /* I - Rotation matrix */ - - - rmat[0][0] = rc; - rmat[0][1] = 0.0; - rmat[0][2] = -rs; - - rmat[1][0] = 0.0; - rmat[1][1] = 1.0; - rmat[1][2] = 0.0; - - rmat[2][0] = rs; - rmat[2][1] = 0.0; - rmat[2][2] = rc; - - mult(rmat,mat,mat); -} - - -/* - * 'zrotate()' - Rotate about the z (blue) axis... - */ - -static void -zrotate(float mat[3][3], /* I - Matrix */ - float rs, /* I - Rotation angle sine */ - float rc) /* I - Rotation angle cosine */ -{ - float rmat[3][3]; /* I - Rotation matrix */ - - - rmat[0][0] = rc; - rmat[0][1] = rs; - rmat[0][2] = 0.0; - - rmat[1][0] = -rs; - rmat[1][1] = rc; - rmat[1][2] = 0.0; - - rmat[2][0] = 0.0; - rmat[2][1] = 0.0; - rmat[2][2] = 1.0; - - mult(rmat,mat,mat); -} - - -/* - * 'zshear()' - Shear z using x and y... - */ - -static void -zshear(float mat[3][3], /* I - Matrix */ - float dx, /* I - X shear */ - float dy) /* I - Y shear */ -{ - float smat[3][3]; /* Shear matrix */ - - - smat[0][0] = 1.0; - smat[0][1] = 0.0; - smat[0][2] = dx; - - smat[1][0] = 0.0; - smat[1][1] = 1.0; - smat[1][2] = dy; - - smat[2][0] = 0.0; - smat[2][1] = 0.0; - smat[2][2] = 1.0; - - mult(smat, mat, mat); -} - - -/* - * End of "$Id: image-colorspace.c 7720 2008-07-11 22:46:21Z mike $". - */ diff --git a/filter/image-gif.c b/filter/image-gif.c deleted file mode 100644 index c082c089f..000000000 --- a/filter/image-gif.c +++ /dev/null @@ -1,696 +0,0 @@ -/* - * "$Id: image-gif.c 7720 2008-07-11 22:46:21Z mike $" - * - * GIF image routines for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * _cupsImageReadGIF() - Read a GIF image file. - * gif_get_block() - Read a GIF data block... - * gif_get_code() - Get a LZW code from the file... - * gif_read_cmap() - Read the colormap from a GIF file... - * gif_read_image() - Read a GIF image stream... - * gif_read_lzw() - Read a byte from the LZW stream... - */ - -/* - * Include necessary headers... - */ - -#include "image-private.h" - - -/* - * GIF definitions... - */ - -#define GIF_INTERLACE 0x40 -#define GIF_COLORMAP 0x80 -#define GIF_MAX_BITS 12 - -typedef cups_ib_t gif_cmap_t[256][4]; -typedef short gif_table_t[4096]; - - -/* - * Local globals... - */ - -static int gif_eof = 0; /* Did we hit EOF? */ - - -/* - * Local functions... - */ - -static int gif_get_block(FILE *fp, unsigned char *buffer); -static int gif_get_code (FILE *fp, int code_size, int first_time); -static int gif_read_cmap(FILE *fp, int ncolors, gif_cmap_t cmap, - int *gray); -static int gif_read_image(FILE *fp, cups_image_t *img, gif_cmap_t cmap, - int interlace); -static int gif_read_lzw(FILE *fp, int first_time, int input_code_size); - - -/* - * '_cupsImageReadGIF()' - Read a GIF image file. - */ - -int /* O - Read status */ -_cupsImageReadGIF( - cups_image_t *img, /* IO - cupsImage */ - FILE *fp, /* I - cupsImage file */ - cups_icspace_t primary, /* I - Primary choice for colorspace */ - cups_icspace_t secondary, /* I - Secondary choice for colorspace */ - int saturation, /* I - Color saturation (%) */ - int hue, /* I - Color hue (degrees) */ - const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */ -{ - unsigned char buf[1024]; /* Input buffer */ - gif_cmap_t cmap; /* Colormap */ - int i, /* Looping var */ - bpp, /* Bytes per pixel */ - gray, /* Grayscale image? */ - ncolors, /* Bits per pixel */ - transparent; /* Transparent color index */ - - - /* - * GIF files are either grayscale or RGB - no CMYK... - */ - - if (primary == CUPS_IMAGE_RGB_CMYK) - primary = CUPS_IMAGE_RGB; - - /* - * Read the header; we already know it is a GIF file... - */ - - fread(buf, 13, 1, fp); - - img->xsize = (buf[7] << 8) | buf[6]; - img->ysize = (buf[9] << 8) | buf[8]; - ncolors = 2 << (buf[10] & 0x07); - gray = primary == CUPS_IMAGE_BLACK || primary == CUPS_IMAGE_WHITE; - - if (buf[10] & GIF_COLORMAP) - if (gif_read_cmap(fp, ncolors, cmap, &gray)) - { - fclose(fp); - return (-1); - } - - transparent = -1; - - for (;;) - { - switch (getc(fp)) - { - case ';' : /* End of image */ - fclose(fp); - return (-1); /* Early end of file */ - - case '!' : /* Extension record */ - buf[0] = getc(fp); - if (buf[0] == 0xf9) /* Graphic Control Extension */ - { - gif_get_block(fp, buf); - if (buf[0] & 1) /* Get transparent color index */ - transparent = buf[3]; - } - - while (gif_get_block(fp, buf) != 0); - break; - - case ',' : /* cupsImage data */ - fread(buf, 9, 1, fp); - - if (buf[8] & GIF_COLORMAP) - { - ncolors = 2 << (buf[8] & 0x07); - gray = primary == CUPS_IMAGE_BLACK || primary == CUPS_IMAGE_WHITE; - - if (gif_read_cmap(fp, ncolors, cmap, &gray)) - { - fclose(fp); - return (-1); - } - } - - if (transparent >= 0) - { - /* - * Make transparent color white... - */ - - cmap[transparent][0] = 255; - cmap[transparent][1] = 255; - cmap[transparent][2] = 255; - } - - if (gray) - { - switch (secondary) - { - case CUPS_IMAGE_CMYK : - for (i = ncolors - 1; i >= 0; i --) - cupsImageWhiteToCMYK(cmap[i], cmap[i], 1); - break; - case CUPS_IMAGE_CMY : - for (i = ncolors - 1; i >= 0; i --) - cupsImageWhiteToCMY(cmap[i], cmap[i], 1); - break; - case CUPS_IMAGE_BLACK : - for (i = ncolors - 1; i >= 0; i --) - cupsImageWhiteToBlack(cmap[i], cmap[i], 1); - break; - case CUPS_IMAGE_WHITE : - break; - case CUPS_IMAGE_RGB : - case CUPS_IMAGE_RGB_CMYK : - for (i = ncolors - 1; i >= 0; i --) - cupsImageWhiteToRGB(cmap[i], cmap[i], 1); - break; - } - - img->colorspace = secondary; - } - else - { - if (hue != 0 || saturation != 100) - for (i = ncolors - 1; i >= 0; i --) - cupsImageRGBAdjust(cmap[i], 1, saturation, hue); - - switch (primary) - { - case CUPS_IMAGE_CMYK : - for (i = ncolors - 1; i >= 0; i --) - cupsImageRGBToCMYK(cmap[i], cmap[i], 1); - break; - case CUPS_IMAGE_CMY : - for (i = ncolors - 1; i >= 0; i --) - cupsImageRGBToCMY(cmap[i], cmap[i], 1); - break; - case CUPS_IMAGE_BLACK : - for (i = ncolors - 1; i >= 0; i --) - cupsImageRGBToBlack(cmap[i], cmap[i], 1); - break; - case CUPS_IMAGE_WHITE : - for (i = ncolors - 1; i >= 0; i --) - cupsImageRGBToWhite(cmap[i], cmap[i], 1); - break; - case CUPS_IMAGE_RGB : - case CUPS_IMAGE_RGB_CMYK : - for (i = ncolors - 1; i >= 0; i --) - cupsImageRGBToRGB(cmap[i], cmap[i], 1); - break; - } - - img->colorspace = primary; - } - - if (lut) - { - bpp = cupsImageGetDepth(img); - - for (i = ncolors - 1; i >= 0; i --) - cupsImageLut(cmap[i], bpp, lut); - } - - img->xsize = (buf[5] << 8) | buf[4]; - img->ysize = (buf[7] << 8) | buf[6]; - - /* - * Check the dimensions of the image; since the dimensions are - * a 16-bit integer we just need to check for 0... - */ - - if (img->xsize == 0 || img->ysize == 0) - { - fprintf(stderr, "DEBUG: Bad GIF image dimensions: %dx%d\n", - img->xsize, img->ysize); - fclose(fp); - return (1); - } - - i = gif_read_image(fp, img, cmap, buf[8] & GIF_INTERLACE); - fclose(fp); - return (i); - } - } -} - - -/* - * 'gif_get_block()' - Read a GIF data block... - */ - -static int /* O - Number characters read */ -gif_get_block(FILE *fp, /* I - File to read from */ - unsigned char *buf) /* I - Input buffer */ -{ - int count; /* Number of character to read */ - - - /* - * Read the count byte followed by the data from the file... - */ - - if ((count = getc(fp)) == EOF) - { - gif_eof = 1; - return (-1); - } - else if (count == 0) - gif_eof = 1; - else if (fread(buf, 1, count, fp) < count) - { - gif_eof = 1; - return (-1); - } - else - gif_eof = 0; - - return (count); -} - - -/* - * 'gif_get_code()' - Get a LZW code from the file... - */ - -static int /* O - LZW code */ -gif_get_code(FILE *fp, /* I - File to read from */ - int code_size, /* I - Size of code in bits */ - int first_time) /* I - 1 = first time, 0 = not first time */ -{ - unsigned i, j, /* Looping vars */ - ret; /* Return value */ - int count; /* Number of bytes read */ - static unsigned char buf[280]; /* Input buffer */ - static unsigned curbit, /* Current bit */ - lastbit, /* Last bit in buffer */ - done, /* Done with this buffer? */ - last_byte; /* Last byte in buffer */ - static const unsigned char bits[8] = /* Bit masks for codes */ - { - 0x01, 0x02, 0x04, 0x08, - 0x10, 0x20, 0x40, 0x80 - }; - - - if (first_time) - { - /* - * Just initialize the input buffer... - */ - - curbit = 0; - lastbit = 0; - last_byte = 0; - done = 0; - - return (0); - } - - if ((curbit + code_size) >= lastbit) - { - /* - * Don't have enough bits to hold the code... - */ - - if (done) - return (-1); /* Sorry, no more... */ - - /* - * Move last two bytes to front of buffer... - */ - - if (last_byte > 1) - { - buf[0] = buf[last_byte - 2]; - buf[1] = buf[last_byte - 1]; - last_byte = 2; - } - else if (last_byte == 1) - { - buf[0] = buf[last_byte - 1]; - last_byte = 1; - } - - /* - * Read in another buffer... - */ - - if ((count = gif_get_block(fp, buf + last_byte)) <= 0) - { - /* - * Whoops, no more data! - */ - - done = 1; - return (-1); - } - - /* - * Update buffer state... - */ - - curbit = (curbit - lastbit) + 8 * last_byte; - last_byte += count; - lastbit = last_byte * 8; - } - - for (ret = 0, i = curbit + code_size - 1, j = code_size; - j > 0; - i --, j --) - ret = (ret << 1) | ((buf[i / 8] & bits[i & 7]) != 0); - - curbit += code_size; - - return ret; -} - - -/* - * 'gif_read_cmap()' - Read the colormap from a GIF file... - */ - -static int /* O - -1 on error, 0 on success */ -gif_read_cmap(FILE *fp, /* I - File to read from */ - int ncolors, /* I - Number of colors in file */ - gif_cmap_t cmap, /* O - Colormap information */ - int *gray) /* IO - Is the image grayscale? */ -{ - int i; /* Looping var */ - - - /* - * Read the colormap... - */ - - for (i = 0; i < ncolors; i ++) - if (fread(cmap[i], 3, 1, fp) < 1) - return (-1); - - /* - * Check to see if the colormap is a grayscale ramp... - */ - - for (i = 0; i < ncolors; i ++) - if (cmap[i][0] != cmap[i][1] || cmap[i][1] != cmap[i][2]) - break; - - if (i == ncolors) - { - *gray = 1; - return (0); - } - - /* - * If this needs to be a grayscale image, convert the RGB values to - * luminance values... - */ - - if (*gray) - for (i = 0; i < ncolors; i ++) - cmap[i][0] = (cmap[i][0] * 31 + cmap[i][1] * 61 + cmap[i][2] * 8) / 100; - - return (0); -} - - -/* - * 'gif_read_image()' - Read a GIF image stream... - */ - -static int /* I - 0 = success, -1 = failure */ -gif_read_image(FILE *fp, /* I - Input file */ - cups_image_t *img, /* I - cupsImage pointer */ - gif_cmap_t cmap, /* I - Colormap */ - int interlace) /* I - Non-zero = interlaced image */ -{ - unsigned char code_size; /* Code size */ - cups_ib_t *pixels, /* Pixel buffer */ - *temp; /* Current pixel */ - int xpos, /* Current X position */ - ypos, /* Current Y position */ - pass; /* Current pass */ - int pixel; /* Current pixel */ - int bpp; /* Bytes per pixel */ - static const int xpasses[4] = /* X interleaving */ - { 8, 8, 4, 2 }, - ypasses[5] = /* Y interleaving */ - { 0, 4, 2, 1, 999999 }; - - - bpp = cupsImageGetDepth(img); - pixels = calloc(bpp, img->xsize); - xpos = 0; - ypos = 0; - pass = 0; - code_size = getc(fp); - - if (!pixels) - return (-1); - - if (code_size > GIF_MAX_BITS || gif_read_lzw(fp, 1, code_size) < 0) - { - free(pixels); - return (-1); - } - - temp = pixels; - while ((pixel = gif_read_lzw(fp, 0, code_size)) >= 0) - { - switch (bpp) - { - case 4 : - temp[3] = cmap[pixel][3]; - case 3 : - temp[2] = cmap[pixel][2]; - case 2 : - temp[1] = cmap[pixel][1]; - default : - temp[0] = cmap[pixel][0]; - } - - xpos ++; - temp += bpp; - if (xpos == img->xsize) - { - _cupsImagePutRow(img, 0, ypos, img->xsize, pixels); - - xpos = 0; - temp = pixels; - - if (interlace) - { - ypos += xpasses[pass]; - - if (ypos >= img->ysize) - { - pass ++; - - ypos = ypasses[pass]; - } - } - else - ypos ++; - } - - if (ypos >= img->ysize) - break; - } - - free(pixels); - - return (0); -} - - -/* - * 'gif_read_lzw()' - Read a byte from the LZW stream... - */ - -static int /* I - Byte from stream */ -gif_read_lzw(FILE *fp, /* I - File to read from */ - int first_time, /* I - 1 = first time, 0 = not first time */ - int input_code_size) /* I - Code size in bits */ -{ - int i, /* Looping var */ - code, /* Current code */ - incode; /* Input code */ - static short fresh = 0, /* 1 = empty buffers */ - code_size, /* Current code size */ - set_code_size, /* Initial code size set */ - max_code, /* Maximum code used */ - max_code_size, /* Maximum code size */ - firstcode, /* First code read */ - oldcode, /* Last code read */ - clear_code, /* Clear code for LZW input */ - end_code, /* End code for LZW input */ - *stack = NULL, /* Output stack */ - *sp; /* Current stack pointer */ - static gif_table_t *table = NULL; /* String table */ - - - if (first_time) - { - /* - * Setup LZW state... - */ - - set_code_size = input_code_size; - code_size = set_code_size + 1; - clear_code = 1 << set_code_size; - end_code = clear_code + 1; - max_code_size = 2 * clear_code; - max_code = clear_code + 2; - - /* - * Allocate memory for buffers... - */ - - if (table == NULL) - table = calloc(2, sizeof(gif_table_t)); - - if (table == NULL) - return (-1); - - if (stack == NULL) - stack = calloc(8192, sizeof(short)); - - if (stack == NULL) - return (-1); - - /* - * Initialize input buffers... - */ - - gif_get_code(fp, 0, 1); - - /* - * Wipe the decompressor table (already mostly 0 due to the calloc above...) - */ - - fresh = 1; - - for (i = 1; i < clear_code; i ++) - table[1][i] = i; - - sp = stack; - - return (0); - } - else if (fresh) - { - fresh = 0; - - do - { - firstcode = oldcode = gif_get_code(fp, code_size, 0); - } - while (firstcode == clear_code); - - return (firstcode & 255); - } - else if (!table) - return (0); - - if (sp > stack) - return ((*--sp) & 255); - - while ((code = gif_get_code(fp, code_size, 0)) >= 0) - { - if (code == clear_code) - { - /* - * Clear/reset the compression table... - */ - - memset(table, 0, 2 * sizeof(gif_table_t)); - for (i = 1; i < clear_code; i ++) - table[1][i] = i; - - code_size = set_code_size + 1; - max_code_size = 2 * clear_code; - max_code = clear_code + 2; - - sp = stack; - - firstcode = oldcode = gif_get_code(fp, code_size, 0); - - return (firstcode & 255); - } - else if (code == end_code || code > max_code) - { - unsigned char buf[260]; /* Block buffer */ - - if (!gif_eof) - while (gif_get_block(fp, buf) > 0); - - return (-2); - } - - incode = code; - - if (code == max_code) - { - if (sp < (stack + 8192)) - *sp++ = firstcode; - - code = oldcode; - } - - while (code >= clear_code && sp < (stack + 8192)) - { - *sp++ = table[1][code]; - if (code == table[0][code]) - return (255); - - code = table[0][code]; - } - - if (sp < (stack + 8192)) - *sp++ = firstcode = table[1][code]; - - code = max_code; - - if (code < 4096) - { - table[0][code] = oldcode; - table[1][code] = firstcode; - max_code ++; - - if (max_code >= max_code_size && max_code_size < 4096) - { - max_code_size *= 2; - code_size ++; - } - } - - oldcode = incode; - - if (sp > stack) - return ((*--sp) & 255); - } - - return (code & 255); -} - - -/* - * End of "$Id: image-gif.c 7720 2008-07-11 22:46:21Z mike $". - */ diff --git a/filter/image-jpeg.c b/filter/image-jpeg.c deleted file mode 100644 index 623a68928..000000000 --- a/filter/image-jpeg.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * "$Id: image-jpeg.c 7355 2008-02-28 20:49:40Z mike $" - * - * JPEG image routines for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * _cupsImageReadJPEG() - Read a JPEG image file. - */ - -/* - * Include necessary headers... - */ - -#include "image-private.h" - -#ifdef HAVE_LIBJPEG -# include /* JPEG/JFIF image definitions */ - - -/* - * '_cupsImageReadJPEG()' - Read a JPEG image file. - */ - -int /* O - Read status */ -_cupsImageReadJPEG( - cups_image_t *img, /* IO - cupsImage */ - FILE *fp, /* I - cupsImage file */ - cups_icspace_t primary, /* I - Primary choice for colorspace */ - cups_icspace_t secondary, /* I - Secondary choice for colorspace */ - int saturation, /* I - Color saturation (%) */ - int hue, /* I - Color hue (degrees) */ - const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */ -{ - struct jpeg_decompress_struct cinfo; /* Decompressor info */ - struct jpeg_error_mgr jerr; /* Error handler info */ - cups_ib_t *in, /* Input pixels */ - *out; /* Output pixels */ - jpeg_saved_marker_ptr marker; /* Pointer to marker data */ - int psjpeg = 0; /* Non-zero if Photoshop CMYK JPEG */ - static const char *cspaces[] = - { /* JPEG colorspaces... */ - "JCS_UNKNOWN", - "JCS_GRAYSCALE", - "JCS_RGB", - "JCS_YCbCr", - "JCS_CMYK", - "JCS_YCCK" - }; - - - /* - * Read the JPEG header... - */ - - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_decompress(&cinfo); - jpeg_save_markers(&cinfo, JPEG_APP0 + 14, 0xffff); /* Adobe JPEG */ - jpeg_stdio_src(&cinfo, fp); - jpeg_read_header(&cinfo, 1); - - /* - * Parse any Adobe APPE data embedded in the JPEG file. Since Adobe doesn't - * bother following standards, we have to invert the CMYK JPEG data written by - * Adobe apps... - */ - - for (marker = cinfo.marker_list; marker; marker = marker->next) - if (marker->marker == (JPEG_APP0 + 14) && marker->data_length >= 12 && - !memcmp(marker->data, "Adobe", 5) && marker->data[11] == 2) - { - fputs("DEBUG: Adobe CMYK JPEG detected (inverting color values)\n", - stderr); - psjpeg = 1; - } - - cinfo.quantize_colors = 0; - - fprintf(stderr, "DEBUG: num_components = %d\n", cinfo.num_components); - fprintf(stderr, "DEBUG: jpeg_color_space = %s\n", - cspaces[cinfo.jpeg_color_space]); - - if (cinfo.num_components == 1) - { - fputs("DEBUG: Converting image to grayscale...\n", stderr); - - cinfo.out_color_space = JCS_GRAYSCALE; - cinfo.out_color_components = 1; - cinfo.output_components = 1; - - img->colorspace = secondary; - } - else if (cinfo.num_components == 4) - { - fputs("DEBUG: Converting image to CMYK...\n", stderr); - - cinfo.out_color_space = JCS_CMYK; - cinfo.out_color_components = 4; - cinfo.output_components = 4; - - img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_CMYK : primary; - } - else - { - fputs("DEBUG: Converting image to RGB...\n", stderr); - - cinfo.out_color_space = JCS_RGB; - cinfo.out_color_components = 3; - cinfo.output_components = 3; - - img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary; - } - - jpeg_calc_output_dimensions(&cinfo); - - if (cinfo.output_width <= 0 || cinfo.output_width > CUPS_IMAGE_MAX_WIDTH || - cinfo.output_height <= 0 || cinfo.output_height > CUPS_IMAGE_MAX_HEIGHT) - { - fprintf(stderr, "DEBUG: Bad JPEG dimensions %dx%d!\n", - cinfo.output_width, cinfo.output_height); - - jpeg_destroy_decompress(&cinfo); - - fclose(fp); - return (1); - } - - img->xsize = cinfo.output_width; - img->ysize = cinfo.output_height; - - if (cinfo.X_density > 0 && cinfo.Y_density > 0 && cinfo.density_unit > 0) - { - if (cinfo.density_unit == 1) - { - img->xppi = cinfo.X_density; - img->yppi = cinfo.Y_density; - } - else - { - img->xppi = (int)((float)cinfo.X_density * 2.54); - img->yppi = (int)((float)cinfo.Y_density * 2.54); - } - - if (img->xppi == 0 || img->yppi == 0) - { - fprintf(stderr, "DEBUG: Bad JPEG image resolution %dx%d PPI.\n", - img->xppi, img->yppi); - img->xppi = img->yppi = 128; - } - } - - fprintf(stderr, "DEBUG: JPEG image %dx%dx%d, %dx%d PPI\n", - img->xsize, img->ysize, cinfo.output_components, - img->xppi, img->yppi); - - cupsImageSetMaxTiles(img, 0); - - in = malloc(img->xsize * cinfo.output_components); - out = malloc(img->xsize * cupsImageGetDepth(img)); - - jpeg_start_decompress(&cinfo); - - while (cinfo.output_scanline < cinfo.output_height) - { - jpeg_read_scanlines(&cinfo, (JSAMPROW *)&in, (JDIMENSION)1); - - if (psjpeg && cinfo.output_components == 4) - { - /* - * Invert CMYK data from Photoshop... - */ - - cups_ib_t *ptr; /* Pointer into buffer */ - int i; /* Looping var */ - - - for (ptr = in, i = img->xsize * 4; i > 0; i --, ptr ++) - *ptr = 255 - *ptr; - } - - if ((saturation != 100 || hue != 0) && cinfo.output_components == 3) - cupsImageRGBAdjust(in, img->xsize, saturation, hue); - - if ((img->colorspace == CUPS_IMAGE_WHITE && cinfo.out_color_space == JCS_GRAYSCALE) || - (img->colorspace == CUPS_IMAGE_CMYK && cinfo.out_color_space == JCS_CMYK)) - { -#ifdef DEBUG - int i, j; - cups_ib_t *ptr; - - - fputs("DEBUG: Direct Data...\n", stderr); - - fputs("DEBUG:", stderr); - - for (i = 0, ptr = in; i < img->xsize; i ++) - { - putc(' ', stderr); - for (j = 0; j < cinfo.output_components; j ++, ptr ++) - fprintf(stderr, "%02X", *ptr & 255); - } - - putc('\n', stderr); -#endif /* DEBUG */ - - if (lut) - cupsImageLut(in, img->xsize * cupsImageGetDepth(img), lut); - - _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, in); - } - else if (cinfo.out_color_space == JCS_GRAYSCALE) - { - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_BLACK : - cupsImageWhiteToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_RGB : - cupsImageWhiteToRGB(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageWhiteToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageWhiteToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * cupsImageGetDepth(img), lut); - - _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out); - } - else if (cinfo.out_color_space == JCS_RGB) - { - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_RGB : - cupsImageRGBToRGB(in, out, img->xsize); - break; - case CUPS_IMAGE_WHITE : - cupsImageRGBToWhite(in, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageRGBToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageRGBToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageRGBToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * cupsImageGetDepth(img), lut); - - _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out); - } - else /* JCS_CMYK */ - { - fputs("DEBUG: JCS_CMYK\n", stderr); - - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_WHITE : - cupsImageCMYKToWhite(in, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageCMYKToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageCMYKToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_RGB : - cupsImageCMYKToRGB(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * cupsImageGetDepth(img), lut); - - _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out); - } - } - - free(in); - free(out); - - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - - fclose(fp); - - return (0); -} -#endif /* HAVE_LIBJPEG */ - - -/* - * End of "$Id: image-jpeg.c 7355 2008-02-28 20:49:40Z mike $". - */ diff --git a/filter/image-photocd.c b/filter/image-photocd.c deleted file mode 100644 index 512959dbc..000000000 --- a/filter/image-photocd.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * "$Id: image-photocd.c 7221 2008-01-16 22:20:08Z mike $" - * - * PhotoCD routines for CUPS. - * - * PhotoCD support is currently limited to the 768x512 base image, which - * is only YCC encoded. Support for the higher resolution images will - * require a lot of extra code... - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2006 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * _cupsImageReadPhotoCD() - Read a PhotoCD image file. - */ - -/* - * Include necessary headers... - */ - -#include "image-private.h" - - -/* - * '_cupsImageReadPhotoCD()' - Read a PhotoCD image file. - */ - -int /* O - Read status */ -_cupsImageReadPhotoCD( - cups_image_t *img, /* IO - cupsImage */ - FILE *fp, /* I - cupsImage file */ - cups_icspace_t primary, /* I - Primary choice for colorspace */ - cups_icspace_t secondary, /* I - Secondary choice for colorspace */ - int saturation, /* I - Color saturation (%) */ - int hue, /* I - Color hue (degrees) */ - const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */ -{ - int x, y; /* Looping vars */ - int xdir, /* X direction */ - xstart; /* X starting point */ - int bpp; /* Bytes per pixel */ - int pass; /* Pass number */ - int rotation; /* 0 for 768x512, 1 for 512x768 */ - int temp, /* Adjusted luminance */ - temp2, /* Red, green, and blue values */ - cb, cr; /* Adjusted chroma values */ - cups_ib_t *in, /* Input (YCC) pixels */ - *iy, /* Luminance */ - *icb, /* Blue chroma */ - *icr, /* Red chroma */ - *rgb, /* RGB */ - *rgbptr, /* Pointer into RGB data */ - *out; /* Output pixels */ - - - (void)secondary; - - /* - * Get the image orientation... - */ - - fseek(fp, 72, SEEK_SET); - rotation = (getc(fp) & 63) != 8; - - /* - * Seek to the start of the base image... - */ - - fseek(fp, 0x30000, SEEK_SET); - - /* - * Allocate and initialize... - */ - - img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary; - img->xppi = 128; - img->yppi = 128; - - if (rotation) - { - img->xsize = 512; - img->ysize = 768; - } - else - { - img->xsize = 768; - img->ysize = 512; - } - - cupsImageSetMaxTiles(img, 0); - - bpp = cupsImageGetDepth(img); - - if ((in = malloc(768 * 3)) == NULL) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - fclose(fp); - return (1); - } - - if ((out = malloc(768 * bpp)) == NULL) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - fclose(fp); - free(in); - return (1); - } - - if (bpp > 1) - { - if ((rgb = malloc(768 * 3)) == NULL) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - fclose(fp); - free(in); - free(out); - return (1); - } - } - else - rgb = NULL; - - if (rotation) - { - xstart = 767 * bpp; - xdir = -2 * bpp; - } - else - { - xstart = 0; - xdir = 0; - } - - /* - * Read the image file... - */ - - for (y = 0; y < 512; y += 2) - { - /* - * Grab the next two scanlines: - * - * YYYYYYYYYYYYYYY... - * YYYYYYYYYYYYYYY... - * CbCbCb...CrCrCr... - */ - - if (fread(in, 1, 768 * 3, fp) < (768 * 3)) - { - /* - * Couldn't read a row of data - return an error! - */ - - free(in); - free(out); - - if (bpp > 1) - free(rgb); - - return (-1); - } - - /* - * Process the two scanlines... - */ - - for (pass = 0, iy = in; pass < 2; pass ++) - { - if (bpp == 1) - { - /* - * Just extract the luminance channel from the line and put it - * in the image... - */ - - if (primary == CUPS_IMAGE_BLACK) - { - if (rotation) - { - for (rgbptr = out + xstart, x = 0; x < 768; x ++) - *rgbptr-- = 255 - *iy++; - - if (lut) - cupsImageLut(out, 768, lut); - - _cupsImagePutCol(img, 511 - y - pass, 0, 768, out); - } - else - { - cupsImageWhiteToBlack(iy, out, 768); - - if (lut) - cupsImageLut(out, 768, lut); - - _cupsImagePutRow(img, 0, y + pass, 768, out); - iy += 768; - } - } - else if (rotation) - { - for (rgbptr = out + xstart, x = 0; x < 768; x ++) - *rgbptr-- = 255 - *iy++; - - if (lut) - cupsImageLut(out, 768, lut); - - _cupsImagePutCol(img, 511 - y - pass, 0, 768, out); - } - else - { - if (lut) - cupsImageLut(iy, 768, lut); - - _cupsImagePutRow(img, 0, y + pass, 768, iy); - iy += 768; - } - } - else - { - /* - * Convert YCbCr to RGB... While every pixel gets a luminance - * value, adjacent pixels share chroma information. - */ - - cb = cr = 0.0f; - - for (x = 0, rgbptr = rgb + xstart, icb = in + 1536, icr = in + 1920; - x < 768; - x ++, iy ++, rgbptr += xdir) - { - if (!(x & 1)) - { - cb = (float)(*icb - 156); - cr = (float)(*icr - 137); - } - - temp = 92241 * (*iy); - - temp2 = (temp + 86706 * cr) / 65536; - if (temp2 < 0) - *rgbptr++ = 0; - else if (temp2 > 255) - *rgbptr++ = 255; - else - *rgbptr++ = temp2; - - temp2 = (temp - 25914 * cb - 44166 * cr) / 65536; - if (temp2 < 0) - *rgbptr++ = 0; - else if (temp2 > 255) - *rgbptr++ = 255; - else - *rgbptr++ = temp2; - - temp2 = (temp + 133434 * cb) / 65536; - if (temp2 < 0) - *rgbptr++ = 0; - else if (temp2 > 255) - *rgbptr++ = 255; - else - *rgbptr++ = temp2; - - if (x & 1) - { - icb ++; - icr ++; - } - } - - /* - * Adjust the hue and saturation if needed... - */ - - if (saturation != 100 || hue != 0) - cupsImageRGBAdjust(rgb, 768, saturation, hue); - - /* - * Then convert the RGB data to the appropriate colorspace and - * put it in the image... - */ - - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_RGB : - cupsImageRGBToRGB(rgb, out, 768); - break; - case CUPS_IMAGE_CMY : - cupsImageRGBToCMY(rgb, out, 768); - break; - case CUPS_IMAGE_CMYK : - cupsImageRGBToCMYK(rgb, out, 768); - break; - } - - if (lut) - cupsImageLut(out, 768 * bpp, lut); - - if (rotation) - _cupsImagePutCol(img, 511 - y - pass, 0, 768, out); - else - _cupsImagePutRow(img, 0, y + pass, 768, out); - } - } - } - - /* - * Free memory and return... - */ - - free(in); - free(out); - if (bpp > 1) - free(rgb); - - return (0); -} - - -/* - * End of "$Id: image-photocd.c 7221 2008-01-16 22:20:08Z mike $". - */ diff --git a/filter/image-pix.c b/filter/image-pix.c deleted file mode 100644 index b940e770d..000000000 --- a/filter/image-pix.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * "$Id: image-pix.c 7221 2008-01-16 22:20:08Z mike $" - * - * Alias PIX image routines for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * _cupsImageReadPIX() - Read a PIX image file. - * read_short() - Read a 16-bit integer. - */ - -/* - * Include necessary headers... - */ - -#include "image-private.h" - - -/* - * Local functions... - */ - -static short read_short(FILE *fp); - - -/* - * '_cupsImageReadPIX()' - Read a PIX image file. - */ - -int /* O - Read status */ -_cupsImageReadPIX( - cups_image_t *img, /* IO - cupsImage */ - FILE *fp, /* I - cupsImage file */ - cups_icspace_t primary, /* I - Primary choice for colorspace */ - cups_icspace_t secondary, /* I - Secondary choice for colorspace */ - int saturation, /* I - Color saturation (%) */ - int hue, /* I - Color hue (degrees) */ - const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */ -{ - short width, /* Width of image */ - height, /* Height of image */ - depth; /* Depth of image (bits) */ - int count, /* Repetition count */ - bpp, /* Bytes per pixel */ - x, y; /* Looping vars */ - cups_ib_t r, g, b; /* Red, green/gray, blue values */ - cups_ib_t *in, /* Input pixels */ - *out, /* Output pixels */ - *ptr; /* Pointer into pixels */ - - - /* - * Get the image dimensions and setup the image... - */ - - width = read_short(fp); - height = read_short(fp); - read_short(fp); - read_short(fp); - depth = read_short(fp); - - /* - * Check the dimensions of the image. Since the short values used for the - * width and height cannot exceed CUPS_IMAGE_MAX_WIDTH or - * CUPS_IMAGE_MAX_HEIGHT, we just need to verify they are positive integers. - */ - - if (width <= 0 || height <= 0 || - (depth != 8 && depth != 24)) - { - fprintf(stderr, "DEBUG: Bad PIX image dimensions %dx%dx%d\n", - width, height, depth); - fclose(fp); - return (1); - } - - if (depth == 8) - img->colorspace = secondary; - else - img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary; - - img->xsize = width; - img->ysize = height; - - cupsImageSetMaxTiles(img, 0); - - bpp = cupsImageGetDepth(img); - - if ((in = malloc(img->xsize * (depth / 8))) == NULL) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - fclose(fp); - return (1); - } - - if ((out = malloc(img->xsize * bpp)) == NULL) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - fclose(fp); - free(in); - return (1); - } - - /* - * Read the image data... - */ - - if (depth == 8) - { - for (count = 0, y = 0, g = 0; y < img->ysize; y ++) - { - if (img->colorspace == CUPS_IMAGE_WHITE) - ptr = out; - else - ptr = in; - - for (x = img->xsize; x > 0; x --, count --) - { - if (count == 0) - { - count = getc(fp); - g = getc(fp); - } - - *ptr++ = g; - } - - if (img->colorspace != CUPS_IMAGE_WHITE) - switch (img->colorspace) - { - default : - cupsImageWhiteToRGB(in, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageWhiteToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageWhiteToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageWhiteToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * bpp, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, out); - } - } - else - { - for (count = 0, y = 0, r = 0, g = 0, b = 0; y < img->ysize; y ++) - { - ptr = in; - - for (x = img->xsize; x > 0; x --, count --) - { - if (count == 0) - { - count = getc(fp); - b = getc(fp); - g = getc(fp); - r = getc(fp); - } - - *ptr++ = r; - *ptr++ = g; - *ptr++ = b; - } - - if (saturation != 100 || hue != 0) - cupsImageRGBAdjust(in, img->xsize, saturation, hue); - - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_WHITE : - cupsImageRGBToWhite(in, out, img->xsize); - break; - case CUPS_IMAGE_RGB : - cupsImageRGBToWhite(in, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageRGBToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageRGBToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageRGBToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * bpp, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, out); - } - } - - fclose(fp); - free(in); - free(out); - - return (0); -} - - -/* - * 'read_short()' - Read a 16-bit integer. - */ - -static short /* O - Value from file */ -read_short(FILE *fp) /* I - File to read from */ -{ - int ch; /* Character from file */ - - - ch = getc(fp); - return ((ch << 8) | getc(fp)); -} - - -/* - * End of "$Id: image-pix.c 7221 2008-01-16 22:20:08Z mike $". - */ diff --git a/filter/image-png.c b/filter/image-png.c deleted file mode 100644 index 81defbffa..000000000 --- a/filter/image-png.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * "$Id: image-png.c 7437 2008-04-09 03:16:10Z mike $" - * - * PNG image routines for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * _cupsImageReadPNG() - Read a PNG image file. - */ - -/* - * Include necessary headers... - */ - -#include "image-private.h" - -#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ) -# include /* Portable Network Graphics (PNG) definitions */ - - -/* - * '_cupsImageReadPNG()' - Read a PNG image file. - */ - -int /* O - Read status */ -_cupsImageReadPNG( - cups_image_t *img, /* IO - cupsImage */ - FILE *fp, /* I - cupsImage file */ - cups_icspace_t primary, /* I - Primary choice for colorspace */ - cups_icspace_t secondary, /* I - Secondary choice for colorspace */ - int saturation, /* I - Color saturation (%) */ - int hue, /* I - Color hue (degrees) */ - const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */ -{ - int y; /* Looping var */ - png_structp pp; /* PNG read pointer */ - png_infop info; /* PNG info pointers */ - png_uint_32 width, /* Width of image */ - height; /* Height of image */ - int bit_depth, /* Bit depth */ - color_type, /* Color type */ - interlace_type, /* Interlace type */ - compression_type, /* Compression type */ - filter_type; /* Filter type */ - png_uint_32 xppm, /* X pixels per meter */ - yppm; /* Y pixels per meter */ - int bpp; /* Bytes per pixel */ - int pass, /* Current pass */ - passes; /* Number of passes required */ - cups_ib_t *in, /* Input pixels */ - *inptr, /* Pointer into pixels */ - *out; /* Output pixels */ - png_color_16 bg; /* Background color */ - - - /* - * Setup the PNG data structures... - */ - - pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - info = png_create_info_struct(pp); - - /* - * Initialize the PNG read "engine"... - */ - - png_init_io(pp, fp); - - /* - * Get the image dimensions and load the output image... - */ - - png_read_info(pp, info); - - png_get_IHDR(pp, info, &width, &height, &bit_depth, &color_type, - &interlace_type, &compression_type, &filter_type); - - fprintf(stderr, "DEBUG: PNG image: %dx%dx%d, color_type=%x (%s%s%s)\n", - (int)width, (int)height, bit_depth, color_type, - (color_type & PNG_COLOR_MASK_COLOR) ? "RGB" : "GRAYSCALE", - (color_type & PNG_COLOR_MASK_ALPHA) ? "+ALPHA" : "", - (color_type & PNG_COLOR_MASK_PALETTE) ? "+PALETTE" : ""); - - if (color_type & PNG_COLOR_MASK_PALETTE) - png_set_expand(pp); - else if (bit_depth < 8) - { - png_set_packing(pp); - png_set_expand(pp); - } - else if (bit_depth == 16) - png_set_strip_16(pp); - - if (color_type & PNG_COLOR_MASK_COLOR) - img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : - primary; - else - img->colorspace = secondary; - - if (width == 0 || width > CUPS_IMAGE_MAX_WIDTH || - height == 0 || height > CUPS_IMAGE_MAX_HEIGHT) - { - fprintf(stderr, "DEBUG: PNG image has invalid dimensions %ux%u!\n", - (unsigned)width, (unsigned)height); - fclose(fp); - return (1); - } - - img->xsize = width; - img->ysize = height; - - if ((xppm = png_get_x_pixels_per_meter(pp, info)) != 0 && - (yppm = png_get_y_pixels_per_meter(pp, info)) != 0) - { - img->xppi = (int)((float)xppm * 0.0254); - img->yppi = (int)((float)yppm * 0.0254); - - if (img->xppi == 0 || img->yppi == 0) - { - fprintf(stderr, "DEBUG: PNG image has invalid resolution %dx%d PPI\n", - img->xppi, img->yppi); - - img->xppi = img->yppi = 128; - } - } - - cupsImageSetMaxTiles(img, 0); - - passes = png_set_interlace_handling(pp); - - /* - * Handle transparency... - */ - - if (png_get_valid(pp, info, PNG_INFO_tRNS)) - png_set_tRNS_to_alpha(pp); - - bg.red = 65535; - bg.green = 65535; - bg.blue = 65535; - - png_set_background(pp, &bg, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); - - if (passes == 1) - { - /* - * Load one row at a time... - */ - - if (color_type == PNG_COLOR_TYPE_GRAY || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - in = malloc(img->xsize); - else - in = malloc(img->xsize * 3); - } - else - { - /* - * Interlaced images must be loaded all at once... - */ - - size_t bufsize; /* Size of buffer */ - - - if (color_type == PNG_COLOR_TYPE_GRAY || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - bufsize = img->xsize * img->ysize; - - if ((bufsize / img->xsize) != img->ysize) - { - fprintf(stderr, "DEBUG: PNG image dimensions (%ux%u) too large!\n", - (unsigned)width, (unsigned)height); - fclose(fp); - return (1); - } - } - else - { - bufsize = img->xsize * img->ysize * 3; - - if ((bufsize / (img->xsize * 3)) != img->ysize) - { - fprintf(stderr, "DEBUG: PNG image dimensions (%ux%u) too large!\n", - (unsigned)width, (unsigned)height); - fclose(fp); - return (1); - } - } - - in = malloc(bufsize); - } - - bpp = cupsImageGetDepth(img); - out = malloc(img->xsize * bpp); - - if (!in || !out) - { - fputs("DEBUG: Unable to allocate memory for PNG image!\n", stderr); - - if (in) - free(in); - - if (out) - free(out); - - fclose(fp); - - return (1); - } - - /* - * Read the image, interlacing as needed... - */ - - for (pass = 1; pass <= passes; pass ++) - for (inptr = in, y = 0; y < img->ysize; y ++) - { - png_read_row(pp, (png_bytep)inptr, NULL); - - if (pass == passes) - { - /* - * Output this row... - */ - - if (color_type & PNG_COLOR_MASK_COLOR) - { - if ((saturation != 100 || hue != 0) && bpp > 1) - cupsImageRGBAdjust(inptr, img->xsize, saturation, hue); - - switch (img->colorspace) - { - case CUPS_IMAGE_WHITE : - cupsImageRGBToWhite(inptr, out, img->xsize); - break; - case CUPS_IMAGE_RGB : - case CUPS_IMAGE_RGB_CMYK : - cupsImageRGBToRGB(inptr, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageRGBToBlack(inptr, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageRGBToCMY(inptr, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageRGBToCMYK(inptr, out, img->xsize); - break; - } - } - else - { - switch (img->colorspace) - { - case CUPS_IMAGE_WHITE : - memcpy(out, inptr, img->xsize); - break; - case CUPS_IMAGE_RGB : - case CUPS_IMAGE_RGB_CMYK : - cupsImageWhiteToRGB(inptr, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageWhiteToBlack(inptr, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageWhiteToCMY(inptr, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageWhiteToCMYK(inptr, out, img->xsize); - break; - } - } - - if (lut) - cupsImageLut(out, img->xsize * bpp, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, out); - } - - if (passes > 1) - { - if (color_type & PNG_COLOR_MASK_COLOR) - inptr += img->xsize * 3; - else - inptr += img->xsize; - } - } - - png_read_end(pp, info); - png_destroy_read_struct(&pp, &info, NULL); - - fclose(fp); - free(in); - free(out); - - return (0); -} -#endif /* HAVE_LIBPNG && HAVE_LIBZ */ - - -/* - * End of "$Id: image-png.c 7437 2008-04-09 03:16:10Z mike $". - */ diff --git a/filter/image-pnm.c b/filter/image-pnm.c deleted file mode 100644 index 8cc761f33..000000000 --- a/filter/image-pnm.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * "$Id: image-pnm.c 7374 2008-03-08 01:13:26Z mike $" - * - * Portable Any Map file routines for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * _cupsImageReadPNM() - Read a PNM image file. - */ - -/* - * Include necessary headers... - */ - -#include "image-private.h" - - -/* - * '_cupsImageReadPNM()' - Read a PNM image file. - */ - -int /* O - Read status */ -_cupsImageReadPNM( - cups_image_t *img, /* IO - cupsImage */ - FILE *fp, /* I - cupsImage file */ - cups_icspace_t primary, /* I - Primary choice for colorspace */ - cups_icspace_t secondary, /* I - Secondary choice for colorspace */ - int saturation, /* I - Color saturation (%) */ - int hue, /* I - Color hue (degrees) */ - const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */ -{ - int x, y; /* Looping vars */ - int bpp; /* Bytes per pixel */ - cups_ib_t *in, /* Input pixels */ - *inptr, /* Current input pixel */ - *out, /* Output pixels */ - *outptr, /* Current output pixel */ - bit; /* Bit in input line */ - char line[255], /* Input line */ - *lineptr; /* Pointer in line */ - int format, /* Format of PNM file */ - val, /* Pixel value */ - maxval; /* Maximum pixel value */ - - - /* - * Read the file header in the format: - * - * Pformat - * # comment1 - * # comment2 - * ... - * # commentN - * width - * height - * max sample - */ - - if ((lineptr = fgets(line, sizeof(line), fp)) == NULL) - { - fputs("DEBUG: Bad PNM header!\n", stderr); - fclose(fp); - return (1); - } - - lineptr ++; - - format = atoi(lineptr); - while (isdigit(*lineptr & 255)) - lineptr ++; - - while (lineptr != NULL && img->xsize == 0) - { - if (*lineptr == '\0' || *lineptr == '#') - lineptr = fgets(line, sizeof(line), fp); - else if (isdigit(*lineptr & 255)) - { - img->xsize = atoi(lineptr); - while (isdigit(*lineptr & 255)) - lineptr ++; - } - else - lineptr ++; - } - - while (lineptr != NULL && img->ysize == 0) - { - if (*lineptr == '\0' || *lineptr == '#') - lineptr = fgets(line, sizeof(line), fp); - else if (isdigit(*lineptr & 255)) - { - img->ysize = atoi(lineptr); - while (isdigit(*lineptr & 255)) - lineptr ++; - } - else - lineptr ++; - } - - if (format != 1 && format != 4) - { - maxval = 0; - - while (lineptr != NULL && maxval == 0) - { - if (*lineptr == '\0' || *lineptr == '#') - lineptr = fgets(line, sizeof(line), fp); - else if (isdigit(*lineptr & 255)) - { - maxval = atoi(lineptr); - while (isdigit(*lineptr & 255)) - lineptr ++; - } - else - lineptr ++; - } - } - else - maxval = 1; - - if (img->xsize == 0 || img->xsize > CUPS_IMAGE_MAX_WIDTH || - img->ysize == 0 || img->ysize > CUPS_IMAGE_MAX_HEIGHT) - { - fprintf(stderr, "DEBUG: Bad PNM dimensions %dx%d!\n", - img->xsize, img->ysize); - fclose(fp); - return (1); - } - - if (maxval == 0) - { - fprintf(stderr, "DEBUG: Bad PNM max value %d!\n", maxval); - fclose(fp); - return (1); - } - - if (format == 1 || format == 2 || format == 4 || format == 5) - img->colorspace = secondary; - else - img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary; - - cupsImageSetMaxTiles(img, 0); - - bpp = cupsImageGetDepth(img); - - if ((in = malloc(img->xsize * 3)) == NULL) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - fclose(fp); - return (1); - } - - if ((out = malloc(img->xsize * bpp)) == NULL) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - fclose(fp); - free(in); - return (1); - } - - /* - * Read the image file... - */ - - for (y = 0; y < img->ysize; y ++) - { - switch (format) - { - case 1 : - for (x = img->xsize, inptr = in; x > 0; x --, inptr ++) - if (fscanf(fp, "%d", &val) == 1) - *inptr = val ? 0 : 255; - break; - - case 2 : - for (x = img->xsize, inptr = in; x > 0; x --, inptr ++) - if (fscanf(fp, "%d", &val) == 1) - *inptr = 255 * val / maxval; - break; - - case 3 : - for (x = img->xsize, inptr = in; x > 0; x --, inptr += 3) - { - if (fscanf(fp, "%d", &val) == 1) - inptr[0] = 255 * val / maxval; - if (fscanf(fp, "%d", &val) == 1) - inptr[1] = 255 * val / maxval; - if (fscanf(fp, "%d", &val) == 1) - inptr[2] = 255 * val / maxval; - } - break; - - case 4 : - fread(out, (img->xsize + 7) / 8, 1, fp); - for (x = img->xsize, inptr = in, outptr = out, bit = 128; - x > 0; - x --, inptr ++) - { - if (*outptr & bit) - *inptr = 0; - else - *inptr = 255; - - if (bit > 1) - bit >>= 1; - else - { - bit = 128; - outptr ++; - } - } - break; - - case 5 : - fread(in, img->xsize, 1, fp); - break; - - case 6 : - fread(in, img->xsize, 3, fp); - break; - } - - switch (format) - { - case 1 : - case 2 : - case 4 : - case 5 : - if (img->colorspace == CUPS_IMAGE_WHITE) - { - if (lut) - cupsImageLut(in, img->xsize, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, in); - } - else - { - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_RGB : - cupsImageWhiteToRGB(in, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageWhiteToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageWhiteToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageWhiteToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * bpp, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, out); - } - break; - - default : - if ((saturation != 100 || hue != 0) && bpp > 1) - cupsImageRGBAdjust(in, img->xsize, saturation, hue); - - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_WHITE : - cupsImageRGBToWhite(in, out, img->xsize); - break; - case CUPS_IMAGE_RGB : - cupsImageRGBToRGB(in, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageRGBToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageRGBToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageRGBToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * bpp, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, out); - break; - } - } - - free(in); - free(out); - - fclose(fp); - - return (0); -} - - -/* - * End of "$Id: image-pnm.c 7374 2008-03-08 01:13:26Z mike $". - */ diff --git a/filter/image-private.h b/filter/image-private.h deleted file mode 100644 index 2264cf1f7..000000000 --- a/filter/image-private.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - * "$Id: image-private.h 7473 2008-04-21 17:51:58Z mike $" - * - * Private image library definitions for CUPS. - * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1993-2006 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - */ - -#ifndef _CUPS_IMAGE_PRIVATE_H_ -# define _CUPS_IMAGE_PRIVATE_H_ - -/* - * Include necessary headers... - */ - -# include "image.h" -# include -# include -# include -# include -# include -# ifdef WIN32 -# include -# else -# include -# endif /* WIN32 */ -# include -# include - - -/* - * Constants... - */ - -# define CUPS_IMAGE_MAX_WIDTH 0x07ffffff - /* 2^27-1 to allow for 15-channel data */ -# define CUPS_IMAGE_MAX_HEIGHT 0x3fffffff - /* 2^30-1 */ - -# define CUPS_TILE_SIZE 256 /* 256x256 pixel tiles */ -# define CUPS_TILE_MINIMUM 10 /* Minimum number of tiles */ - - -/* - * min/max/abs macros... - */ - -# ifndef max -# define max(a,b) ((a) > (b) ? (a) : (b)) -# endif /* !max */ -# ifndef min -# define min(a,b) ((a) < (b) ? (a) : (b)) -# endif /* !min */ -# ifndef abs -# define abs(a) ((a) < 0 ? -(a) : (a)) -# endif /* !abs */ - - -/* - * Types and structures... - */ - -typedef enum cups_iztype_e /**** Image zoom type ****/ -{ - CUPS_IZOOM_FAST, /* Use nearest-neighbor sampling */ - CUPS_IZOOM_NORMAL, /* Use bilinear interpolation */ - CUPS_IZOOM_BEST /* Use bicubic interpolation */ -} cups_iztype_t; - -struct cups_ic_s; - -typedef struct cups_itile_s /**** Image tile ****/ -{ - int dirty; /* True if tile is dirty */ - off_t pos; /* Position of tile on disk (-1 if not written) */ - struct cups_ic_s *ic; /* Pixel data */ -} cups_itile_t; - -typedef struct cups_ic_s /**** Image tile cache ****/ -{ - struct cups_ic_s *prev, /* Previous tile in cache */ - *next; /* Next tile in cache */ - cups_itile_t *tile; /* Tile this is attached to */ - cups_ib_t *pixels; /* Pixel data */ -} cups_ic_t; - -struct cups_image_s /**** Image file data ****/ -{ - cups_icspace_t colorspace; /* Colorspace of image */ - unsigned xsize, /* Width of image in pixels */ - ysize, /* Height of image in pixels */ - xppi, /* X resolution in pixels-per-inch */ - yppi, /* Y resolution in pixels-per-inch */ - num_ics, /* Number of cached tiles */ - max_ics; /* Maximum number of cached tiles */ - cups_itile_t **tiles; /* Tiles in image */ - cups_ic_t *first, /* First cached tile in image */ - *last; /* Last cached tile in image */ - int cachefile; /* Tile cache file */ - char cachename[256]; /* Tile cache filename */ -}; - -struct cups_izoom_s /**** Image zoom data ****/ -{ - cups_image_t *img; /* Image to zoom */ - cups_iztype_t type; /* Type of zooming */ - unsigned xorig, /* X origin */ - yorig, /* Y origin */ - width, /* Width of input area */ - height, /* Height of input area */ - depth, /* Number of bytes per pixel */ - rotated, /* Non-zero if image needs to be rotated */ - xsize, /* Width of output image */ - ysize, /* Height of output image */ - xmax, /* Maximum input image X position */ - ymax, /* Maximum input image Y position */ - xmod, /* Threshold for Bresenheim rounding */ - ymod; /* ... */ - int xstep, /* Amount to step for each pixel along X */ - xincr, - instep, /* Amount to step pixel pointer along X */ - inincr, - ystep, /* Amount to step for each pixel along Y */ - yincr, - row; /* Current row */ - cups_ib_t *rows[2], /* Horizontally scaled pixel data */ - *in; /* Unscaled input pixel data */ -}; - - -/* - * Prototypes... - */ - -extern int _cupsImagePutCol(cups_image_t *img, int x, int y, - int height, const cups_ib_t *pixels); -extern int _cupsImagePutRow(cups_image_t *img, int x, int y, - int width, const cups_ib_t *pixels); -extern int _cupsImageReadBMP(cups_image_t *img, FILE *fp, - cups_icspace_t primary, - cups_icspace_t secondary, - int saturation, int hue, - const cups_ib_t *lut); -extern int _cupsImageReadFPX(cups_image_t *img, FILE *fp, - cups_icspace_t primary, - cups_icspace_t secondary, - int saturation, int hue, - const cups_ib_t *lut); -extern int _cupsImageReadGIF(cups_image_t *img, FILE *fp, - cups_icspace_t primary, - cups_icspace_t secondary, - int saturation, int hue, - const cups_ib_t *lut); -extern int _cupsImageReadJPEG(cups_image_t *img, FILE *fp, - cups_icspace_t primary, - cups_icspace_t secondary, - int saturation, int hue, - const cups_ib_t *lut); -extern int _cupsImageReadPIX(cups_image_t *img, FILE *fp, - cups_icspace_t primary, - cups_icspace_t secondary, - int saturation, int hue, - const cups_ib_t *lut); -extern int _cupsImageReadPNG(cups_image_t *img, FILE *fp, - cups_icspace_t primary, - cups_icspace_t secondary, - int saturation, int hue, - const cups_ib_t *lut); -extern int _cupsImageReadPNM(cups_image_t *img, FILE *fp, - cups_icspace_t primary, - cups_icspace_t secondary, - int saturation, int hue, - const cups_ib_t *lut); -extern int _cupsImageReadPhotoCD(cups_image_t *img, FILE *fp, - cups_icspace_t primary, - cups_icspace_t secondary, - int saturation, int hue, - const cups_ib_t *lut); -extern int _cupsImageReadSGI(cups_image_t *img, FILE *fp, - cups_icspace_t primary, - cups_icspace_t secondary, - int saturation, int hue, - const cups_ib_t *lut); -extern int _cupsImageReadSunRaster(cups_image_t *img, FILE *fp, - cups_icspace_t primary, - cups_icspace_t secondary, - int saturation, int hue, - const cups_ib_t *lut); -extern int _cupsImageReadTIFF(cups_image_t *img, FILE *fp, - cups_icspace_t primary, - cups_icspace_t secondary, - int saturation, int hue, - const cups_ib_t *lut); -extern void _cupsImageZoomDelete(cups_izoom_t *z); -extern void _cupsImageZoomFill(cups_izoom_t *z, int iy); -extern cups_izoom_t *_cupsImageZoomNew(cups_image_t *img, int xc0, int yc0, - int xc1, int yc1, int xsize, - int ysize, int rotated, - cups_iztype_t type); - -extern int _cupsRasterExecPS(cups_page_header2_t *h, - int *preferred_bits, - const char *code); -extern void _cupsRasterAddError(const char *f, ...); -extern void _cupsRasterClearError(void); - -#endif /* !_CUPS_IMAGE_PRIVATE_H_ */ - -/* - * End of "$Id: image-private.h 7473 2008-04-21 17:51:58Z mike $". - */ diff --git a/filter/image-sgi.c b/filter/image-sgi.c deleted file mode 100644 index 39d6f4453..000000000 --- a/filter/image-sgi.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * "$Id: image-sgi.c 7223 2008-01-16 23:41:19Z mike $" - * - * SGI image file routines for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * _cupsImageReadSGI() - Read a SGI image file. - */ - -/* - * Include necessary headers... - */ - -#include "image-private.h" -#include "image-sgi.h" - - -/* - * '_cupsImageReadSGI()' - Read a SGI image file. - */ - -int /* O - Read status */ -_cupsImageReadSGI( - cups_image_t *img, /* IO - cupsImage */ - FILE *fp, /* I - cupsImage file */ - cups_icspace_t primary, /* I - Primary choice for colorspace */ - cups_icspace_t secondary, /* I - Secondary choice for colorspace */ - int saturation, /* I - Color saturation (%) */ - int hue, /* I - Color hue (degrees) */ - const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */ -{ - int i, y; /* Looping vars */ - int bpp; /* Bytes per pixel */ - sgi_t *sgip; /* SGI image file */ - cups_ib_t *in, /* Input pixels */ - *inptr, /* Current input pixel */ - *out; /* Output pixels */ - unsigned short *rows[4], /* Row pointers for image data */ - *red, - *green, - *blue, - *gray, - *alpha; - - - /* - * Setup the SGI file... - */ - - sgip = sgiOpenFile(fp, SGI_READ, 0, 0, 0, 0, 0); - - /* - * Get the image dimensions and load the output image... - */ - - /* - * Check the image dimensions; since xsize and ysize are unsigned shorts, - * just check if they are 0 since they can't exceed CUPS_IMAGE_MAX_WIDTH or - * CUPS_IMAGE_MAX_HEIGHT... - */ - - if (sgip->xsize == 0 || sgip->ysize == 0 || - sgip->zsize == 0 || sgip->zsize > 4) - { - fprintf(stderr, "DEBUG: Bad SGI image dimensions %ux%ux%u!\n", - sgip->xsize, sgip->ysize, sgip->zsize); - sgiClose(sgip); - return (1); - } - - if (sgip->zsize < 3) - img->colorspace = secondary; - else - img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary; - - img->xsize = sgip->xsize; - img->ysize = sgip->ysize; - - cupsImageSetMaxTiles(img, 0); - - bpp = cupsImageGetDepth(img); - - if ((in = malloc(img->xsize * sgip->zsize)) == NULL) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - sgiClose(sgip); - return (1); - } - - if ((out = malloc(img->xsize * bpp)) == NULL) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - sgiClose(sgip); - free(in); - return (1); - } - - if ((rows[0] = calloc(img->xsize * sgip->zsize, - sizeof(unsigned short))) == NULL) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - sgiClose(sgip); - free(in); - free(out); - return (1); - } - - for (i = 1; i < sgip->zsize; i ++) - rows[i] = rows[0] + i * img->xsize; - - /* - * Read the SGI image file... - */ - - for (y = 0; y < img->ysize; y ++) - { - for (i = 0; i < sgip->zsize; i ++) - sgiGetRow(sgip, rows[i], img->ysize - 1 - y, i); - - switch (sgip->zsize) - { - case 1 : - if (sgip->bpp == 1) - for (i = img->xsize - 1, gray = rows[0], inptr = in; - i >= 0; - i --) - { - *inptr++ = *gray++; - } - else - for (i = img->xsize - 1, gray = rows[0], inptr = in; - i >= 0; - i --) - { - *inptr++ = (*gray++) / 256 + 128; - } - break; - case 2 : - if (sgip->bpp == 1) - for (i = img->xsize - 1, gray = rows[0], alpha = rows[1], inptr = in; - i >= 0; - i --) - { - *inptr++ = (*gray++) * (*alpha++) / 255; - } - else - for (i = img->xsize - 1, gray = rows[0], alpha = rows[1], inptr = in; - i >= 0; - i --) - { - *inptr++ = ((*gray++) / 256 + 128) * (*alpha++) / 32767; - } - break; - case 3 : - if (sgip->bpp == 1) - for (i = img->xsize - 1, red = rows[0], green = rows[1], - blue = rows[2], inptr = in; - i >= 0; - i --) - { - *inptr++ = *red++; - *inptr++ = *green++; - *inptr++ = *blue++; - } - else - for (i = img->xsize - 1, red = rows[0], green = rows[1], - blue = rows[2], inptr = in; - i >= 0; - i --) - { - *inptr++ = (*red++) / 256 + 128; - *inptr++ = (*green++) / 256 + 128; - *inptr++ = (*blue++) / 256 + 128; - } - break; - case 4 : - if (sgip->bpp == 1) - for (i = img->xsize - 1, red = rows[0], green = rows[1], - blue = rows[2], alpha = rows[3], inptr = in; - i >= 0; - i --) - { - *inptr++ = (*red++) * (*alpha) / 255; - *inptr++ = (*green++) * (*alpha) / 255; - *inptr++ = (*blue++) * (*alpha++) / 255; - } - else - for (i = img->xsize - 1, red = rows[0], green = rows[1], - blue = rows[2], alpha = rows[3], inptr = in; - i >= 0; - i --) - { - *inptr++ = ((*red++) / 256 + 128) * (*alpha) / 32767; - *inptr++ = ((*green++) / 256 + 128) * (*alpha) / 32767; - *inptr++ = ((*blue++) / 256 + 128) * (*alpha++) / 32767; - } - break; - } - - if (sgip->zsize < 3) - { - if (img->colorspace == CUPS_IMAGE_WHITE) - { - if (lut) - cupsImageLut(in, img->xsize, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, in); - } - else - { - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_RGB : - case CUPS_IMAGE_RGB_CMYK : - cupsImageWhiteToRGB(in, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageWhiteToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageWhiteToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageWhiteToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * bpp, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, out); - } - } - else - { - if ((saturation != 100 || hue != 0) && bpp > 1) - cupsImageRGBAdjust(in, img->xsize, saturation, hue); - - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_WHITE : - cupsImageRGBToWhite(in, out, img->xsize); - break; - case CUPS_IMAGE_RGB : - cupsImageRGBToRGB(in, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageRGBToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageRGBToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageRGBToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * bpp, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, out); - } - } - - free(in); - free(out); - free(rows[0]); - - sgiClose(sgip); - - return (0); -} - - -/* - * End of "$Id: image-sgi.c 7223 2008-01-16 23:41:19Z mike $". - */ diff --git a/filter/image-sgi.h b/filter/image-sgi.h deleted file mode 100644 index 8f1781a2d..000000000 --- a/filter/image-sgi.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * "$Id: image-sgi.h 6649 2007-07-11 21:46:42Z mike $" - * - * SGI image file format library definitions for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - */ - -#ifndef _SGI_H_ -# define _SGI_H_ - -# include -# include -# include - -# ifdef __cplusplus -extern "C" { -# endif - - -/* - * Constants... - */ - -# define SGI_MAGIC 474 /* Magic number in image file */ - -# define SGI_READ 0 /* Read from an SGI image file */ -# define SGI_WRITE 1 /* Write to an SGI image file */ - -# define SGI_COMP_NONE 0 /* No compression */ -# define SGI_COMP_RLE 1 /* Run-length encoding */ -# define SGI_COMP_ARLE 2 /* Agressive run-length encoding */ - - -/* - * Image structure... - */ - -typedef struct -{ - FILE *file; /* Image file */ - int mode, /* File open mode */ - bpp, /* Bytes per pixel/channel */ - comp; /* Compression */ - unsigned short xsize, /* Width in pixels */ - ysize, /* Height in pixels */ - zsize; /* Number of channels */ - long firstrow, /* File offset for first row */ - nextrow, /* File offset for next row */ - **table, /* Offset table for compression */ - **length; /* Length table for compression */ - unsigned short *arle_row; /* Advanced RLE compression buffer */ - long arle_offset, /* Advanced RLE buffer offset */ - arle_length; /* Advanced RLE buffer length */ -} sgi_t; - - -/* - * Prototypes... - */ - -extern int sgiClose(sgi_t *sgip); -extern int sgiGetRow(sgi_t *sgip, unsigned short *row, int y, int z); -extern sgi_t *sgiOpen(const char *filename, int mode, int comp, int bpp, - int xsize, int ysize, int zsize); -extern sgi_t *sgiOpenFile(FILE *file, int mode, int comp, int bpp, - int xsize, int ysize, int zsize); -extern int sgiPutRow(sgi_t *sgip, unsigned short *row, int y, int z); - -# ifdef __cplusplus -} -# endif -#endif /* !_SGI_H_ */ - -/* - * End of "$Id: image-sgi.h 6649 2007-07-11 21:46:42Z mike $". - */ diff --git a/filter/image-sgilib.c b/filter/image-sgilib.c deleted file mode 100644 index 4f3d50fe0..000000000 --- a/filter/image-sgilib.c +++ /dev/null @@ -1,890 +0,0 @@ -/* - * "$Id: image-sgilib.c 7221 2008-01-16 22:20:08Z mike $" - * - * SGI image file format library routines for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * sgiClose() - Close an SGI image file. - * sgiGetRow() - Get a row of image data from a file. - * sgiOpen() - Open an SGI image file for reading or writing. - * sgiOpenFile() - Open an SGI image file for reading or writing. - * sgiPutRow() - Put a row of image data to a file. - * getlong() - Get a 32-bit big-endian integer. - * getshort() - Get a 16-bit big-endian integer. - * putlong() - Put a 32-bit big-endian integer. - * putshort() - Put a 16-bit big-endian integer. - * read_rle8() - Read 8-bit RLE data. - * read_rle16() - Read 16-bit RLE data. - * write_rle8() - Write 8-bit RLE data. - * write_rle16() - Write 16-bit RLE data. - */ - -#include "image-sgi.h" - - -/* - * Local functions... - */ - -static int getlong(FILE *); -static int getshort(FILE *); -static int putlong(long, FILE *); -static int putshort(unsigned short, FILE *); -static int read_rle8(FILE *, unsigned short *, int); -static int read_rle16(FILE *, unsigned short *, int); -static int write_rle8(FILE *, unsigned short *, int); -static int write_rle16(FILE *, unsigned short *, int); - - -/* - * 'sgiClose()' - Close an SGI image file. - */ - -int /* O - 0 on success, -1 on error */ -sgiClose(sgi_t *sgip) /* I - SGI image */ -{ - int i; /* Return status */ - long *offset; /* Looping var for offset table */ - - - if (sgip == NULL) - return (-1); - - if (sgip->mode == SGI_WRITE && sgip->comp != SGI_COMP_NONE) - { - /* - * Write the scanline offset table to the file... - */ - - fseek(sgip->file, 512, SEEK_SET); - - for (i = sgip->ysize * sgip->zsize, offset = sgip->table[0]; - i > 0; - i --, offset ++) - if (putlong(offset[0], sgip->file) < 0) - return (-1); - - for (i = sgip->ysize * sgip->zsize, offset = sgip->length[0]; - i > 0; - i --, offset ++) - if (putlong(offset[0], sgip->file) < 0) - return (-1); - } - - if (sgip->table != NULL) - { - free(sgip->table[0]); - free(sgip->table); - } - - if (sgip->length != NULL) - { - free(sgip->length[0]); - free(sgip->length); - } - - if (sgip->comp == SGI_COMP_ARLE) - free(sgip->arle_row); - - i = fclose(sgip->file); - free(sgip); - - return (i); -} - - -/* - * 'sgiGetRow()' - Get a row of image data from a file. - */ - -int /* O - 0 on success, -1 on error */ -sgiGetRow(sgi_t *sgip, /* I - SGI image */ - unsigned short *row, /* O - Row to read */ - int y, /* I - Line to read */ - int z) /* I - Channel to read */ -{ - int x; /* X coordinate */ - long offset; /* File offset */ - - - if (sgip == NULL || - row == NULL || - y < 0 || y >= sgip->ysize || - z < 0 || z >= sgip->zsize) - return (-1); - - switch (sgip->comp) - { - case SGI_COMP_NONE : - /* - * Seek to the image row - optimize buffering by only seeking if - * necessary... - */ - - offset = 512 + (y + z * sgip->ysize) * sgip->xsize * sgip->bpp; - if (offset != ftell(sgip->file)) - fseek(sgip->file, offset, SEEK_SET); - - if (sgip->bpp == 1) - { - for (x = sgip->xsize; x > 0; x --, row ++) - *row = getc(sgip->file); - } - else - { - for (x = sgip->xsize; x > 0; x --, row ++) - *row = getshort(sgip->file); - } - break; - - case SGI_COMP_RLE : - offset = sgip->table[z][y]; - if (offset != ftell(sgip->file)) - fseek(sgip->file, offset, SEEK_SET); - - if (sgip->bpp == 1) - return (read_rle8(sgip->file, row, sgip->xsize)); - else - return (read_rle16(sgip->file, row, sgip->xsize)); - } - - return (0); -} - - -/* - * 'sgiOpen()' - Open an SGI image file for reading or writing. - */ - -sgi_t * /* O - New image */ -sgiOpen(const char *filename, /* I - File to open */ - int mode, /* I - Open mode (SGI_READ or SGI_WRITE) */ - int comp, /* I - Type of compression */ - int bpp, /* I - Bytes per pixel */ - int xsize, /* I - Width of image in pixels */ - int ysize, /* I - Height of image in pixels */ - int zsize) /* I - Number of channels */ -{ - sgi_t *sgip; /* New SGI image file */ - FILE *file; /* Image file pointer */ - - - if (mode == SGI_READ) - file = fopen(filename, "rb"); - else - file = fopen(filename, "wb+"); - - if (file == NULL) - return (NULL); - - if ((sgip = sgiOpenFile(file, mode, comp, bpp, xsize, ysize, zsize)) == NULL) - fclose(file); - - return (sgip); -} - - -/* - * 'sgiOpenFile()' - Open an SGI image file for reading or writing. - */ - -sgi_t * /* O - New image */ -sgiOpenFile(FILE *file, /* I - File to open */ - int mode, /* I - Open mode (SGI_READ or SGI_WRITE) */ - int comp, /* I - Type of compression */ - int bpp, /* I - Bytes per pixel */ - int xsize, /* I - Width of image in pixels */ - int ysize, /* I - Height of image in pixels */ - int zsize) /* I - Number of channels */ -{ - int i, j; /* Looping var */ - char name[80]; /* Name of file in image header */ - short magic; /* Magic number */ - sgi_t *sgip; /* New image pointer */ - - - if ((sgip = calloc(sizeof(sgi_t), 1)) == NULL) - return (NULL); - - sgip->file = file; - - switch (mode) - { - case SGI_READ : - sgip->mode = SGI_READ; - - magic = getshort(sgip->file); - if (magic != SGI_MAGIC) - { - free(sgip); - return (NULL); - } - - sgip->comp = getc(sgip->file); - sgip->bpp = getc(sgip->file); - getshort(sgip->file); /* Dimensions */ - sgip->xsize = getshort(sgip->file); - sgip->ysize = getshort(sgip->file); - sgip->zsize = getshort(sgip->file); - getlong(sgip->file); /* Minimum pixel */ - getlong(sgip->file); /* Maximum pixel */ - - if (sgip->comp) - { - /* - * This file is compressed; read the scanline tables... - */ - - fseek(sgip->file, 512, SEEK_SET); - - if ((sgip->table = calloc(sgip->zsize, sizeof(long *))) == NULL) - { - free(sgip); - return (NULL); - } - - if ((sgip->table[0] = calloc(sgip->ysize * sgip->zsize, - sizeof(long))) == NULL) - { - free(sgip->table); - free(sgip); - return (NULL); - } - - for (i = 1; i < sgip->zsize; i ++) - sgip->table[i] = sgip->table[0] + i * sgip->ysize; - - for (i = 0; i < sgip->zsize; i ++) - for (j = 0; j < sgip->ysize; j ++) - sgip->table[i][j] = getlong(sgip->file); - } - break; - - case SGI_WRITE : - if (xsize < 1 || - ysize < 1 || - zsize < 1 || - bpp < 1 || bpp > 2 || - comp < SGI_COMP_NONE || comp > SGI_COMP_ARLE) - { - free(sgip); - return (NULL); - } - - sgip->mode = SGI_WRITE; - - putshort(SGI_MAGIC, sgip->file); - putc((sgip->comp = comp) != 0, sgip->file); - putc(sgip->bpp = bpp, sgip->file); - putshort(3, sgip->file); /* Dimensions */ - putshort(sgip->xsize = xsize, sgip->file); - putshort(sgip->ysize = ysize, sgip->file); - putshort(sgip->zsize = zsize, sgip->file); - if (bpp == 1) - { - putlong(0, sgip->file); /* Minimum pixel */ - putlong(255, sgip->file); /* Maximum pixel */ - } - else - { - putlong(-32768, sgip->file); /* Minimum pixel */ - putlong(32767, sgip->file); /* Maximum pixel */ - } - putlong(0, sgip->file); /* Reserved */ - - memset(name, 0, sizeof(name)); - fwrite(name, sizeof(name), 1, sgip->file); - - for (i = 0; i < 102; i ++) - putlong(0, sgip->file); - - switch (comp) - { - case SGI_COMP_NONE : /* No compression */ - /* - * This file is uncompressed. To avoid problems with sparse files, - * we need to write blank pixels for the entire image... - */ - - if (bpp == 1) - { - for (i = xsize * ysize * zsize; i > 0; i --) - putc(0, sgip->file); - } - else - { - for (i = xsize * ysize * zsize; i > 0; i --) - putshort(0, sgip->file); - } - break; - - case SGI_COMP_ARLE : /* Aggressive RLE */ - sgip->arle_row = calloc(xsize, sizeof(unsigned short)); - sgip->arle_offset = 0; - - case SGI_COMP_RLE : /* Run-Length Encoding */ - /* - * This file is compressed; write the (blank) scanline tables... - */ - - for (i = 2 * ysize * zsize; i > 0; i --) - putlong(0, sgip->file); - - sgip->firstrow = ftell(sgip->file); - sgip->nextrow = ftell(sgip->file); - if ((sgip->table = calloc(sgip->zsize, sizeof(long *))) == NULL) - { - free(sgip); - return (NULL); - } - - if ((sgip->table[0] = calloc(sgip->ysize * sgip->zsize, - sizeof(long))) == NULL) - { - free(sgip->table); - free(sgip); - return (NULL); - } - - for (i = 1; i < sgip->zsize; i ++) - sgip->table[i] = sgip->table[0] + i * sgip->ysize; - - if ((sgip->length = calloc(sgip->zsize, sizeof(long *))) == NULL) - { - free(sgip->table); - free(sgip); - return (NULL); - } - - if ((sgip->length[0] = calloc(sgip->ysize * sgip->zsize, - sizeof(long))) == NULL) - { - free(sgip->length); - free(sgip->table); - free(sgip); - return (NULL); - } - - for (i = 1; i < sgip->zsize; i ++) - sgip->length[i] = sgip->length[0] + i * sgip->ysize; - break; - } - break; - - default : - free(sgip); - return (NULL); - } - - return (sgip); -} - - -/* - * 'sgiPutRow()' - Put a row of image data to a file. - */ - -int /* O - 0 on success, -1 on error */ -sgiPutRow(sgi_t *sgip, /* I - SGI image */ - unsigned short *row, /* I - Row to write */ - int y, /* I - Line to write */ - int z) /* I - Channel to write */ -{ - int x; /* X coordinate */ - long offset; /* File offset */ - - - if (sgip == NULL || - row == NULL || - y < 0 || y >= sgip->ysize || - z < 0 || z >= sgip->zsize) - return (-1); - - switch (sgip->comp) - { - case SGI_COMP_NONE : - /* - * Seek to the image row - optimize buffering by only seeking if - * necessary... - */ - - offset = 512 + (y + z * sgip->ysize) * sgip->xsize * sgip->bpp; - if (offset != ftell(sgip->file)) - fseek(sgip->file, offset, SEEK_SET); - - if (sgip->bpp == 1) - { - for (x = sgip->xsize; x > 0; x --, row ++) - putc(*row, sgip->file); - } - else - { - for (x = sgip->xsize; x > 0; x --, row ++) - putshort(*row, sgip->file); - } - break; - - case SGI_COMP_ARLE : - if (sgip->table[z][y] != 0) - return (-1); - - /* - * First check the last row written... - */ - - if (sgip->arle_offset > 0) - { - for (x = 0; x < sgip->xsize; x ++) - if (row[x] != sgip->arle_row[x]) - break; - - if (x == sgip->xsize) - { - sgip->table[z][y] = sgip->arle_offset; - sgip->length[z][y] = sgip->arle_length; - return (0); - } - } - - /* - * If that didn't match, search all the previous rows... - */ - - fseek(sgip->file, sgip->firstrow, SEEK_SET); - - if (sgip->bpp == 1) - { - for (;;) - { - sgip->arle_offset = ftell(sgip->file); - if ((sgip->arle_length = read_rle8(sgip->file, sgip->arle_row, sgip->xsize)) < 0) - { - x = 0; - break; - } - - if (memcmp(row, sgip->arle_row, sgip->xsize * sizeof(unsigned short)) == 0) - { - x = sgip->xsize; - break; - } - } - } - else - { - for (;;) - { - sgip->arle_offset = ftell(sgip->file); - if ((sgip->arle_length = read_rle16(sgip->file, sgip->arle_row, sgip->xsize)) < 0) - { - x = 0; - break; - } - - if (memcmp(row, sgip->arle_row, sgip->xsize * sizeof(unsigned short)) == 0) - { - x = sgip->xsize; - break; - } - } - } - - if (x == sgip->xsize) - { - sgip->table[z][y] = sgip->arle_offset; - sgip->length[z][y] = sgip->arle_length; - return (0); - } - else - fseek(sgip->file, 0, SEEK_END); /* Clear EOF */ - - case SGI_COMP_RLE : - if (sgip->table[z][y] != 0) - return (-1); - - offset = sgip->table[z][y] = sgip->nextrow; - - if (offset != ftell(sgip->file)) - fseek(sgip->file, offset, SEEK_SET); - - if (sgip->bpp == 1) - x = write_rle8(sgip->file, row, sgip->xsize); - else - x = write_rle16(sgip->file, row, sgip->xsize); - - if (sgip->comp == SGI_COMP_ARLE) - { - sgip->arle_offset = offset; - sgip->arle_length = x; - memcpy(sgip->arle_row, row, sgip->xsize * sizeof(unsigned short)); - } - - sgip->nextrow = ftell(sgip->file); - sgip->length[z][y] = x; - - return (x); - } - - return (0); -} - - -/* - * 'getlong()' - Get a 32-bit big-endian integer. - */ - -static int /* O - Long value */ -getlong(FILE *fp) /* I - File to read from */ -{ - unsigned char b[4]; /* Bytes from file */ - - - fread(b, 4, 1, fp); - return ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]); -} - - -/* - * 'getshort()' - Get a 16-bit big-endian integer. - */ - -static int /* O - Short value */ -getshort(FILE *fp) /* I - File to read from */ -{ - unsigned char b[2]; /* Bytes from file */ - - - fread(b, 2, 1, fp); - return ((b[0] << 8) | b[1]); -} - - -/* - * 'putlong()' - Put a 32-bit big-endian integer. - */ - -static int /* O - 0 on success, -1 on error */ -putlong(long n, /* I - Long to write */ - FILE *fp) /* I - File to write to */ -{ - if (putc(n >> 24, fp) == EOF) - return (EOF); - if (putc(n >> 16, fp) == EOF) - return (EOF); - if (putc(n >> 8, fp) == EOF) - return (EOF); - if (putc(n, fp) == EOF) - return (EOF); - else - return (0); -} - - -/* - * 'putshort()' - Put a 16-bit big-endian integer. - */ - -static int /* O - 0 on success, -1 on error */ -putshort(unsigned short n, /* I - Short to write */ - FILE *fp) /* I - File to write to */ -{ - if (putc(n >> 8, fp) == EOF) - return (EOF); - if (putc(n, fp) == EOF) - return (EOF); - else - return (0); -} - - -/* - * 'read_rle8()' - Read 8-bit RLE data. - */ - -static int /* O - Value on success, -1 on error */ -read_rle8(FILE *fp, /* I - File to read from */ - unsigned short *row, /* O - Data */ - int xsize) /* I - Width of data in pixels */ -{ - int i, /* Looping var */ - ch, /* Current character */ - count, /* RLE count */ - length; /* Number of bytes read... */ - - - length = 0; - - while (xsize > 0) - { - if ((ch = getc(fp)) == EOF) - return (-1); - length ++; - - count = ch & 127; - if (count == 0) - break; - - if (ch & 128) - { - for (i = 0; i < count; i ++, row ++, xsize --, length ++) - if (xsize > 0) - *row = getc(fp); - } - else - { - ch = getc(fp); - length ++; - for (i = 0; i < count && xsize > 0; i ++, row ++, xsize --) - *row = ch; - } - } - - return (xsize > 0 ? -1 : length); -} - - -/* - * 'read_rle16()' - Read 16-bit RLE data. - */ - -static int /* O - Value on success, -1 on error */ -read_rle16(FILE *fp, /* I - File to read from */ - unsigned short *row, /* O - Data */ - int xsize) /* I - Width of data in pixels */ -{ - int i, /* Looping var */ - ch, /* Current character */ - count, /* RLE count */ - length; /* Number of bytes read... */ - - - length = 0; - - while (xsize > 0) - { - if ((ch = getshort(fp)) == EOF) - return (-1); - length ++; - - count = ch & 127; - if (count == 0) - break; - - if (ch & 128) - { - for (i = 0; i < count; i ++, row ++, xsize --, length ++) - if (xsize > 0) - *row = getshort(fp); - } - else - { - ch = getshort(fp); - length ++; - for (i = 0; i < count && xsize > 0; i ++, row ++, xsize --) - *row = ch; - } - } - - return (xsize > 0 ? -1 : length * 2); -} - - -/* - * 'write_rle8()' - Write 8-bit RLE data. - */ - -static int /* O - Length on success, -1 on error */ -write_rle8(FILE *fp, /* I - File to write to */ - unsigned short *row, /* I - Data */ - int xsize) /* I - Width of data in pixels */ -{ - int length, /* Length in bytes */ - count, /* Number of repeating pixels */ - i, /* Looping var */ - x; /* Current column */ - unsigned short *start, /* Start of current sequence */ - repeat; /* Repeated pixel */ - - - for (x = xsize, length = 0; x > 0;) - { - start = row; - row += 2; - x -= 2; - - while (x > 0 && (row[-2] != row[-1] || row[-1] != row[0])) - { - row ++; - x --; - } - - row -= 2; - x += 2; - - count = row - start; - while (count > 0) - { - i = count > 126 ? 126 : count; - count -= i; - - if (putc(128 | i, fp) == EOF) - return (-1); - length ++; - - while (i > 0) - { - if (putc(*start, fp) == EOF) - return (-1); - start ++; - i --; - length ++; - } - } - - if (x <= 0) - break; - - start = row; - repeat = row[0]; - - row ++; - x --; - - while (x > 0 && *row == repeat) - { - row ++; - x --; - } - - count = row - start; - while (count > 0) - { - i = count > 126 ? 126 : count; - count -= i; - - if (putc(i, fp) == EOF) - return (-1); - length ++; - - if (putc(repeat, fp) == EOF) - return (-1); - length ++; - } - } - - length ++; - - if (putc(0, fp) == EOF) - return (-1); - else - return (length); -} - - -/* - * 'write_rle16()' - Write 16-bit RLE data. - */ - -static int /* O - Length in words */ -write_rle16(FILE *fp, /* I - File to write to */ - unsigned short *row, /* I - Data */ - int xsize) /* I - Width of data in pixels */ -{ - int length, /* Length in words */ - count, /* Number of repeating pixels */ - i, /* Looping var */ - x; /* Current column */ - unsigned short *start, /* Start of current sequence */ - repeat; /* Repeated pixel */ - - - for (x = xsize, length = 0; x > 0;) - { - start = row; - row += 2; - x -= 2; - - while (x > 0 && (row[-2] != row[-1] || row[-1] != row[0])) - { - row ++; - x --; - } - - row -= 2; - x += 2; - - count = row - start; - while (count > 0) - { - i = count > 126 ? 126 : count; - count -= i; - - if (putshort(128 | i, fp) == EOF) - return (-1); - length ++; - - while (i > 0) - { - if (putshort(*start, fp) == EOF) - return (-1); - start ++; - i --; - length ++; - } - } - - if (x <= 0) - break; - - start = row; - repeat = row[0]; - - row ++; - x --; - - while (x > 0 && *row == repeat) - { - row ++; - x --; - } - - count = row - start; - while (count > 0) - { - i = count > 126 ? 126 : count; - count -= i; - - if (putshort(i, fp) == EOF) - return (-1); - length ++; - - if (putshort(repeat, fp) == EOF) - return (-1); - length ++; - } - } - - length ++; - - if (putshort(0, fp) == EOF) - return (-1); - else - return (2 * length); -} - - -/* - * End of "$Id: image-sgilib.c 7221 2008-01-16 22:20:08Z mike $". - */ diff --git a/filter/image-sun.c b/filter/image-sun.c deleted file mode 100644 index 8e6c1d3d9..000000000 --- a/filter/image-sun.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * "$Id: image-sun.c 7223 2008-01-16 23:41:19Z mike $" - * - * Sun Raster image file routines for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * _cupsImageReadSunRaster() - Read a SunRaster image file. - * read_unsigned() - Read a 32-bit unsigned integer. - */ - -/* - * Include necessary headers... - */ - -#include "image-private.h" - - -#define RAS_MAGIC 0x59a66a95 - - /* Sun supported ras_type's */ -#define RT_OLD 0 /* Raw pixrect image in 68000 byte order */ -#define RT_STANDARD 1 /* Raw pixrect image in 68000 byte order */ -#define RT_BYTE_ENCODED 2 /* Run-length compression of bytes */ -#define RT_FORMAT_RGB 3 /* XRGB or RGB instead of XBGR or BGR */ -#define RT_EXPERIMENTAL 0xffff /* Reserved for testing */ - - /* Sun registered ras_maptype's */ -#define RMT_RAW 2 - /* Sun supported ras_maptype's */ -#define RMT_NONE 0 /* ras_maplength is expected to be 0 */ -#define RMT_EQUAL_RGB 1 /* red[ras_maplength/3],green[],blue[] */ - -#define RAS_RLE 0x80 - -/* - * NOTES: - * Each line of the image is rounded out to a multiple of 16 bits. - * This corresponds to the rounding convention used by the memory pixrect - * package (/usr/include/pixrect/memvar.h) of the SunWindows system. - * The ras_encoding field (always set to 0 by Sun's supported software) - * was renamed to ras_length in release 2.0. As a result, rasterfiles - * of type 0 generated by the old software claim to have 0 length; for - * compatibility, code reading rasterfiles must be prepared to compute the - * true length from the width, height, and depth fields. - */ - -/* - * Local functions... - */ - -static unsigned read_unsigned(FILE *fp); - - -/* - * '_cupsImageReadSunRaster()' - Read a SunRaster image file. - */ - -int /* O - Read status */ -_cupsImageReadSunRaster( - cups_image_t *img, /* IO - cupsImage */ - FILE *fp, /* I - cupsImage file */ - cups_icspace_t primary, /* I - Primary choice for colorspace */ - cups_icspace_t secondary, /* I - Secondary choice for colorspace */ - int saturation, /* I - Color saturation (%) */ - int hue, /* I - Color hue (degrees) */ - const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */ -{ - int i, x, y, - bpp, /* Bytes per pixel */ - scanwidth, - run_count, - run_value; - cups_ib_t *in, - *out, - *scanline, - *scanptr, - *p, - bit; - unsigned ras_depth, /* depth (1, 8, or 24 bits) of pixel */ - ras_type, /* type of file; see RT_* below */ - ras_maplength; /* length (bytes) of following map */ - unsigned char cmap[3][256]; /* colormap */ - - - /* - * Read the header; we already know that this is a raster file (cupsImageOpen - * checks this) so we don't need to check the magic number again. - */ - - fputs("DEBUG: Reading Sun Raster image...\n", stderr); - - read_unsigned(fp); /* Skip magic */ - img->xsize = read_unsigned(fp); - img->ysize = read_unsigned(fp); - ras_depth = read_unsigned(fp); - /* ras_length */read_unsigned(fp); - ras_type = read_unsigned(fp); - /* ras_maptype*/read_unsigned(fp); - ras_maplength = read_unsigned(fp); - - fprintf(stderr, "DEBUG: ras_width=%d, ras_height=%d, ras_depth=%d, ras_type=%d, ras_maplength=%d\n", - img->xsize, img->ysize, ras_depth, ras_type, ras_maplength); - - if (ras_maplength > 768 || - img->xsize == 0 || img->xsize > CUPS_IMAGE_MAX_WIDTH || - img->ysize == 0 || img->ysize > CUPS_IMAGE_MAX_HEIGHT || - ras_depth == 0 || ras_depth > 32) - { - fputs("DEBUG: Raster image cannot be loaded!\n", stderr); - return (1); - } - - if (ras_maplength > 0) - { - memset(cmap[0], 255, sizeof(cmap[0])); - memset(cmap[1], 0, sizeof(cmap[1])); - memset(cmap[2], 0, sizeof(cmap[2])); - - fread(cmap[0], 1, ras_maplength / 3, fp); - fread(cmap[1], 1, ras_maplength / 3, fp); - fread(cmap[2], 1, ras_maplength / 3, fp); - } - - /* - * Compute the width of each line and allocate memory as needed... - */ - - scanwidth = (img->xsize * ras_depth + 7) / 8; - if (scanwidth & 1) - scanwidth ++; - - if (ras_depth < 24 && ras_maplength == 0) - { - img->colorspace = secondary; - in = malloc(img->xsize + 1); - } - else - { - img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary; - in = malloc(img->xsize * 3 + 1); - } - - if (!in) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - fclose(fp); - return (1); - } - - bpp = cupsImageGetDepth(img); - - if ((out = malloc(img->xsize * bpp)) == NULL) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - fclose(fp); - free(in); - return (1); - } - - if ((scanline = malloc(scanwidth)) == NULL) - { - fputs("DEBUG: Unable to allocate memory!\n", stderr); - fclose(fp); - free(in); - free(out); - return (1); - } - - run_count = 0; - run_value = 0; - - fprintf(stderr, "DEBUG: bpp=%d, scanwidth=%d\n", bpp, scanwidth); - - for (y = 0; y < img->ysize; y ++) - { - if ((ras_depth != 8 && ras_depth != 24) || ras_maplength > 0) - p = scanline; - else - p = in; - - if (ras_type != RT_BYTE_ENCODED) - fread(p, scanwidth, 1, fp); - else - { - for (i = scanwidth; i > 0; i --, p ++) - { - if (run_count > 0) - { - *p = run_value; - run_count --; - } - else - { - run_value = getc(fp); - - if (run_value == RAS_RLE) - { - run_count = getc(fp); - if (run_count == 0) - *p = RAS_RLE; - else - run_value = *p = getc(fp); - } - else - *p = run_value; - } - } - } - - if (ras_depth == 1 && ras_maplength == 0) - { - /* - * 1-bit B&W image... - */ - - for (x = img->xsize, bit = 128, scanptr = scanline, p = in; - x > 0; - x --, p ++) - { - if (*scanptr & bit) - *p = 255; - else - *p = 0; - - if (bit > 1) - bit >>= 1; - else - { - bit = 128; - scanptr ++; - } - } - } - else if (ras_depth == 1) - { - /* - * 1-bit colormapped image... - */ - - for (x = img->xsize, bit = 128, scanptr = scanline, p = in; - x > 0; - x --) - { - if (*scanptr & bit) - { - *p++ = cmap[0][1]; - *p++ = cmap[1][1]; - *p++ = cmap[2][1]; - } - else - { - *p++ = cmap[0][0]; - *p++ = cmap[1][0]; - *p++ = cmap[2][0]; - } - - if (bit > 1) - bit >>= 1; - else - { - bit = 128; - scanptr ++; - } - } - } - else if (ras_depth == 8 && ras_maplength > 0) - { - /* - * 8-bit colormapped image. - */ - - for (x = img->xsize, scanptr = scanline, p = in; - x > 0; - x --) - { - *p++ = cmap[0][*scanptr]; - *p++ = cmap[1][*scanptr]; - *p++ = cmap[2][*scanptr++]; - } - } - else if (ras_depth == 24 && ras_type != RT_FORMAT_RGB) - { - /* - * Convert BGR to RGB... - */ - - for (x = img->xsize, scanptr = scanline, p = in; - x > 0; - x --, scanptr += 3) - { - *p++ = scanptr[2]; - *p++ = scanptr[1]; - *p++ = scanptr[0]; - } - } - - if (ras_depth <= 8 && ras_maplength == 0) - { - if (img->colorspace == CUPS_IMAGE_WHITE) - { - if (lut) - cupsImageLut(in, img->xsize, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, in); - } - else - { - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_RGB : - cupsImageWhiteToRGB(in, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageWhiteToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageWhiteToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageWhiteToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * bpp, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, out); - } - } - else - { - if ((saturation != 100 || hue != 0) && bpp > 1) - cupsImageRGBAdjust(in, img->xsize, saturation, hue); - - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_WHITE : - cupsImageRGBToWhite(in, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageRGBToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageRGBToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageRGBToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * bpp, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, out); - } - } - - free(scanline); - free(in); - free(out); - - fclose(fp); - - return (0); -} - - -/* - * 'read_unsigned()' - Read a 32-bit unsigned integer. - */ - -static unsigned /* O - Integer from file */ -read_unsigned(FILE *fp) /* I - File to read from */ -{ - unsigned v; /* Integer from file */ - - - v = getc(fp); - v = (v << 8) | getc(fp); - v = (v << 8) | getc(fp); - v = (v << 8) | getc(fp); - - return (v); -} - - -/* - * End of "$Id: image-sun.c 7223 2008-01-16 23:41:19Z mike $". - */ diff --git a/filter/image-tiff.c b/filter/image-tiff.c deleted file mode 100644 index 8e09ee5ce..000000000 --- a/filter/image-tiff.c +++ /dev/null @@ -1,1715 +0,0 @@ -/* - * "$Id: image-tiff.c 6649 2007-07-11 21:46:42Z mike $" - * - * TIFF file routines for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * _cupsImageReadTIFF() - Read a TIFF image file. - */ - -/* - * Include necessary headers... - */ - -#include "image-private.h" - -#ifdef HAVE_LIBTIFF -# include /* TIFF image definitions */ -# include -# include - - -/* - * '_cupsImageReadTIFF()' - Read a TIFF image file. - */ - -int /* O - Read status */ -_cupsImageReadTIFF( - cups_image_t *img, /* IO - cupsImage */ - FILE *fp, /* I - cupsImage file */ - cups_icspace_t primary, /* I - Primary choice for colorspace */ - cups_icspace_t secondary, /* I - Secondary choice for colorspace */ - int saturation, /* I - Color saturation (%) */ - int hue, /* I - Color hue (degrees) */ - const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */ -{ - TIFF *tif; /* TIFF file */ - uint32 width, height; /* Size of image */ - uint16 photometric, /* Colorspace */ - compression, /* Type of compression */ - orientation, /* Orientation */ - resunit, /* Units for resolution */ - samples, /* Number of samples/pixel */ - bits, /* Number of bits/pixel */ - inkset, /* Ink set for color separations */ - numinks; /* Number of inks in set */ - float xres, /* Horizontal resolution */ - yres; /* Vertical resolution */ - uint16 *redcmap, /* Red colormap information */ - *greencmap, /* Green colormap information */ - *bluecmap; /* Blue colormap information */ - int c, /* Color index */ - num_colors, /* Number of colors */ - bpp, /* Bytes per pixel */ - x, y, /* Current x & y */ - row, /* Current row in image */ - xstart, ystart, /* Starting x & y */ - xdir, ydir, /* X & y direction */ - xcount, ycount, /* X & Y counters */ - pstep, /* Pixel step (= bpp or -2 * bpp) */ - scanwidth, /* Width of scanline */ - r, g, b, k, /* Red, green, blue, and black values */ - alpha; /* cupsImage includes alpha? */ - cups_ib_t *in, /* Input buffer */ - *out, /* Output buffer */ - *p, /* Pointer into buffer */ - *scanline, /* Scanline buffer */ - *scanptr, /* Pointer into scanline buffer */ - bit, /* Current bit */ - pixel, /* Current pixel */ - zero, /* Zero value (bitmaps) */ - one; /* One value (bitmaps) */ - - - /* - * Open the TIFF file and get the required parameters... - */ - - lseek(fileno(fp), 0, SEEK_SET); /* Work around "feature" in some stdio's */ - - if ((tif = TIFFFdOpen(fileno(fp), "", "r")) == NULL) - { - fputs("DEBUG: TIFFFdOpen() failed!\n", stderr); - fclose(fp); - return (-1); - } - - if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width)) - { - fputs("DEBUG: No image width tag in the file!\n", stderr); - TIFFClose(tif); - fclose(fp); - return (-1); - } - - if (!TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height)) - { - fputs("DEBUG: No image height tag in the file!\n", stderr); - TIFFClose(tif); - fclose(fp); - return (-1); - } - - if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) - { - fputs("DEBUG: No photometric tag in the file!\n", stderr); - TIFFClose(tif); - fclose(fp); - return (-1); - } - - if (!TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression)) - { - fputs("DEBUG: No compression tag in the file!\n", stderr); - TIFFClose(tif); - fclose(fp); - return (-1); - } - - if (!TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samples)) - samples = 1; - - if (!TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bits)) - bits = 1; - - /* - * Get the image orientation... - */ - - if (!TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation)) - orientation = 0; - - /* - * Get the image resolution... - */ - - if (TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres) && - TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres) && - TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &resunit)) - { - if (resunit == RESUNIT_INCH) - { - img->xppi = xres; - img->yppi = yres; - } - else if (resunit == RESUNIT_CENTIMETER) - { - img->xppi = xres * 2.54; - img->yppi = yres * 2.54; - } - else - { - img->xppi = 128; - img->yppi = 128; - } - - if (img->xppi == 0 || img->yppi == 0) - { - fputs("DEBUG: Bad TIFF resolution.\n", stderr); - img->xppi = img->yppi = 128; - } - - fprintf(stderr, "DEBUG: TIFF resolution = %fx%f, units=%d\n", - xres, yres, resunit); - fprintf(stderr, "DEBUG: Stored resolution = %dx%d PPI\n", - img->xppi, img->yppi); - } - - /* - * See if the image has an alpha channel... - */ - - if (samples == 2 || (samples == 4 && photometric == PHOTOMETRIC_RGB)) - alpha = 1; - else - alpha = 0; - - /* - * Check the size of the image... - */ - - if (width == 0 || width > CUPS_IMAGE_MAX_WIDTH || - height == 0 || height > CUPS_IMAGE_MAX_HEIGHT || - (bits != 1 && bits != 2 && bits != 4 && bits != 8) || - samples < 1 || samples > 4) - { - fprintf(stderr, "DEBUG: Bad TIFF dimensions %ux%ux%ux%u!\n", - (unsigned)width, (unsigned)height, (unsigned)bits, - (unsigned)samples); - TIFFClose(tif); - fclose(fp); - return (1); - } - - /* - * Setup the image size and colorspace... - */ - - img->xsize = width; - img->ysize = height; - if (photometric == PHOTOMETRIC_MINISBLACK || - photometric == PHOTOMETRIC_MINISWHITE) - img->colorspace = secondary; - else if (photometric == PHOTOMETRIC_SEPARATED && primary == CUPS_IMAGE_RGB_CMYK) - img->colorspace = CUPS_IMAGE_CMYK; - else if (primary == CUPS_IMAGE_RGB_CMYK) - img->colorspace = CUPS_IMAGE_RGB; - else - img->colorspace = primary; - - fprintf(stderr, "DEBUG: img->colorspace = %d\n", img->colorspace); - - bpp = cupsImageGetDepth(img); - - cupsImageSetMaxTiles(img, 0); - - /* - * Set the X & Y start and direction according to the image orientation... - */ - - switch (orientation) - { - case ORIENTATION_TOPRIGHT : - fputs("DEBUG: orientation = top-right\n", stderr); - break; - case ORIENTATION_RIGHTTOP : - fputs("DEBUG: orientation = right-top\n", stderr); - break; - default : - case ORIENTATION_TOPLEFT : - fputs("DEBUG: orientation = top-left\n", stderr); - break; - case ORIENTATION_LEFTTOP : - fputs("DEBUG: orientation = left-top\n", stderr); - break; - case ORIENTATION_BOTLEFT : - fputs("DEBUG: orientation = bottom-left\n", stderr); - break; - case ORIENTATION_LEFTBOT : - fputs("DEBUG: orientation = left-bottom\n", stderr); - break; - case ORIENTATION_BOTRIGHT : - fputs("DEBUG: orientation = bottom-right\n", stderr); - break; - case ORIENTATION_RIGHTBOT : - fputs("DEBUG: orientation = right-bottom\n", stderr); - break; - } - - switch (orientation) - { - case ORIENTATION_TOPRIGHT : - case ORIENTATION_RIGHTTOP : - xstart = img->xsize - 1; - xdir = -1; - ystart = 0; - ydir = 1; - break; - default : - case ORIENTATION_TOPLEFT : - case ORIENTATION_LEFTTOP : - xstart = 0; - xdir = 1; - ystart = 0; - ydir = 1; - break; - case ORIENTATION_BOTLEFT : - case ORIENTATION_LEFTBOT : - xstart = 0; - xdir = 1; - ystart = img->ysize - 1; - ydir = -1; - break; - case ORIENTATION_BOTRIGHT : - case ORIENTATION_RIGHTBOT : - xstart = img->xsize - 1; - xdir = -1; - ystart = img->ysize - 1; - ydir = -1; - break; - } - - /* - * Allocate a scanline buffer... - */ - - scanwidth = TIFFScanlineSize(tif); - scanline = _TIFFmalloc(scanwidth); - - /* - * Allocate input and output buffers... - */ - - if (orientation < ORIENTATION_LEFTTOP) - { - if (samples > 1 || photometric == PHOTOMETRIC_PALETTE) - pstep = xdir * 3; - else - pstep = xdir; - - in = malloc(img->xsize * 3 + 3); - out = malloc(img->xsize * bpp); - } - else - { - if (samples > 1 || photometric == PHOTOMETRIC_PALETTE) - pstep = ydir * 3; - else - pstep = ydir; - - in = malloc(img->ysize * 3 + 3); - out = malloc(img->ysize * bpp); - } - - /* - * Read the image. This is greatly complicated by the fact that TIFF - * supports literally hundreds of different colorspaces and orientations, - * each which must be handled separately... - */ - - fprintf(stderr, "DEBUG: photometric = %d\n", photometric); - fprintf(stderr, "DEBUG: compression = %d\n", compression); - - switch (photometric) - { - case PHOTOMETRIC_MINISWHITE : - case PHOTOMETRIC_MINISBLACK : - if (photometric == PHOTOMETRIC_MINISWHITE) - { - zero = 255; - one = 0; - } - else - { - zero = 0; - one = 255; - } - - if (orientation < ORIENTATION_LEFTTOP) - { - /* - * Row major order... - */ - - for (y = ystart, ycount = img->ysize, row = 0; - ycount > 0; - ycount --, y += ydir, row ++) - { - if (bits == 1) - { - TIFFReadScanline(tif, scanline, row, 0); - for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 128; - xcount > 0; - xcount --, p += pstep) - { - if (*scanptr & bit) - *p = one; - else - *p = zero; - - if (bit > 1) - bit >>= 1; - else - { - bit = 128; - scanptr ++; - } - } - } - else if (bits == 2) - { - TIFFReadScanline(tif, scanline, row, 0); - for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 0xc0; - xcount > 0; - xcount --, p += pstep) - { - pixel = *scanptr & bit; - while (pixel > 3) - pixel >>= 2; - *p = (255 * pixel / 3) ^ zero; - - if (bit > 3) - bit >>= 2; - else - { - bit = 0xc0; - scanptr ++; - } - } - } - else if (bits == 4) - { - TIFFReadScanline(tif, scanline, row, 0); - for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 0xf0; - xcount > 0; - xcount --, p += pstep) - { - if (bit == 0xf0) - { - *p = (255 * ((*scanptr & 0xf0) >> 4) / 15) ^ zero; - bit = 0x0f; - } - else - { - *p = (255 * (*scanptr & 0x0f) / 15) ^ zero; - bit = 0xf0; - scanptr ++; - } - } - } - else if (xdir < 0 || zero || alpha) - { - TIFFReadScanline(tif, scanline, row, 0); - - if (alpha) - { - if (zero) - { - for (xcount = img->xsize, p = in + xstart, scanptr = scanline; - xcount > 0; - xcount --, p += pstep, scanptr += 2) - *p = (scanptr[1] * (255 - scanptr[0]) + - (255 - scanptr[1]) * 255) / 255; - } - else - { - for (xcount = img->xsize, p = in + xstart, scanptr = scanline; - xcount > 0; - xcount --, p += pstep, scanptr += 2) - *p = (scanptr[1] * scanptr[0] + - (255 - scanptr[1]) * 255) / 255; - } - } - else - { - if (zero) - { - for (xcount = img->xsize, p = in + xstart, scanptr = scanline; - xcount > 0; - xcount --, p += pstep, scanptr ++) - *p = 255 - *scanptr; - } - else - { - for (xcount = img->xsize, p = in + xstart, scanptr = scanline; - xcount > 0; - xcount --, p += pstep, scanptr ++) - *p = *scanptr; - } - } - } - else - TIFFReadScanline(tif, in, row, 0); - - if (img->colorspace == CUPS_IMAGE_WHITE) - { - if (lut) - cupsImageLut(in, img->xsize, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, in); - } - else - { - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_RGB : - cupsImageWhiteToRGB(in, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageWhiteToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageWhiteToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageWhiteToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * bpp, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, out); - } - } - } - else - { - /* - * Column major order... - */ - - for (x = xstart, xcount = img->xsize, row = 0; - xcount > 0; - xcount --, x += xdir, row ++) - { - if (bits == 1) - { - TIFFReadScanline(tif, scanline, row, 0); - for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 128; - ycount > 0; - ycount --, p += ydir) - { - if (*scanptr & bit) - *p = one; - else - *p = zero; - - if (bit > 1) - bit >>= 1; - else - { - bit = 128; - scanptr ++; - } - } - } - else if (bits == 2) - { - TIFFReadScanline(tif, scanline, row, 0); - for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 0xc0; - ycount > 0; - ycount --, p += ydir) - { - pixel = *scanptr & 0xc0; - while (pixel > 3) - pixel >>= 2; - - *p = (255 * pixel / 3) ^ zero; - - if (bit > 3) - bit >>= 2; - else - { - bit = 0xc0; - scanptr ++; - } - } - } - else if (bits == 4) - { - TIFFReadScanline(tif, scanline, row, 0); - for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 0xf0; - ycount > 0; - ycount --, p += ydir) - { - if (bit == 0xf0) - { - *p = (255 * ((*scanptr & 0xf0) >> 4) / 15) ^ zero; - bit = 0x0f; - } - else - { - *p = (255 * (*scanptr & 0x0f) / 15) ^ zero; - bit = 0xf0; - scanptr ++; - } - } - } - else if (ydir < 0 || zero || alpha) - { - TIFFReadScanline(tif, scanline, row, 0); - - if (alpha) - { - if (zero) - { - for (ycount = img->ysize, p = in + ystart, scanptr = scanline; - ycount > 0; - ycount --, p += ydir, scanptr += 2) - *p = (scanptr[1] * (255 - scanptr[0]) + - (255 - scanptr[1]) * 255) / 255; - } - else - { - for (ycount = img->ysize, p = in + ystart, scanptr = scanline; - ycount > 0; - ycount --, p += ydir, scanptr += 2) - *p = (scanptr[1] * scanptr[0] + - (255 - scanptr[1]) * 255) / 255; - } - } - else - { - if (zero) - { - for (ycount = img->ysize, p = in + ystart, scanptr = scanline; - ycount > 0; - ycount --, p += ydir, scanptr ++) - *p = 255 - *scanptr; - } - else - { - for (ycount = img->ysize, p = in + ystart, scanptr = scanline; - ycount > 0; - ycount --, p += ydir, scanptr ++) - *p = *scanptr; - } - } - } - else - TIFFReadScanline(tif, in, row, 0); - - if (img->colorspace == CUPS_IMAGE_WHITE) - { - if (lut) - cupsImageLut(in, img->ysize, lut); - - _cupsImagePutCol(img, x, 0, img->ysize, in); - } - else - { - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_RGB : - cupsImageWhiteToRGB(in, out, img->ysize); - break; - case CUPS_IMAGE_BLACK : - cupsImageWhiteToBlack(in, out, img->ysize); - break; - case CUPS_IMAGE_CMY : - cupsImageWhiteToCMY(in, out, img->ysize); - break; - case CUPS_IMAGE_CMYK : - cupsImageWhiteToCMYK(in, out, img->ysize); - break; - } - - if (lut) - cupsImageLut(out, img->ysize * bpp, lut); - - _cupsImagePutCol(img, x, 0, img->ysize, out); - } - } - } - break; - - case PHOTOMETRIC_PALETTE : - if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &redcmap, &greencmap, &bluecmap)) - { - fputs("DEBUG: No colormap tag in the file!\n", stderr); - fclose(fp); - return (-1); - } - - num_colors = 1 << bits; - - for (c = 0; c < num_colors; c ++) - { - redcmap[c] >>= 8; - greencmap[c] >>= 8; - bluecmap[c] >>= 8; - } - - if (orientation < ORIENTATION_LEFTTOP) - { - /* - * Row major order... - */ - - for (y = ystart, ycount = img->ysize, row = 0; - ycount > 0; - ycount --, y += ydir, row ++) - { - if (bits == 1) - { - TIFFReadScanline(tif, scanline, row, 0); - for (xcount = img->xsize, scanptr = scanline, - p = in + xstart * 3, bit = 128; - xcount > 0; - xcount --, p += pstep) - { - if (*scanptr & bit) - { - p[0] = redcmap[1]; - p[1] = greencmap[1]; - p[2] = bluecmap[1]; - } - else - { - p[0] = redcmap[0]; - p[1] = greencmap[0]; - p[2] = bluecmap[0]; - } - - if (bit > 1) - bit >>= 1; - else - { - bit = 128; - scanptr ++; - } - } - } - else if (bits == 2) - { - TIFFReadScanline(tif, scanline, row, 0); - for (xcount = img->xsize, scanptr = scanline, - p = in + xstart * 3, bit = 0xc0; - xcount > 0; - xcount --, p += pstep) - { - pixel = *scanptr & bit; - while (pixel > 3) - pixel >>= 2; - - p[0] = redcmap[pixel]; - p[1] = greencmap[pixel]; - p[2] = bluecmap[pixel]; - - if (bit > 3) - bit >>= 2; - else - { - bit = 0xc0; - scanptr ++; - } - } - } - else if (bits == 4) - { - TIFFReadScanline(tif, scanline, row, 0); - for (xcount = img->xsize, scanptr = scanline, - p = in + 3 * xstart, bit = 0xf0; - xcount > 0; - xcount --, p += pstep) - { - if (bit == 0xf0) - { - pixel = (*scanptr & 0xf0) >> 4; - p[0] = redcmap[pixel]; - p[1] = greencmap[pixel]; - p[2] = bluecmap[pixel]; - bit = 0x0f; - } - else - { - pixel = *scanptr++ & 0x0f; - p[0] = redcmap[pixel]; - p[1] = greencmap[pixel]; - p[2] = bluecmap[pixel]; - bit = 0xf0; - } - } - } - else - { - TIFFReadScanline(tif, scanline, row, 0); - - for (xcount = img->xsize, p = in + 3 * xstart, scanptr = scanline; - xcount > 0; - xcount --, p += pstep) - { - p[0] = redcmap[*scanptr]; - p[1] = greencmap[*scanptr]; - p[2] = bluecmap[*scanptr++]; - } - } - - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_WHITE : - cupsImageRGBToWhite(in, out, img->xsize); - break; - case CUPS_IMAGE_RGB : - cupsImageRGBToRGB(in, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageRGBToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageRGBToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageRGBToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * bpp, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, out); - } - } - else - { - /* - * Column major order... - */ - - for (x = xstart, xcount = img->xsize, row = 0; - xcount > 0; - xcount --, x += xdir, row ++) - { - if (bits == 1) - { - TIFFReadScanline(tif, scanline, row, 0); - for (ycount = img->ysize, scanptr = scanline, - p = in + 3 * ystart, bit = 128; - ycount > 0; - ycount --, p += ydir) - { - if (*scanptr & bit) - { - p[0] = redcmap[1]; - p[1] = greencmap[1]; - p[2] = bluecmap[1]; - } - else - { - p[0] = redcmap[0]; - p[1] = greencmap[0]; - p[2] = bluecmap[0]; - } - - if (bit > 1) - bit >>= 1; - else - { - bit = 128; - scanptr ++; - } - } - } - else if (bits == 2) - { - TIFFReadScanline(tif, scanline, row, 0); - for (ycount = img->ysize, scanptr = scanline, - p = in + 3 * ystart, bit = 0xc0; - ycount > 0; - ycount --, p += ydir) - { - pixel = *scanptr & 0xc0; - while (pixel > 3) - pixel >>= 2; - - p[0] = redcmap[pixel]; - p[1] = greencmap[pixel]; - p[2] = bluecmap[pixel]; - - if (bit > 3) - bit >>= 2; - else - { - bit = 0xc0; - scanptr ++; - } - } - } - else if (bits == 4) - { - TIFFReadScanline(tif, scanline, row, 0); - for (ycount = img->ysize, scanptr = scanline, - p = in + 3 * ystart, bit = 0xf0; - ycount > 0; - ycount --, p += ydir) - { - if (bit == 0xf0) - { - pixel = (*scanptr & 0xf0) >> 4; - p[0] = redcmap[pixel]; - p[1] = greencmap[pixel]; - p[2] = bluecmap[pixel]; - bit = 0x0f; - } - else - { - pixel = *scanptr++ & 0x0f; - p[0] = redcmap[pixel]; - p[1] = greencmap[pixel]; - p[2] = bluecmap[pixel]; - bit = 0xf0; - } - } - } - else - { - TIFFReadScanline(tif, scanline, row, 0); - - for (ycount = img->ysize, p = in + 3 * ystart, scanptr = scanline; - ycount > 0; - ycount --, p += ydir) - { - p[0] = redcmap[*scanptr]; - p[1] = greencmap[*scanptr]; - p[2] = bluecmap[*scanptr++]; - } - } - - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_WHITE : - cupsImageRGBToWhite(in, out, img->ysize); - break; - case CUPS_IMAGE_RGB : - cupsImageRGBToRGB(in, out, img->ysize); - break; - case CUPS_IMAGE_BLACK : - cupsImageRGBToBlack(in, out, img->ysize); - break; - case CUPS_IMAGE_CMY : - cupsImageRGBToCMY(in, out, img->ysize); - break; - case CUPS_IMAGE_CMYK : - cupsImageRGBToCMYK(in, out, img->ysize); - break; - } - - if (lut) - cupsImageLut(out, img->ysize * bpp, lut); - - _cupsImagePutCol(img, x, 0, img->ysize, out); - } - } - break; - - case PHOTOMETRIC_RGB : - if (orientation < ORIENTATION_LEFTTOP) - { - /* - * Row major order... - */ - - for (y = ystart, ycount = img->ysize, row = 0; - ycount > 0; - ycount --, y += ydir, row ++) - { - if (bits == 1) - { - TIFFReadScanline(tif, scanline, row, 0); - for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0; - xcount > 0; - xcount --, p += pstep) - { - if (*scanptr & bit & 0x88) - p[0] = 255; - else - p[0] = 0; - - if (*scanptr & bit & 0x44) - p[1] = 255; - else - p[1] = 0; - - if (*scanptr & bit & 0x22) - p[2] = 255; - else - p[2] = 0; - - if (bit == 0xf0) - bit = 0x0f; - else - { - bit = 0xf0; - scanptr ++; - } - } - } - else if (bits == 2) - { - TIFFReadScanline(tif, scanline, row, 0); - for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3; - xcount > 0; - xcount --, p += pstep, scanptr ++) - { - pixel = *scanptr >> 2; - p[0] = 255 * (pixel & 3) / 3; - pixel >>= 2; - p[1] = 255 * (pixel & 3) / 3; - pixel >>= 2; - p[2] = 255 * (pixel & 3) / 3; - } - } - else if (bits == 4) - { - TIFFReadScanline(tif, scanline, row, 0); - for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3; - xcount > 0; - xcount -= 2, p += 2 * pstep, scanptr += 3) - { - pixel = scanptr[0]; - p[1] = 255 * (pixel & 15) / 15; - pixel >>= 4; - p[0] = 255 * (pixel & 15) / 15; - pixel = scanptr[1]; - p[2] = 255 * ((pixel >> 4) & 15) / 15; - - if (xcount > 1) - { - p[pstep + 0] = 255 * (pixel & 15) / 15; - pixel = scanptr[2]; - p[pstep + 2] = 255 * (pixel & 15) / 15; - pixel >>= 4; - p[pstep + 1] = 255 * (pixel & 15) / 15; - } - } - } - else if (xdir < 0 || alpha) - { - TIFFReadScanline(tif, scanline, row, 0); - - if (alpha) - { - for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline; - xcount > 0; - xcount --, p += pstep, scanptr += 4) - { - p[0] = (scanptr[0] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; - p[1] = (scanptr[1] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; - p[2] = (scanptr[2] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; - } - } - else - { - for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline; - xcount > 0; - xcount --, p += pstep, scanptr += 3) - { - p[0] = scanptr[0]; - p[1] = scanptr[1]; - p[2] = scanptr[2]; - } - } - } - else - TIFFReadScanline(tif, in, row, 0); - - if ((saturation != 100 || hue != 0) && bpp > 1) - cupsImageRGBAdjust(in, img->xsize, saturation, hue); - - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_WHITE : - cupsImageRGBToWhite(in, out, img->xsize); - break; - case CUPS_IMAGE_RGB : - cupsImageRGBToRGB(in, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageRGBToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageRGBToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageRGBToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * bpp, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, out); - } - } - else - { - /* - * Column major order... - */ - - for (x = xstart, xcount = img->xsize, row = 0; - xcount > 0; - xcount --, x += xdir, row ++) - { - if (bits == 1) - { - TIFFReadScanline(tif, scanline, row, 0); - for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3, bit = 0xf0; - ycount > 0; - ycount --, p += pstep) - { - if (*scanptr & bit & 0x88) - p[0] = 255; - else - p[0] = 0; - - if (*scanptr & bit & 0x44) - p[1] = 255; - else - p[1] = 0; - - if (*scanptr & bit & 0x22) - p[2] = 255; - else - p[2] = 0; - - if (bit == 0xf0) - bit = 0x0f; - else - { - bit = 0xf0; - scanptr ++; - } - } - } - else if (bits == 2) - { - TIFFReadScanline(tif, scanline, row, 0); - for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3; - ycount > 0; - ycount --, p += pstep, scanptr ++) - { - pixel = *scanptr >> 2; - p[0] = 255 * (pixel & 3) / 3; - pixel >>= 2; - p[1] = 255 * (pixel & 3) / 3; - pixel >>= 2; - p[2] = 255 * (pixel & 3) / 3; - } - } - else if (bits == 4) - { - TIFFReadScanline(tif, scanline, row, 0); - for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3; - ycount > 0; - ycount -= 2, p += 2 * pstep, scanptr += 3) - { - pixel = scanptr[0]; - p[1] = 255 * (pixel & 15) / 15; - pixel >>= 4; - p[0] = 255 * (pixel & 15) / 15; - pixel = scanptr[1]; - p[2] = 255 * ((pixel >> 4) & 15) / 15; - - if (ycount > 1) - { - p[pstep + 0] = 255 * (pixel & 15) / 15; - pixel = scanptr[2]; - p[pstep + 2] = 255 * (pixel & 15) / 15; - pixel >>= 4; - p[pstep + 1] = 255 * (pixel & 15) / 15; - } - } - } - else if (ydir < 0 || alpha) - { - TIFFReadScanline(tif, scanline, row, 0); - - if (alpha) - { - for (ycount = img->ysize, p = in + ystart * 3, scanptr = scanline; - ycount > 0; - ycount --, p += pstep, scanptr += 4) - { - p[0] = (scanptr[0] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; - p[1] = (scanptr[1] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; - p[2] = (scanptr[2] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; - } - } - else - { - for (ycount = img->ysize, p = in + ystart * 3, scanptr = scanline; - ycount > 0; - ycount --, p += pstep, scanptr += 3) - { - p[0] = scanptr[0]; - p[1] = scanptr[1]; - p[2] = scanptr[2]; - } - } - } - else - TIFFReadScanline(tif, in, row, 0); - - if ((saturation != 100 || hue != 0) && bpp > 1) - cupsImageRGBAdjust(in, img->ysize, saturation, hue); - - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_WHITE : - cupsImageRGBToWhite(in, out, img->ysize); - break; - case CUPS_IMAGE_RGB : - cupsImageRGBToRGB(in, out, img->ysize); - break; - case CUPS_IMAGE_BLACK : - cupsImageRGBToBlack(in, out, img->ysize); - break; - case CUPS_IMAGE_CMY : - cupsImageRGBToCMY(in, out, img->ysize); - break; - case CUPS_IMAGE_CMYK : - cupsImageRGBToCMYK(in, out, img->ysize); - break; - } - - if (lut) - cupsImageLut(out, img->ysize * bpp, lut); - - _cupsImagePutCol(img, x, 0, img->ysize, out); - } - } - break; - - case PHOTOMETRIC_SEPARATED : - inkset = INKSET_CMYK; - numinks = 4; - -#ifdef TIFFTAG_NUMBEROFINKS - if (!TIFFGetField(tif, TIFFTAG_INKSET, &inkset) && - !TIFFGetField(tif, TIFFTAG_NUMBEROFINKS, &numinks)) -#else - if (!TIFFGetField(tif, TIFFTAG_INKSET, &inkset)) -#endif /* TIFFTAG_NUMBEROFINKS */ - { - fputs("WARNING: No inkset or number-of-inks tag in the file!\n", stderr); - } - - if (inkset == INKSET_CMYK || numinks == 4) - { - if (orientation < ORIENTATION_LEFTTOP) - { - /* - * Row major order... - */ - - for (y = ystart, ycount = img->ysize, row = 0; - ycount > 0; - ycount --, y += ydir, row ++) - { - if (bits == 1) - { - TIFFReadScanline(tif, scanline, row, 0); - for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0; - xcount > 0; - xcount --, p += pstep) - { - if (*scanptr & bit & 0x11) - { - p[0] = 0; - p[1] = 0; - p[2] = 0; - } - else - { - if (*scanptr & bit & 0x88) - p[0] = 0; - else - p[0] = 255; - - if (*scanptr & bit & 0x44) - p[1] = 0; - else - p[1] = 255; - - if (*scanptr & bit & 0x22) - p[2] = 0; - else - p[2] = 255; - } - - if (bit == 0xf0) - bit = 0x0f; - else - { - bit = 0xf0; - scanptr ++; - } - } - } - else if (bits == 2) - { - TIFFReadScanline(tif, scanline, row, 0); - for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3; - xcount > 0; - xcount --, p += pstep, scanptr ++) - { - pixel = *scanptr; - k = 255 * (pixel & 3) / 3; - if (k == 255) - { - p[0] = 0; - p[1] = 0; - p[2] = 0; - } - else - { - pixel >>= 2; - b = 255 - 255 * (pixel & 3) / 3 - k; - if (b < 0) - p[2] = 0; - else if (b < 256) - p[2] = b; - else - p[2] = 255; - - pixel >>= 2; - g = 255 - 255 * (pixel & 3) / 3 - k; - if (g < 0) - p[1] = 0; - else if (g < 256) - p[1] = g; - else - p[1] = 255; - - pixel >>= 2; - r = 255 - 255 * (pixel & 3) / 3 - k; - if (r < 0) - p[0] = 0; - else if (r < 256) - p[0] = r; - else - p[0] = 255; - } - } - } - else if (bits == 4) - { - TIFFReadScanline(tif, scanline, row, 0); - for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3; - xcount > 0; - xcount --, p += pstep, scanptr += 2) - { - pixel = scanptr[1]; - k = 255 * (pixel & 15) / 15; - if (k == 255) - { - p[0] = 0; - p[1] = 0; - p[2] = 0; - } - else - { - pixel >>= 4; - b = 255 - 255 * (pixel & 15) / 15 - k; - if (b < 0) - p[2] = 0; - else if (b < 256) - p[2] = b; - else - p[2] = 255; - - pixel = scanptr[0]; - g = 255 - 255 * (pixel & 15) / 15 - k; - if (g < 0) - p[1] = 0; - else if (g < 256) - p[1] = g; - else - p[1] = 255; - - pixel >>= 4; - r = 255 - 255 * (pixel & 15) / 15 - k; - if (r < 0) - p[0] = 0; - else if (r < 256) - p[0] = r; - else - p[0] = 255; - } - } - } - else if (img->colorspace == CUPS_IMAGE_CMYK) - { - TIFFReadScanline(tif, scanline, row, 0); - _cupsImagePutRow(img, 0, y, img->xsize, scanline); - } - else - { - TIFFReadScanline(tif, scanline, row, 0); - - for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline; - xcount > 0; - xcount --, p += pstep, scanptr += 4) - { - k = scanptr[3]; - if (k == 255) - { - p[0] = 0; - p[1] = 0; - p[2] = 0; - } - else - { - r = 255 - scanptr[0] - k; - if (r < 0) - p[0] = 0; - else if (r < 256) - p[0] = r; - else - p[0] = 255; - - g = 255 - scanptr[1] - k; - if (g < 0) - p[1] = 0; - else if (g < 256) - p[1] = g; - else - p[1] = 255; - - b = 255 - scanptr[2] - k; - if (b < 0) - p[2] = 0; - else if (b < 256) - p[2] = b; - else - p[2] = 255; - } - } - } - - if ((saturation != 100 || hue != 0) && bpp > 1) - cupsImageRGBAdjust(in, img->xsize, saturation, hue); - - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_WHITE : - cupsImageRGBToWhite(in, out, img->xsize); - break; - case CUPS_IMAGE_RGB : - cupsImageRGBToRGB(in, out, img->xsize); - break; - case CUPS_IMAGE_BLACK : - cupsImageRGBToBlack(in, out, img->xsize); - break; - case CUPS_IMAGE_CMY : - cupsImageRGBToCMY(in, out, img->xsize); - break; - case CUPS_IMAGE_CMYK : - cupsImageRGBToCMYK(in, out, img->xsize); - break; - } - - if (lut) - cupsImageLut(out, img->xsize * 3, lut); - - _cupsImagePutRow(img, 0, y, img->xsize, out); - } - } - else - { - /* - * Column major order... - */ - - for (x = xstart, xcount = img->xsize, row = 0; - xcount > 0; - xcount --, x += xdir, row ++) - { - if (bits == 1) - { - TIFFReadScanline(tif, scanline, row, 0); - for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0; - ycount > 0; - ycount --, p += pstep) - { - if (*scanptr & bit & 0x11) - { - p[0] = 0; - p[1] = 0; - p[2] = 0; - } - else - { - if (*scanptr & bit & 0x88) - p[0] = 0; - else - p[0] = 255; - - if (*scanptr & bit & 0x44) - p[1] = 0; - else - p[1] = 255; - - if (*scanptr & bit & 0x22) - p[2] = 0; - else - p[2] = 255; - } - - if (bit == 0xf0) - bit = 0x0f; - else - { - bit = 0xf0; - scanptr ++; - } - } - } - else if (bits == 2) - { - TIFFReadScanline(tif, scanline, row, 0); - for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3; - ycount > 0; - ycount --, p += pstep, scanptr ++) - { - pixel = *scanptr; - k = 255 * (pixel & 3) / 3; - if (k == 255) - { - p[0] = 0; - p[1] = 0; - p[2] = 0; - } - else - { - pixel >>= 2; - b = 255 - 255 * (pixel & 3) / 3 - k; - if (b < 0) - p[2] = 0; - else if (b < 256) - p[2] = b; - else - p[2] = 255; - - pixel >>= 2; - g = 255 - 255 * (pixel & 3) / 3 - k; - if (g < 0) - p[1] = 0; - else if (g < 256) - p[1] = g; - else - p[1] = 255; - - pixel >>= 2; - r = 255 - 255 * (pixel & 3) / 3 - k; - if (r < 0) - p[0] = 0; - else if (r < 256) - p[0] = r; - else - p[0] = 255; - } - } - } - else if (bits == 4) - { - TIFFReadScanline(tif, scanline, row, 0); - for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3; - ycount > 0; - ycount --, p += pstep, scanptr += 2) - { - pixel = scanptr[1]; - k = 255 * (pixel & 15) / 15; - if (k == 255) - { - p[0] = 0; - p[1] = 0; - p[2] = 0; - } - else - { - pixel >>= 4; - b = 255 - 255 * (pixel & 15) / 15 - k; - if (b < 0) - p[2] = 0; - else if (b < 256) - p[2] = b; - else - p[2] = 255; - - pixel = scanptr[0]; - g = 255 - 255 * (pixel & 15) / 15 - k; - if (g < 0) - p[1] = 0; - else if (g < 256) - p[1] = g; - else - p[1] = 255; - - pixel >>= 4; - r = 255 - 255 * (pixel & 15) / 15 - k; - if (r < 0) - p[0] = 0; - else if (r < 256) - p[0] = r; - else - p[0] = 255; - } - } - } - else if (img->colorspace == CUPS_IMAGE_CMYK) - { - TIFFReadScanline(tif, scanline, row, 0); - _cupsImagePutCol(img, x, 0, img->ysize, scanline); - } - else - { - TIFFReadScanline(tif, scanline, row, 0); - - for (ycount = img->ysize, p = in + xstart * 3, scanptr = scanline; - ycount > 0; - ycount --, p += pstep, scanptr += 4) - { - k = scanptr[3]; - if (k == 255) - { - p[0] = 0; - p[1] = 0; - p[2] = 0; - } - else - { - r = 255 - scanptr[0] - k; - if (r < 0) - p[0] = 0; - else if (r < 256) - p[0] = r; - else - p[0] = 255; - - g = 255 - scanptr[1] - k; - if (g < 0) - p[1] = 0; - else if (g < 256) - p[1] = g; - else - p[1] = 255; - - b = 255 - scanptr[2] - k; - if (b < 0) - p[2] = 0; - else if (b < 256) - p[2] = b; - else - p[2] = 255; - } - } - } - - if ((saturation != 100 || hue != 0) && bpp > 1) - cupsImageRGBAdjust(in, img->ysize, saturation, hue); - - switch (img->colorspace) - { - default : - break; - - case CUPS_IMAGE_WHITE : - cupsImageRGBToWhite(in, out, img->ysize); - break; - case CUPS_IMAGE_RGB : - cupsImageRGBToRGB(in, out, img->ysize); - break; - case CUPS_IMAGE_BLACK : - cupsImageRGBToBlack(in, out, img->ysize); - break; - case CUPS_IMAGE_CMY : - cupsImageRGBToCMY(in, out, img->ysize); - break; - case CUPS_IMAGE_CMYK : - cupsImageRGBToCMYK(in, out, img->ysize); - break; - } - - if (lut) - cupsImageLut(out, img->ysize * bpp, lut); - - _cupsImagePutCol(img, x, 0, img->ysize, out); - } - } - - break; - } - - default : - _TIFFfree(scanline); - free(in); - free(out); - - TIFFClose(tif); - fputs("DEBUG: Unknown TIFF photometric value!\n", stderr); - return (-1); - } - - /* - * Free temporary buffers, close the TIFF file, and return. - */ - - _TIFFfree(scanline); - free(in); - free(out); - - TIFFClose(tif); - return (0); -} -#endif /* HAVE_LIBTIFF */ - - -/* - * End of "$Id: image-tiff.c 6649 2007-07-11 21:46:42Z mike $". - */ diff --git a/filter/image-zoom.c b/filter/image-zoom.c deleted file mode 100644 index c631a5021..000000000 --- a/filter/image-zoom.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * "$Id: image-zoom.c 6649 2007-07-11 21:46:42Z mike $" - * - * cupsImage zoom routines for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2006 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * _cupsImageZoomDelete() - Free a zoom record... - * _cupsImageZoomFill() - Fill a zoom record... - * _cupsImageZoomNew() - Allocate a pixel zoom record... - * zoom_bilinear() - Fill a zoom record with image data utilizing - * bilinear interpolation. - * zoom_nearest() - Fill a zoom record quickly using nearest-neighbor - * sampling. - */ - -/* - * Include necessary headers... - */ - -#include "image-private.h" - - -/* - * Local functions... - */ - -static void zoom_bilinear(cups_izoom_t *z, int iy); -static void zoom_nearest(cups_izoom_t *z, int iy); - - -/* - * '_cupsImageZoomDelete()' - Free a zoom record... - */ - -void -_cupsImageZoomDelete(cups_izoom_t *z) /* I - Zoom record to free */ -{ - free(z->rows[0]); - free(z->rows[1]); - free(z->in); - free(z); -} - - -/* - * '_cupsImageZoomFill()' - Fill a zoom record with image data utilizing bilinear - * interpolation. - */ - -void -_cupsImageZoomFill(cups_izoom_t *z, /* I - Zoom record to fill */ - int iy) /* I - Zoom image row */ -{ - switch (z->type) - { - case CUPS_IZOOM_FAST : - zoom_nearest(z, iy); - break; - - default : - zoom_bilinear(z, iy); - break; - } -} - - -/* - * '_cupsImageZoomNew()' - Allocate a pixel zoom record... - */ - -cups_izoom_t * -_cupsImageZoomNew( - cups_image_t *img, /* I - cupsImage to zoom */ - int xc0, /* I - Upper-lefthand corner */ - int yc0, /* I - ... */ - int xc1, /* I - Lower-righthand corner */ - int yc1, /* I - ... */ - int xsize, /* I - Final width of image */ - int ysize, /* I - Final height of image */ - int rotated, /* I - Non-zero if image is rotated 90 degs */ - cups_iztype_t type) /* I - Zoom type */ -{ - cups_izoom_t *z; /* New zoom record */ - int flip; /* Flip on X axis? */ - - - if (xsize > CUPS_IMAGE_MAX_WIDTH || - ysize > CUPS_IMAGE_MAX_HEIGHT || - (xc1 - xc0) > CUPS_IMAGE_MAX_WIDTH || - (yc1 - yc0) > CUPS_IMAGE_MAX_HEIGHT) - return (NULL); /* Protect against integer overflow */ - - if ((z = (cups_izoom_t *)calloc(1, sizeof(cups_izoom_t))) == NULL) - return (NULL); - - z->img = img; - z->row = 0; - z->depth = cupsImageGetDepth(img); - z->rotated = rotated; - z->type = type; - - if (xsize < 0) - { - flip = 1; - xsize = -xsize; - } - else - { - flip = 0; - } - - if (rotated) - { - z->xorig = xc1; - z->yorig = yc0; - z->width = yc1 - yc0 + 1; - z->height = xc1 - xc0 + 1; - z->xsize = xsize; - z->ysize = ysize; - z->xmod = z->width % z->xsize; - z->xstep = z->width / z->xsize; - z->xincr = 1; - z->ymod = z->height % z->ysize; - z->ystep = z->height / z->ysize; - z->yincr = 1; - z->instep = z->xstep * z->depth; - z->inincr = /* z->xincr * */ z->depth; /* z->xincr is always 1 */ - - if (z->width < img->ysize) - z->xmax = z->width; - else - z->xmax = z->width - 1; - - if (z->height < img->xsize) - z->ymax = z->height; - else - z->ymax = z->height - 1; - } - else - { - z->xorig = xc0; - z->yorig = yc0; - z->width = xc1 - xc0 + 1; - z->height = yc1 - yc0 + 1; - z->xsize = xsize; - z->ysize = ysize; - z->xmod = z->width % z->xsize; - z->xstep = z->width / z->xsize; - z->xincr = 1; - z->ymod = z->height % z->ysize; - z->ystep = z->height / z->ysize; - z->yincr = 1; - z->instep = z->xstep * z->depth; - z->inincr = /* z->xincr * */ z->depth; /* z->xincr is always 1 */ - - if (z->width < img->xsize) - z->xmax = z->width; - else - z->xmax = z->width - 1; - - if (z->height < img->ysize) - z->ymax = z->height; - else - z->ymax = z->height - 1; - } - - if (flip) - { - z->instep = -z->instep; - z->inincr = -z->inincr; - } - - if ((z->rows[0] = (cups_ib_t *)malloc(z->xsize * z->depth)) == NULL) - { - free(z); - return (NULL); - } - - if ((z->rows[1] = (cups_ib_t *)malloc(z->xsize * z->depth)) == NULL) - { - free(z->rows[0]); - free(z); - return (NULL); - } - - if ((z->in = (cups_ib_t *)malloc(z->width * z->depth)) == NULL) - { - free(z->rows[0]); - free(z->rows[1]); - free(z); - return (NULL); - } - - return (z); -} - - -/* - * 'zoom_bilinear()' - Fill a zoom record with image data utilizing bilinear - * interpolation. - */ - -static void -zoom_bilinear(cups_izoom_t *z, /* I - Zoom record to fill */ - int iy) /* I - Zoom image row */ -{ - cups_ib_t *r, /* Row pointer */ - *inptr; /* Pixel pointer */ - int xerr0, /* X error counter */ - xerr1; /* ... */ - int ix, - x, - count, - z_depth, - z_xstep, - z_xincr, - z_instep, - z_inincr, - z_xmax, - z_xmod, - z_xsize; - - - if (iy > z->ymax) - iy = z->ymax; - - z->row ^= 1; - - z_depth = z->depth; - z_xsize = z->xsize; - z_xmax = z->xmax; - z_xmod = z->xmod; - z_xstep = z->xstep; - z_xincr = z->xincr; - z_instep = z->instep; - z_inincr = z->inincr; - - if (z->rotated) - cupsImageGetCol(z->img, z->xorig - iy, z->yorig, z->width, z->in); - else - cupsImageGetRow(z->img, z->xorig, z->yorig + iy, z->width, z->in); - - if (z_inincr < 0) - inptr = z->in + (z->width - 1) * z_depth; - else - inptr = z->in; - - for (x = z_xsize, xerr0 = z_xsize, xerr1 = 0, ix = 0, r = z->rows[z->row]; - x > 0; - x --) - { - if (ix < z_xmax) - { - for (count = 0; count < z_depth; count ++) - *r++ = (inptr[count] * xerr0 + inptr[z_depth + count] * xerr1) / z_xsize; - } - else - { - for (count = 0; count < z_depth; count ++) - *r++ = inptr[count]; - } - - ix += z_xstep; - inptr += z_instep; - xerr0 -= z_xmod; - xerr1 += z_xmod; - - if (xerr0 <= 0) - { - xerr0 += z_xsize; - xerr1 -= z_xsize; - ix += z_xincr; - inptr += z_inincr; - } - } -} - - -/* - * 'zoom_nearest()' - Fill a zoom record quickly using nearest-neighbor - * sampling. - */ - -static void -zoom_nearest(cups_izoom_t *z, /* I - Zoom record to fill */ - int iy) /* I - Zoom image row */ -{ - cups_ib_t *r, /* Row pointer */ - *inptr; /* Pixel pointer */ - int xerr0; /* X error counter */ - int ix, - x, - count, - z_depth, - z_xstep, - z_xincr, - z_instep, - z_inincr, - z_xmod, - z_xsize; - - - if (iy > z->ymax) - iy = z->ymax; - - z->row ^= 1; - - z_depth = z->depth; - z_xsize = z->xsize; - z_xmod = z->xmod; - z_xstep = z->xstep; - z_xincr = z->xincr; - z_instep = z->instep; - z_inincr = z->inincr; - - if (z->rotated) - cupsImageGetCol(z->img, z->xorig - iy, z->yorig, z->width, z->in); - else - cupsImageGetRow(z->img, z->xorig, z->yorig + iy, z->width, z->in); - - if (z_inincr < 0) - inptr = z->in + (z->width - 1) * z_depth; - else - inptr = z->in; - - for (x = z_xsize, xerr0 = z_xsize, ix = 0, r = z->rows[z->row]; - x > 0; - x --) - { - for (count = 0; count < z_depth; count ++) - *r++ = inptr[count]; - - ix += z_xstep; - inptr += z_instep; - xerr0 -= z_xmod; - - if (xerr0 <= 0) - { - xerr0 += z_xsize; - ix += z_xincr; - inptr += z_inincr; - } - } -} - - -/* - * End of "$Id: image-zoom.c 6649 2007-07-11 21:46:42Z mike $". - */ diff --git a/filter/image.c b/filter/image.c deleted file mode 100644 index b00275c26..000000000 --- a/filter/image.c +++ /dev/null @@ -1,813 +0,0 @@ -/* - * "$Id: image.c 7473 2008-04-21 17:51:58Z mike $" - * - * Base image support for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * cupsImageClose() - Close an image file. - * cupsImageGetCol() - Get a column of pixels from an image. - * cupsImageGetColorSpace() - Get the image colorspace. - * cupsImageGetDepth() - Get the number of bytes per pixel. - * cupsImageGetHeight() - Get the height of an image. - * cupsImageGetRow() - Get a row of pixels from an image. - * cupsImageGetWidth() - Get the width of an image. - * cupsImageGetXPPI() - Get the horizontal resolution of an image. - * cupsImageGetYPPI() - Get the vertical resolution of an image. - * cupsImageOpen() - Open an image file and read it into memory. - * _cupsImagePutCol() - Put a column of pixels to an image. - * _cupsImagePutRow() - Put a row of pixels to an image. - * cupsImageSetMaxTiles() - Set the maximum number of tiles to cache. - * flush_tile() - Flush the least-recently-used tile in the cache. - * get_tile() - Get a cached tile. - */ - -/* - * Include necessary headers... - */ - -#include "image-private.h" - - -/* - * Local functions... - */ - -static void flush_tile(cups_image_t *img); -static cups_ib_t *get_tile(cups_image_t *img, int x, int y); - - -/* - * 'cupsImageClose()' - Close an image file. - */ - -void -cupsImageClose(cups_image_t *img) /* I - Image to close */ -{ - cups_ic_t *current, /* Current cached tile */ - *next; /* Next cached tile */ - - - /* - * Wipe the tile cache file (if any)... - */ - - if (img->cachefile >= 0) - { - DEBUG_printf(("Closing/removing swap file \"%s\"...\n", img->cachename)); - - close(img->cachefile); - unlink(img->cachename); - } - - /* - * Free the image cache... - */ - - DEBUG_puts("Freeing memory..."); - - for (current = img->first, next = NULL; current != NULL; current = next) - { - DEBUG_printf(("Freeing cache (%p, next = %p)...\n", current, next)); - - next = current->next; - free(current); - } - - /* - * Free the rest of memory... - */ - - if (img->tiles != NULL) - { - DEBUG_printf(("Freeing tiles (%p)...\n", img->tiles[0])); - - free(img->tiles[0]); - - DEBUG_printf(("Freeing tile pointers (%p)...\n", img->tiles)); - - free(img->tiles); - } - - free(img); -} - - -/* - * 'cupsImageGetCol()' - Get a column of pixels from an image. - */ - -int /* O - -1 on error, 0 on success */ -cupsImageGetCol(cups_image_t *img, /* I - Image */ - int x, /* I - Column */ - int y, /* I - Start row */ - int height, /* I - Column height */ - cups_ib_t *pixels) /* O - Pixel data */ -{ - int bpp, /* Bytes per pixel */ - twidth, /* Tile width */ - count; /* Number of pixels to get */ - const cups_ib_t *ib; /* Pointer into tile */ - - - if (img == NULL || x < 0 || x >= img->xsize || y >= img->ysize) - return (-1); - - if (y < 0) - { - height += y; - y = 0; - } - - if ((y + height) > img->ysize) - height = img->ysize - y; - - if (height < 1) - return (-1); - - bpp = cupsImageGetDepth(img); - twidth = bpp * (CUPS_TILE_SIZE - 1); - - while (height > 0) - { - ib = get_tile(img, x, y); - - if (ib == NULL) - return (-1); - - count = CUPS_TILE_SIZE - (y & (CUPS_TILE_SIZE - 1)); - if (count > height) - count = height; - - y += count; - height -= count; - - for (; count > 0; count --, ib += twidth) - switch (bpp) - { - case 4 : - *pixels++ = *ib++; - case 3 : - *pixels++ = *ib++; - *pixels++ = *ib++; - case 1 : - *pixels++ = *ib++; - break; - } - } - - return (0); -} - - -/* - * 'cupsImageGetColorSpace()' - Get the image colorspace. - */ - -cups_icspace_t /* O - Colorspace */ -cupsImageGetColorSpace( - cups_image_t *img) /* I - Image */ -{ - return (img->colorspace); -} - - -/* - * 'cupsImageGetDepth()' - Get the number of bytes per pixel. - */ - -int /* O - Bytes per pixel */ -cupsImageGetDepth(cups_image_t *img) /* I - Image */ -{ - return (abs(img->colorspace)); -} - - -/* - * 'cupsImageGetHeight()' - Get the height of an image. - */ - -unsigned /* O - Height in pixels */ -cupsImageGetHeight(cups_image_t *img) /* I - Image */ -{ - return (img->ysize); -} - - -/* - * 'cupsImageGetRow()' - Get a row of pixels from an image. - */ - -int /* O - -1 on error, 0 on success */ -cupsImageGetRow(cups_image_t *img, /* I - Image */ - int x, /* I - Start column */ - int y, /* I - Row */ - int width, /* I - Width of row */ - cups_ib_t *pixels) /* O - Pixel data */ -{ - int bpp, /* Bytes per pixel */ - count; /* Number of pixels to get */ - const cups_ib_t *ib; /* Pointer to pixels */ - - - if (img == NULL || y < 0 || y >= img->ysize || x >= img->xsize) - return (-1); - - if (x < 0) - { - width += x; - x = 0; - } - - if ((x + width) > img->xsize) - width = img->xsize - x; - - if (width < 1) - return (-1); - - bpp = img->colorspace < 0 ? -img->colorspace : img->colorspace; - - while (width > 0) - { - ib = get_tile(img, x, y); - - if (ib == NULL) - return (-1); - - count = CUPS_TILE_SIZE - (x & (CUPS_TILE_SIZE - 1)); - if (count > width) - count = width; - memcpy(pixels, ib, count * bpp); - pixels += count * bpp; - x += count; - width -= count; - } - - return (0); -} - - -/* - * 'cupsImageGetWidth()' - Get the width of an image. - */ - -unsigned /* O - Width in pixels */ -cupsImageGetWidth(cups_image_t *img) /* I - Image */ -{ - return (img->xsize); -} - - -/* - * 'cupsImageGetXPPI()' - Get the horizontal resolution of an image. - */ - -unsigned /* O - Horizontal PPI */ -cupsImageGetXPPI(cups_image_t *img) /* I - Image */ -{ - return (img->xppi); -} - - -/* - * 'cupsImageGetYPPI()' - Get the vertical resolution of an image. - */ - -unsigned /* O - Vertical PPI */ -cupsImageGetYPPI(cups_image_t *img) /* I - Image */ -{ - return (img->yppi); -} - - -/* - * 'cupsImageOpen()' - Open an image file and read it into memory. - */ - -cups_image_t * /* O - New image */ -cupsImageOpen( - const char *filename, /* I - Filename of image */ - cups_icspace_t primary, /* I - Primary colorspace needed */ - cups_icspace_t secondary, /* I - Secondary colorspace if primary no good */ - int saturation, /* I - Color saturation level */ - int hue, /* I - Color hue adjustment */ - const cups_ib_t *lut) /* I - RGB gamma/brightness LUT */ -{ - FILE *fp; /* File pointer */ - unsigned char header[16], /* First 16 bytes of file */ - header2[16]; /* Bytes 2048-2064 (PhotoCD) */ - cups_image_t *img; /* New image buffer */ - int status; /* Status of load... */ - - - DEBUG_printf(("cupsImageOpen(\"%s\", %d, %d, %d, %d, %p)\n", - filename ? filename : "(null)", primary, secondary, - saturation, hue, lut)); - - /* - * Figure out the file type... - */ - - if ((fp = fopen(filename, "r")) == NULL) - return (NULL); - - if (fread(header, 1, sizeof(header), fp) == 0) - { - fclose(fp); - return (NULL); - } - - fseek(fp, 2048, SEEK_SET); - memset(header2, 0, sizeof(header2)); - fread(header2, 1, sizeof(header2), fp); - fseek(fp, 0, SEEK_SET); - - /* - * Allocate memory... - */ - - img = calloc(sizeof(cups_image_t), 1); - - if (img == NULL) - { - fclose(fp); - return (NULL); - } - - /* - * Load the image as appropriate... - */ - - img->cachefile = -1; - img->max_ics = CUPS_TILE_MINIMUM; - img->xppi = 128; - img->yppi = 128; - - if (!memcmp(header, "GIF87a", 6) || !memcmp(header, "GIF89a", 6)) - status = _cupsImageReadGIF(img, fp, primary, secondary, saturation, hue, - lut); - else if (!memcmp(header, "BM", 2)) - status = _cupsImageReadBMP(img, fp, primary, secondary, saturation, hue, - lut); - else if (header[0] == 0x01 && header[1] == 0xda) - status = _cupsImageReadSGI(img, fp, primary, secondary, saturation, hue, - lut); - else if (header[0] == 0x59 && header[1] == 0xa6 && - header[2] == 0x6a && header[3] == 0x95) - status = _cupsImageReadSunRaster(img, fp, primary, secondary, saturation, - hue, lut); - else if (header[0] == 'P' && header[1] >= '1' && header[1] <= '6') - status = _cupsImageReadPNM(img, fp, primary, secondary, saturation, hue, - lut); - else if (!memcmp(header2, "PCD_IPI", 7)) - status = _cupsImageReadPhotoCD(img, fp, primary, secondary, saturation, - hue, lut); - else if (!memcmp(header + 8, "\000\010", 2) || - !memcmp(header + 8, "\000\030", 2)) - status = _cupsImageReadPIX(img, fp, primary, secondary, saturation, hue, - lut); -#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ) - else if (!memcmp(header, "\211PNG", 4)) - status = _cupsImageReadPNG(img, fp, primary, secondary, saturation, hue, - lut); -#endif /* HAVE_LIBPNG && HAVE_LIBZ */ -#ifdef HAVE_LIBJPEG - else if (!memcmp(header, "\377\330\377", 3) && /* Start-of-Image */ - header[3] >= 0xe0 && header[3] <= 0xef) /* APPn */ - status = _cupsImageReadJPEG(img, fp, primary, secondary, saturation, hue, - lut); -#endif /* HAVE_LIBJPEG */ -#ifdef HAVE_LIBTIFF - else if (!memcmp(header, "MM\000\052", 4) || - !memcmp(header, "II\052\000", 4)) - status = _cupsImageReadTIFF(img, fp, primary, secondary, saturation, hue, - lut); -#endif /* HAVE_LIBTIFF */ - else - { - fclose(fp); - status = -1; - } - - if (status) - { - free(img); - return (NULL); - } - else - return (img); -} - - -/* - * '_cupsImagePutCol()' - Put a column of pixels to an image. - */ - -int /* O - -1 on error, 0 on success */ -_cupsImagePutCol( - cups_image_t *img, /* I - Image */ - int x, /* I - Column */ - int y, /* I - Start row */ - int height, /* I - Column height */ - const cups_ib_t *pixels) /* I - Pixels to put */ -{ - int bpp, /* Bytes per pixel */ - twidth, /* Width of tile */ - count; /* Number of pixels to put */ - int tilex, /* Column within tile */ - tiley; /* Row within tile */ - cups_ib_t *ib; /* Pointer to pixels in tile */ - - - if (img == NULL || x < 0 || x >= img->xsize || y >= img->ysize) - return (-1); - - if (y < 0) - { - height += y; - y = 0; - } - - if ((y + height) > img->ysize) - height = img->ysize - y; - - if (height < 1) - return (-1); - - bpp = cupsImageGetDepth(img); - twidth = bpp * (CUPS_TILE_SIZE - 1); - tilex = x / CUPS_TILE_SIZE; - tiley = y / CUPS_TILE_SIZE; - - while (height > 0) - { - ib = get_tile(img, x, y); - - if (ib == NULL) - return (-1); - - img->tiles[tiley][tilex].dirty = 1; - tiley ++; - - count = CUPS_TILE_SIZE - (y & (CUPS_TILE_SIZE - 1)); - if (count > height) - count = height; - - y += count; - height -= count; - - for (; count > 0; count --, ib += twidth) - switch (bpp) - { - case 4 : - *ib++ = *pixels++; - case 3 : - *ib++ = *pixels++; - *ib++ = *pixels++; - case 1 : - *ib++ = *pixels++; - break; - } - } - - return (0); -} - - -/* - * '_cupsImagePutRow()' - Put a row of pixels to an image. - */ - -int /* O - -1 on error, 0 on success */ -_cupsImagePutRow( - cups_image_t *img, /* I - Image */ - int x, /* I - Start column */ - int y, /* I - Row */ - int width, /* I - Row width */ - const cups_ib_t *pixels) /* I - Pixel data */ -{ - int bpp, /* Bytes per pixel */ - count; /* Number of pixels to put */ - int tilex, /* Column within tile */ - tiley; /* Row within tile */ - cups_ib_t *ib; /* Pointer to pixels in tile */ - - - if (img == NULL || y < 0 || y >= img->ysize || x >= img->xsize) - return (-1); - - if (x < 0) - { - width += x; - x = 0; - } - - if ((x + width) > img->xsize) - width = img->xsize - x; - - if (width < 1) - return (-1); - - bpp = img->colorspace < 0 ? -img->colorspace : img->colorspace; - tilex = x / CUPS_TILE_SIZE; - tiley = y / CUPS_TILE_SIZE; - - while (width > 0) - { - ib = get_tile(img, x, y); - - if (ib == NULL) - return (-1); - - img->tiles[tiley][tilex].dirty = 1; - - count = CUPS_TILE_SIZE - (x & (CUPS_TILE_SIZE - 1)); - if (count > width) - count = width; - memcpy(ib, pixels, count * bpp); - pixels += count * bpp; - x += count; - width -= count; - tilex ++; - } - - return (0); -} - - -/* - * 'cupsImageSetMaxTiles()' - Set the maximum number of tiles to cache. - * - * If the "max_tiles" argument is 0 then the maximum number of tiles is - * computed from the image size or the RIP_CACHE environment variable. - */ - -void -cupsImageSetMaxTiles( - cups_image_t *img, /* I - Image to set */ - int max_tiles) /* I - Number of tiles to cache */ -{ - int cache_size, /* Size of tile cache in bytes */ - min_tiles, /* Minimum number of tiles to cache */ - max_size; /* Maximum cache size in bytes */ - char *cache_env, /* Cache size environment variable */ - cache_units[255]; /* Cache size units */ - - - min_tiles = max(CUPS_TILE_MINIMUM, - 1 + max((img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE, - (img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE)); - - if (max_tiles == 0) - max_tiles = ((img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE) * - ((img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE); - - cache_size = max_tiles * CUPS_TILE_SIZE * CUPS_TILE_SIZE * - cupsImageGetDepth(img); - - if ((cache_env = getenv("RIP_MAX_CACHE")) != NULL) - { - switch (sscanf(cache_env, "%d%254s", &max_size, cache_units)) - { - case 0 : - max_size = 32 * 1024 * 1024; - break; - case 1 : - max_size *= 4 * CUPS_TILE_SIZE * CUPS_TILE_SIZE; - break; - case 2 : - if (tolower(cache_units[0] & 255) == 'g') - max_size *= 1024 * 1024 * 1024; - else if (tolower(cache_units[0] & 255) == 'm') - max_size *= 1024 * 1024; - else if (tolower(cache_units[0] & 255) == 'k') - max_size *= 1024; - else if (tolower(cache_units[0] & 255) == 't') - max_size *= 4 * CUPS_TILE_SIZE * CUPS_TILE_SIZE; - break; - } - } - else - max_size = 32 * 1024 * 1024; - - if (cache_size > max_size) - max_tiles = max_size / CUPS_TILE_SIZE / CUPS_TILE_SIZE / - cupsImageGetDepth(img); - - if (max_tiles < min_tiles) - max_tiles = min_tiles; - - img->max_ics = max_tiles; - - DEBUG_printf(("max_ics=%d...\n", img->max_ics)); -} - - -/* - * 'flush_tile()' - Flush the least-recently-used tile in the cache. - */ - -static void -flush_tile(cups_image_t *img) /* I - Image */ -{ - int bpp; /* Bytes per pixel */ - cups_itile_t *tile; /* Pointer to tile */ - - - bpp = cupsImageGetDepth(img); - tile = img->first->tile; - - if (!tile->dirty) - { - tile->ic = NULL; - return; - } - - if (img->cachefile < 0) - { - if ((img->cachefile = cupsTempFd(img->cachename, - sizeof(img->cachename))) < 0) - { - tile->ic = NULL; - tile->dirty = 0; - return; - } - - DEBUG_printf(("Created swap file \"%s\"...\n", img->cachename)); - } - - if (tile->pos >= 0) - { - if (lseek(img->cachefile, tile->pos, SEEK_SET) != tile->pos) - { - tile->ic = NULL; - tile->dirty = 0; - return; - } - } - else - { - if ((tile->pos = lseek(img->cachefile, 0, SEEK_END)) < 0) - { - tile->ic = NULL; - tile->dirty = 0; - return; - } - } - - write(img->cachefile, tile->ic->pixels, bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE); - - tile->ic = NULL; - tile->dirty = 0; -} - - -/* - * 'get_tile()' - Get a cached tile. - */ - -static cups_ib_t * /* O - Pointer to tile or NULL */ -get_tile(cups_image_t *img, /* I - Image */ - int x, /* I - Column in image */ - int y) /* I - Row in image */ -{ - int bpp, /* Bytes per pixel */ - tilex, /* Column within tile */ - tiley, /* Row within tile */ - xtiles, /* Number of tiles horizontally */ - ytiles; /* Number of tiles vertically */ - cups_ic_t *ic; /* Cache pointer */ - cups_itile_t *tile; /* Tile pointer */ - - - if (img->tiles == NULL) - { - xtiles = (img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE; - ytiles = (img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE; - - DEBUG_printf(("Creating tile array (%dx%d)\n", xtiles, ytiles)); - - if ((img->tiles = calloc(sizeof(cups_itile_t *), ytiles)) == NULL) - return (NULL); - - if ((tile = calloc(xtiles * sizeof(cups_itile_t), ytiles)) == NULL) - return (NULL); - - for (tiley = 0; tiley < ytiles; tiley ++) - { - img->tiles[tiley] = tile; - for (tilex = xtiles; tilex > 0; tilex --, tile ++) - tile->pos = -1; - } - } - - bpp = cupsImageGetDepth(img); - tilex = x / CUPS_TILE_SIZE; - tiley = y / CUPS_TILE_SIZE; - tile = img->tiles[tiley] + tilex; - x &= (CUPS_TILE_SIZE - 1); - y &= (CUPS_TILE_SIZE - 1); - - if ((ic = tile->ic) == NULL) - { - if (img->num_ics < img->max_ics) - { - if ((ic = calloc(sizeof(cups_ic_t) + - bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE, 1)) == NULL) - { - if (img->num_ics == 0) - return (NULL); - - flush_tile(img); - ic = img->first; - } - else - { - ic->pixels = ((cups_ib_t *)ic) + sizeof(cups_ic_t); - - img->num_ics ++; - - DEBUG_printf(("Allocated cache tile %d (%p)...\n", img->num_ics, ic)); - } - } - else - { - DEBUG_printf(("Flushing old cache tile (%p)...\n", img->first)); - - flush_tile(img); - ic = img->first; - } - - ic->tile = tile; - tile->ic = ic; - - if (tile->pos >= 0) - { - DEBUG_printf(("Loading cache tile from file position " CUPS_LLFMT "...\n", - CUPS_LLCAST tile->pos)); - - lseek(img->cachefile, tile->pos, SEEK_SET); - read(img->cachefile, ic->pixels, bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE); - } - else - { - DEBUG_puts("Clearing cache tile..."); - - memset(ic->pixels, 0, bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE); - } - } - - if (ic == img->first) - { - if (ic->next != NULL) - ic->next->prev = NULL; - - img->first = ic->next; - ic->next = NULL; - ic->prev = NULL; - } - else if (img->first == NULL) - img->first = ic; - - if (ic != img->last) - { - /* - * Remove the cache entry from the list... - */ - - if (ic->prev != NULL) - ic->prev->next = ic->next; - if (ic->next != NULL) - ic->next->prev = ic->prev; - - /* - * And add it to the end... - */ - - if (img->last != NULL) - img->last->next = ic; - - ic->prev = img->last; - img->last = ic; - } - - ic->next = NULL; - - return (ic->pixels + bpp * (y * CUPS_TILE_SIZE + x)); -} - - -/* - * End of "$Id: image.c 7473 2008-04-21 17:51:58Z mike $". - */ diff --git a/filter/image.h b/filter/image.h deleted file mode 100644 index 142b5499f..000000000 --- a/filter/image.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * "$Id: image.h 7306 2008-02-15 00:52:38Z mike $" - * - * Image library definitions for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2006 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - */ - -#ifndef _CUPS_IMAGE_H_ -# define _CUPS_IMAGE_H_ - -/* - * Include necessary headers... - */ - -# include -# include - -# ifdef __cplusplus -extern "C" { -# endif /* __cplusplus */ - -/* - * Constants... - */ - -typedef enum cups_icspace_e /**** Image colorspaces ****/ -{ - CUPS_IMAGE_CMYK = -4, /* Cyan, magenta, yellow, and black */ - CUPS_IMAGE_CMY = -3, /* Cyan, magenta, and yellow */ - CUPS_IMAGE_BLACK = -1, /* Black */ - CUPS_IMAGE_WHITE = 1, /* White (luminance) */ - CUPS_IMAGE_RGB = 3, /* Red, green, and blue */ - CUPS_IMAGE_RGB_CMYK = 4 /* Use RGB or CMYK */ -} cups_icspace_t; - - -/* - * Types and structures... - */ - -typedef unsigned char cups_ib_t; /**** Image byte ****/ - -struct cups_image_s; -typedef struct cups_image_s cups_image_t; - /**** Image file data ****/ - -struct cups_izoom_s; -typedef struct cups_izoom_s cups_izoom_t; - /**** Image zoom data ****/ - - -/* - * Prototypes... - */ - -extern void cupsImageClose(cups_image_t *img) _CUPS_API_1_2; -extern void cupsImageCMYKToBlack(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; -extern void cupsImageCMYKToCMY(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; -extern void cupsImageCMYKToCMYK(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; -extern void cupsImageCMYKToRGB(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; -extern void cupsImageCMYKToWhite(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; -extern int cupsImageGetCol(cups_image_t *img, int x, int y, - int height, cups_ib_t *pixels) _CUPS_API_1_2; -extern cups_icspace_t cupsImageGetColorSpace(cups_image_t *img) _CUPS_API_1_2; -extern int cupsImageGetDepth(cups_image_t *img) _CUPS_API_1_2; -extern unsigned cupsImageGetHeight(cups_image_t *img) _CUPS_API_1_2; -extern int cupsImageGetRow(cups_image_t *img, int x, int y, - int width, cups_ib_t *pixels) _CUPS_API_1_2; -extern unsigned cupsImageGetWidth(cups_image_t *img) _CUPS_API_1_2; -extern unsigned cupsImageGetXPPI(cups_image_t *img) _CUPS_API_1_2; -extern unsigned cupsImageGetYPPI(cups_image_t *img) _CUPS_API_1_2; -extern void cupsImageLut(cups_ib_t *pixels, int count, - const cups_ib_t *lut) _CUPS_API_1_2; -extern cups_image_t *cupsImageOpen(const char *filename, - cups_icspace_t primary, - cups_icspace_t secondary, - int saturation, int hue, - const cups_ib_t *lut) _CUPS_API_1_2; -extern void cupsImageRGBAdjust(cups_ib_t *pixels, int count, - int saturation, int hue) _CUPS_API_1_2; -extern void cupsImageRGBToBlack(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; -extern void cupsImageRGBToCMY(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; -extern void cupsImageRGBToCMYK(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; -extern void cupsImageRGBToRGB(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; -extern void cupsImageRGBToWhite(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; -extern void cupsImageSetMaxTiles(cups_image_t *img, int max_tiles) _CUPS_API_1_2; -extern void cupsImageSetProfile(float d, float g, - float matrix[3][3]) _CUPS_API_1_2; -extern void cupsImageSetRasterColorSpace(cups_cspace_t cs) _CUPS_API_1_2; -extern void cupsImageWhiteToBlack(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; -extern void cupsImageWhiteToCMY(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; -extern void cupsImageWhiteToCMYK(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; -extern void cupsImageWhiteToRGB(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; -extern void cupsImageWhiteToWhite(const cups_ib_t *in, - cups_ib_t *out, int count) _CUPS_API_1_2; - - -# ifdef __cplusplus -} -# endif /* __cplusplus */ - -#endif /* !_CUPS_IMAGE_H_ */ - -/* - * End of "$Id: image.h 7306 2008-02-15 00:52:38Z mike $". - */ diff --git a/filter/imagetops.c b/filter/imagetops.c deleted file mode 100644 index d8638b25a..000000000 --- a/filter/imagetops.c +++ /dev/null @@ -1,1078 +0,0 @@ -/* - * "$Id: imagetops.c 6649 2007-07-11 21:46:42Z mike $" - * - * Image file to PostScript filter for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * main() - Main entry... - * ps_hex() - Print binary data as a series of hexadecimal numbers. - * ps_ascii85() - Print binary data as a series of base-85 numbers. - */ - -/* - * Include necessary headers... - */ - -#include "common.h" -#include "image.h" -#include -#include -#include - - -/* - * Globals... - */ - -int Flip = 0, /* Flip/mirror pages */ - XPosition = 0, /* Horizontal position on page */ - YPosition = 0, /* Vertical position on page */ - Collate = 0, /* Collate copies? */ - Copies = 1; /* Number of copies */ - - -/* - * Local functions... - */ - -static void ps_hex(cups_ib_t *, int, int); -static void ps_ascii85(cups_ib_t *, int, int); - - -/* - * 'main()' - Main entry... - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments */ - char *argv[]) /* I - Command-line arguments */ -{ - cups_image_t *img; /* Image to print */ - float xprint, /* Printable area */ - yprint, - xinches, /* Total size in inches */ - yinches; - float xsize, /* Total size in points */ - ysize, - xsize2, - ysize2; - float aspect; /* Aspect ratio */ - int xpages, /* # x pages */ - ypages, /* # y pages */ - xpage, /* Current x page */ - ypage, /* Current y page */ - page; /* Current page number */ - int xc0, yc0, /* Corners of the page in image coords */ - xc1, yc1; - cups_ib_t *row; /* Current row */ - int y; /* Current Y coordinate in image */ - int colorspace; /* Output colorspace */ - int out_offset, /* Offset into output buffer */ - out_length; /* Length of output buffer */ - ppd_file_t *ppd; /* PPD file */ - ppd_choice_t *choice; /* PPD option choice */ - int num_options; /* Number of print options */ - cups_option_t *options; /* Print options */ - const char *val; /* Option value */ - int slowcollate; /* Collate copies the slow way */ - float g; /* Gamma correction value */ - float b; /* Brightness factor */ - float zoom; /* Zoom facter */ - int xppi, yppi; /* Pixels-per-inch */ - int hue, sat; /* Hue and saturation adjustment */ - int realcopies, /* Real copies being printed */ - emit_jcl; /* Emit JCL? */ - float left, top; /* Left and top of image */ - char filename[1024]; /* Name of file to print */ - time_t curtime; /* Current time */ - struct tm *curtm; /* Current date */ - char curdate[255]; /* Current date string */ - - - /* - * Make sure status messages are not buffered... - */ - - setbuf(stderr, NULL); - - /* - * Ignore broken pipe signals... - */ - - signal(SIGPIPE, SIG_IGN); - - /* - * Check command-line... - */ - - if (argc < 6 || argc > 7) - { - _cupsLangPrintf(stderr, - _("Usage: %s job-id user title copies options file"), - argv[0]); - return (1); - } - - /* - * Copy stdin as needed... - */ - - if (argc == 6) - { - int fd; /* File to write to */ - char buffer[8192]; /* Buffer to read into */ - int bytes; /* # of bytes to read */ - - - if ((fd = cupsTempFd(filename, sizeof(filename))) < 0) - { - _cupsLangPrintError("ERROR", _("Unable to copy print file")); - return (1); - } - - fprintf(stderr, "DEBUG: imagetops - copying to temp print file \"%s\".\n", - filename); - - while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0) - write(fd, buffer, bytes); - - close(fd); - } - else - strlcpy(filename, argv[6], sizeof(filename)); - - /* - * Process command-line options and write the prolog... - */ - - zoom = 0.0; - xppi = 0; - yppi = 0; - hue = 0; - sat = 100; - g = 1.0; - b = 1.0; - - Copies = atoi(argv[4]); - - options = NULL; - num_options = cupsParseOptions(argv[5], 0, &options); - - ppd = SetCommonOptions(num_options, options, 0); - - if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL) - { - /* - * This IPP attribute is unnecessarily complicated... - * - * single-document, separate-documents-collated-copies, and - * single-document-new-sheet all require collated copies. - * - * separate-documents-uncollated-copies allows for uncollated copies. - */ - - Collate = _cups_strcasecmp(val, "separate-documents-uncollated-copies") != 0; - } - - if ((val = cupsGetOption("Collate", num_options, options)) != NULL && - _cups_strcasecmp(val, "True") == 0) - Collate = 1; - - if ((val = cupsGetOption("gamma", num_options, options)) != NULL) - { - /* - * Get gamma value from 1 to 10000... - */ - - g = atoi(val) * 0.001f; - - if (g < 0.001f) - g = 0.001f; - else if (g > 10.0f) - g = 10.0f; - } - - if ((val = cupsGetOption("brightness", num_options, options)) != NULL) - { - /* - * Get brightness value from 10 to 1000. - */ - - b = atoi(val) * 0.01f; - - if (b < 0.1f) - b = 0.1f; - else if (b > 10.0f) - b = 10.0f; - } - - if ((val = cupsGetOption("scaling", num_options, options)) != NULL) - zoom = atoi(val) * 0.01; - else if ((val = cupsGetOption("fitplot", num_options, options)) != NULL && - !_cups_strcasecmp(val, "true")) - zoom = 1.0; - else if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL && - !_cups_strcasecmp(val, "true")) - zoom = 1.0; - - if ((val = cupsGetOption("ppi", num_options, options)) != NULL) - if (sscanf(val, "%dx%d", &xppi, &yppi) < 2) - yppi = xppi; - - if ((val = cupsGetOption("position", num_options, options)) != NULL) - { - if (_cups_strcasecmp(val, "center") == 0) - { - XPosition = 0; - YPosition = 0; - } - else if (_cups_strcasecmp(val, "top") == 0) - { - XPosition = 0; - YPosition = 1; - } - else if (_cups_strcasecmp(val, "left") == 0) - { - XPosition = -1; - YPosition = 0; - } - else if (_cups_strcasecmp(val, "right") == 0) - { - XPosition = 1; - YPosition = 0; - } - else if (_cups_strcasecmp(val, "top-left") == 0) - { - XPosition = -1; - YPosition = 1; - } - else if (_cups_strcasecmp(val, "top-right") == 0) - { - XPosition = 1; - YPosition = 1; - } - else if (_cups_strcasecmp(val, "bottom") == 0) - { - XPosition = 0; - YPosition = -1; - } - else if (_cups_strcasecmp(val, "bottom-left") == 0) - { - XPosition = -1; - YPosition = -1; - } - else if (_cups_strcasecmp(val, "bottom-right") == 0) - { - XPosition = 1; - YPosition = -1; - } - } - - if ((val = cupsGetOption("saturation", num_options, options)) != NULL) - sat = atoi(val); - - if ((val = cupsGetOption("hue", num_options, options)) != NULL) - hue = atoi(val); - - if ((choice = ppdFindMarkedChoice(ppd, "MirrorPrint")) != NULL) - { - val = choice->choice; - choice->marked = 0; - } - else - val = cupsGetOption("mirror", num_options, options); - - if (val && (!_cups_strcasecmp(val, "true") || !_cups_strcasecmp(val, "on") || - !_cups_strcasecmp(val, "yes"))) - Flip = 1; - - if ((val = cupsGetOption("emit-jcl", num_options, options)) != NULL && - (!_cups_strcasecmp(val, "false") || !_cups_strcasecmp(val, "off") || - !_cups_strcasecmp(val, "no") || !strcmp(val, "0"))) - emit_jcl = 0; - else - emit_jcl = 1; - - /* - * Open the input image to print... - */ - - colorspace = ColorDevice ? CUPS_IMAGE_RGB_CMYK : CUPS_IMAGE_WHITE; - - img = cupsImageOpen(filename, colorspace, CUPS_IMAGE_WHITE, sat, hue, NULL); - - if (argc == 6) - unlink(filename); - - if (img == NULL) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("The print file could not be opened.")); - ppdClose(ppd); - return (1); - } - - colorspace = cupsImageGetColorSpace(img); - - /* - * Scale as necessary... - */ - - if (zoom == 0.0 && xppi == 0) - { - xppi = cupsImageGetXPPI(img); - yppi = cupsImageGetYPPI(img); - } - - if (yppi == 0) - yppi = xppi; - - fprintf(stderr, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n", - xppi, yppi, zoom); - - if (xppi > 0) - { - /* - * Scale the image as neccesary to match the desired pixels-per-inch. - */ - - if (Orientation & 1) - { - xprint = (PageTop - PageBottom) / 72.0; - yprint = (PageRight - PageLeft) / 72.0; - } - else - { - xprint = (PageRight - PageLeft) / 72.0; - yprint = (PageTop - PageBottom) / 72.0; - } - - fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n", - xprint, yprint); - - xinches = (float)cupsImageGetWidth(img) / (float)xppi; - yinches = (float)cupsImageGetHeight(img) / (float)yppi; - - fprintf(stderr, "DEBUG: Image size is %.1f x %.1f inches...\n", - xinches, yinches); - - if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL) - { - xinches = xinches * atoi(val) / 100; - yinches = yinches * atoi(val) / 100; - } - - if (cupsGetOption("orientation-requested", num_options, options) == NULL && - cupsGetOption("landscape", num_options, options) == NULL) - { - /* - * Rotate the image if it will fit landscape but not portrait... - */ - - fputs("DEBUG: Auto orientation...\n", stderr); - - if ((xinches > xprint || yinches > yprint) && - xinches <= yprint && yinches <= xprint) - { - /* - * Rotate the image as needed... - */ - - fputs("DEBUG: Using landscape orientation...\n", stderr); - - Orientation = (Orientation + 1) & 3; - xsize = yprint; - yprint = xprint; - xprint = xsize; - } - } - } - else - { - /* - * Scale percentage of page size... - */ - - xprint = (PageRight - PageLeft) / 72.0; - yprint = (PageTop - PageBottom) / 72.0; - aspect = (float)cupsImageGetYPPI(img) / (float)cupsImageGetXPPI(img); - - fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n", - xprint, yprint); - - fprintf(stderr, "DEBUG: cupsImageGetXPPI(img) = %d, cupsImageGetYPPI(img) = %d, aspect = %f\n", - cupsImageGetXPPI(img), cupsImageGetYPPI(img), aspect); - - xsize = xprint * zoom; - ysize = xsize * cupsImageGetHeight(img) / cupsImageGetWidth(img) / aspect; - - if (ysize > (yprint * zoom)) - { - ysize = yprint * zoom; - xsize = ysize * cupsImageGetWidth(img) * aspect / cupsImageGetHeight(img); - } - - xsize2 = yprint * zoom; - ysize2 = xsize2 * cupsImageGetHeight(img) / cupsImageGetWidth(img) / aspect; - - if (ysize2 > (xprint * zoom)) - { - ysize2 = xprint * zoom; - xsize2 = ysize2 * cupsImageGetWidth(img) * aspect / cupsImageGetHeight(img); - } - - fprintf(stderr, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize, ysize); - fprintf(stderr, "DEBUG: Landscape size is %.2f x %.2f inches\n", xsize2, ysize2); - - if (cupsGetOption("orientation-requested", num_options, options) == NULL && - cupsGetOption("landscape", num_options, options) == NULL) - { - /* - * Choose the rotation with the largest area, but prefer - * portrait if they are equal... - */ - - fputs("DEBUG: Auto orientation...\n", stderr); - - if ((xsize * ysize) < (xsize2 * xsize2)) - { - /* - * Do landscape orientation... - */ - - fputs("DEBUG: Using landscape orientation...\n", stderr); - - Orientation = 1; - xinches = xsize2; - yinches = ysize2; - xprint = (PageTop - PageBottom) / 72.0; - yprint = (PageRight - PageLeft) / 72.0; - } - else - { - /* - * Do portrait orientation... - */ - - fputs("DEBUG: Using portrait orientation...\n", stderr); - - Orientation = 0; - xinches = xsize; - yinches = ysize; - } - } - else if (Orientation & 1) - { - fputs("DEBUG: Using landscape orientation...\n", stderr); - - xinches = xsize2; - yinches = ysize2; - xprint = (PageTop - PageBottom) / 72.0; - yprint = (PageRight - PageLeft) / 72.0; - } - else - { - fputs("DEBUG: Using portrait orientation...\n", stderr); - - xinches = xsize; - yinches = ysize; - xprint = (PageRight - PageLeft) / 72.0; - yprint = (PageTop - PageBottom) / 72.0; - } - } - - /* - * Compute the number of pages to print and the size of the image on each - * page... - */ - - xpages = ceil(xinches / xprint); - ypages = ceil(yinches / yprint); - - xprint = xinches / xpages; - yprint = yinches / ypages; - - fprintf(stderr, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n", - xpages, xprint, ypages, yprint); - - /* - * Update the page size for custom sizes... - */ - - if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL && - _cups_strcasecmp(choice->choice, "Custom") == 0) - { - float width, /* New width in points */ - length; /* New length in points */ - char s[255]; /* New custom page size... */ - - - /* - * Use the correct width and length for the current orientation... - */ - - if (Orientation & 1) - { - width = yprint * 72.0; - length = xprint * 72.0; - } - else - { - width = xprint * 72.0; - length = yprint * 72.0; - } - - /* - * Add margins to page size... - */ - - width += ppd->custom_margins[0] + ppd->custom_margins[2]; - length += ppd->custom_margins[1] + ppd->custom_margins[3]; - - /* - * Enforce minimums... - */ - - if (width < ppd->custom_min[0]) - width = ppd->custom_min[0]; - - if (length < ppd->custom_min[1]) - length = ppd->custom_min[1]; - - fprintf(stderr, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n", - width / 72.0, length / 72.0); - - /* - * Set the new custom size... - */ - - sprintf(s, "Custom.%.0fx%.0f", width, length); - ppdMarkOption(ppd, "PageSize", s); - - /* - * Update page variables... - */ - - PageWidth = width; - PageLength = length; - PageLeft = ppd->custom_margins[0]; - PageRight = width - ppd->custom_margins[2]; - PageBottom = ppd->custom_margins[1]; - PageTop = length - ppd->custom_margins[3]; - } - - /* - * See if we need to collate, and if so how we need to do it... - */ - - if (xpages == 1 && ypages == 1) - Collate = 0; - - slowcollate = Collate && ppdFindOption(ppd, "Collate") == NULL; - - if (Copies > 1 && !slowcollate) - { - realcopies = Copies; - Copies = 1; - } - else - realcopies = 1; - - /* - * Write any "exit server" options that have been selected... - */ - - ppdEmit(ppd, stdout, PPD_ORDER_EXIT); - - /* - * Write any JCL commands that are needed to print PostScript code... - */ - - if (emit_jcl) - ppdEmitJCL(ppd, stdout, atoi(argv[1]), argv[2], argv[3]); - - /* - * Start sending the document with any commands needed... - */ - - curtime = time(NULL); - curtm = localtime(&curtime); - - puts("%!PS-Adobe-3.0"); - printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", PageLeft, PageBottom, - PageRight, PageTop); - printf("%%%%LanguageLevel: %d\n", LanguageLevel); - printf("%%%%Pages: %d\n", xpages * ypages * Copies); - puts("%%DocumentData: Clean7Bit"); - puts("%%DocumentNeededResources: font Helvetica-Bold"); - puts("%%Creator: imagetops/" CUPS_SVERSION); - strftime(curdate, sizeof(curdate), "%c", curtm); - printf("%%%%CreationDate: %s\n", curdate); - WriteTextComment("Title", argv[3]); - WriteTextComment("For", argv[2]); - if (Orientation & 1) - puts("%%Orientation: Landscape"); - else - puts("%%Orientation: Portrait"); - puts("%%EndComments"); - puts("%%BeginProlog"); - - if (ppd != NULL && ppd->patches != NULL) - puts(ppd->patches); - - ppdEmit(ppd, stdout, PPD_ORDER_DOCUMENT); - ppdEmit(ppd, stdout, PPD_ORDER_ANY); - ppdEmit(ppd, stdout, PPD_ORDER_PROLOG); - - if (g != 1.0 || b != 1.0) - printf("{ neg 1 add dup 0 lt { pop 1 } { %.3f exp neg 1 add } " - "ifelse %.3f mul } bind settransfer\n", g, b); - - WriteCommon(); - switch (Orientation) - { - case 0 : - WriteLabelProlog(cupsGetOption("page-label", num_options, options), - PageBottom, PageTop, PageWidth); - break; - - case 1 : - WriteLabelProlog(cupsGetOption("page-label", num_options, options), - PageLeft, PageRight, PageLength); - break; - - case 2 : - WriteLabelProlog(cupsGetOption("page-label", num_options, options), - PageLength - PageTop, PageLength - PageBottom, - PageWidth); - break; - - case 3 : - WriteLabelProlog(cupsGetOption("page-label", num_options, options), - PageWidth - PageRight, PageWidth - PageLeft, - PageLength); - break; - } - - if (realcopies > 1) - { - if (ppd == NULL || ppd->language_level == 1) - printf("/#copies %d def\n", realcopies); - else - printf("<>setpagedevice\n", realcopies); - } - - puts("%%EndProlog"); - - /* - * Output the pages... - */ - - row = malloc(cupsImageGetWidth(img) * abs(colorspace) + 3); - - fprintf(stderr, "DEBUG: XPosition=%d, YPosition=%d, Orientation=%d\n", - XPosition, YPosition, Orientation); - fprintf(stderr, "DEBUG: xprint=%.0f, yprint=%.0f\n", xprint, yprint); - fprintf(stderr, "DEBUG: PageLeft=%.0f, PageRight=%.0f, PageWidth=%.0f\n", - PageLeft, PageRight, PageWidth); - fprintf(stderr, "DEBUG: PageBottom=%.0f, PageTop=%.0f, PageLength=%.0f\n", - PageBottom, PageTop, PageLength); - - switch (Orientation) - { - default : - switch (XPosition) - { - case -1 : - left = PageLeft; - break; - default : - left = (PageRight + PageLeft - xprint * 72) / 2; - break; - case 1 : - left = PageRight - xprint * 72; - break; - } - - switch (YPosition) - { - case -1 : - top = PageBottom + yprint * 72; - break; - default : - top = (PageTop + PageBottom + yprint * 72) / 2; - break; - case 1 : - top = PageTop; - break; - } - break; - - case 1 : - switch (XPosition) - { - case -1 : - left = PageBottom; - break; - default : - left = (PageTop + PageBottom - xprint * 72) / 2; - break; - case 1 : - left = PageTop - xprint * 72; - break; - } - - switch (YPosition) - { - case -1 : - top = PageLeft + yprint * 72; - break; - default : - top = (PageRight + PageLeft + yprint * 72) / 2; - break; - case 1 : - top = PageRight; - break; - } - break; - - case 2 : - switch (XPosition) - { - case 1 : - left = PageLeft; - break; - default : - left = (PageRight + PageLeft - xprint * 72) / 2; - break; - case -1 : - left = PageRight - xprint * 72; - break; - } - - switch (YPosition) - { - case 1 : - top = PageBottom + yprint * 72; - break; - default : - top = (PageTop + PageBottom + yprint * 72) / 2; - break; - case -1 : - top = PageTop; - break; - } - break; - - case 3 : - switch (XPosition) - { - case 1 : - left = PageBottom; - break; - default : - left = (PageTop + PageBottom - xprint * 72) / 2; - break; - case -1 : - left = PageTop - xprint * 72; - break; - } - - switch (YPosition) - { - case 1 : - top = PageLeft + yprint * 72; - break; - default : - top = (PageRight + PageLeft + yprint * 72) / 2; - break; - case -1 : - top = PageRight; - break; - } - break; - } - - fprintf(stderr, "DEBUG: left=%.2f, top=%.2f\n", left, top); - - for (page = 1; Copies > 0; Copies --) - for (xpage = 0; xpage < xpages; xpage ++) - for (ypage = 0; ypage < ypages; ypage ++, page ++) - { - if (ppd && ppd->num_filters == 0) - fprintf(stderr, "PAGE: %d %d\n", page, realcopies); - - _cupsLangPrintFilter(stderr, "INFO", _("Printing page %d."), page); - - printf("%%%%Page: %d %d\n", page, page); - - ppdEmit(ppd, stdout, PPD_ORDER_PAGE); - - puts("gsave"); - - if (Flip) - printf("%.0f 0 translate -1 1 scale\n", PageWidth); - - switch (Orientation) - { - case 1 : /* Landscape */ - printf("%.0f 0 translate 90 rotate\n", PageWidth); - break; - case 2 : /* Reverse Portrait */ - printf("%.0f %.0f translate 180 rotate\n", PageWidth, PageLength); - break; - case 3 : /* Reverse Landscape */ - printf("0 %.0f translate -90 rotate\n", PageLength); - break; - } - - puts("gsave"); - - xc0 = cupsImageGetWidth(img) * xpage / xpages; - xc1 = cupsImageGetWidth(img) * (xpage + 1) / xpages - 1; - yc0 = cupsImageGetHeight(img) * ypage / ypages; - yc1 = cupsImageGetHeight(img) * (ypage + 1) / ypages - 1; - - printf("%.1f %.1f translate\n", left, top); - - printf("%.3f %.3f scale\n\n", - xprint * 72.0 / (xc1 - xc0 + 1), - yprint * 72.0 / (yc1 - yc0 + 1)); - - if (LanguageLevel == 1) - { - printf("/picture %d string def\n", (xc1 - xc0 + 1) * abs(colorspace)); - printf("%d %d 8[1 0 0 -1 0 1]", (xc1 - xc0 + 1), (yc1 - yc0 + 1)); - - if (colorspace == CUPS_IMAGE_WHITE) - puts("{currentfile picture readhexstring pop} image"); - else - printf("{currentfile picture readhexstring pop} false %d colorimage\n", - abs(colorspace)); - - for (y = yc0; y <= yc1; y ++) - { - cupsImageGetRow(img, xc0, y, xc1 - xc0 + 1, row); - ps_hex(row, (xc1 - xc0 + 1) * abs(colorspace), y == yc1); - } - } - else - { - switch (colorspace) - { - case CUPS_IMAGE_WHITE : - puts("/DeviceGray setcolorspace"); - break; - case CUPS_IMAGE_RGB : - puts("/DeviceRGB setcolorspace"); - break; - case CUPS_IMAGE_CMYK : - puts("/DeviceCMYK setcolorspace"); - break; - } - - printf("<<" - "/ImageType 1" - "/Width %d" - "/Height %d" - "/BitsPerComponent 8", - xc1 - xc0 + 1, yc1 - yc0 + 1); - - switch (colorspace) - { - case CUPS_IMAGE_WHITE : - fputs("/Decode[0 1]", stdout); - break; - case CUPS_IMAGE_RGB : - fputs("/Decode[0 1 0 1 0 1]", stdout); - break; - case CUPS_IMAGE_CMYK : - fputs("/Decode[0 1 0 1 0 1 0 1]", stdout); - break; - } - - fputs("\n/DataSource currentfile/ASCII85Decode filter", stdout); - - if (((xc1 - xc0 + 1) / xprint) < 100.0) - fputs("/Interpolate true", stdout); - - puts("/ImageMatrix[1 0 0 -1 0 1]>>image"); - - for (y = yc0, out_offset = 0; y <= yc1; y ++) - { - cupsImageGetRow(img, xc0, y, xc1 - xc0 + 1, row + out_offset); - - out_length = (xc1 - xc0 + 1) * abs(colorspace) + out_offset; - out_offset = out_length & 3; - - ps_ascii85(row, out_length, y == yc1); - - if (out_offset > 0) - memcpy(row, row + out_length - out_offset, out_offset); - } - } - - puts("grestore"); - WriteLabels(0); - puts("grestore"); - puts("showpage"); - } - - puts("%%EOF"); - - /* - * End the job with the appropriate JCL command or CTRL-D otherwise. - */ - - if (emit_jcl) - { - if (ppd && ppd->jcl_end) - ppdEmitJCLEnd(ppd, stdout); - else - putchar(0x04); - } - - /* - * Close files... - */ - - cupsImageClose(img); - ppdClose(ppd); - - return (0); -} - - -/* - * 'ps_hex()' - Print binary data as a series of hexadecimal numbers. - */ - -static void -ps_hex(cups_ib_t *data, /* I - Data to print */ - int length, /* I - Number of bytes to print */ - int last_line) /* I - Last line of raster data? */ -{ - static int col = 0; /* Current column */ - static char *hex = "0123456789ABCDEF"; - /* Hex digits */ - - - while (length > 0) - { - /* - * Put the hex chars out to the file; note that we don't use printf() - * for speed reasons... - */ - - putchar(hex[*data >> 4]); - putchar(hex[*data & 15]); - - data ++; - length --; - - col += 2; - if (col > 78) - { - putchar('\n'); - col = 0; - } - } - - if (last_line && col) - { - putchar('\n'); - col = 0; - } -} - - -/* - * 'ps_ascii85()' - Print binary data as a series of base-85 numbers. - */ - -static void -ps_ascii85(cups_ib_t *data, /* I - Data to print */ - int length, /* I - Number of bytes to print */ - int last_line) /* I - Last line of raster data? */ -{ - unsigned b; /* Binary data word */ - unsigned char c[5]; /* ASCII85 encoded chars */ - static int col = 0; /* Current column */ - - - while (length > 3) - { - b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3]; - - if (b == 0) - { - putchar('z'); - col ++; - } - else - { - c[4] = (b % 85) + '!'; - b /= 85; - c[3] = (b % 85) + '!'; - b /= 85; - c[2] = (b % 85) + '!'; - b /= 85; - c[1] = (b % 85) + '!'; - b /= 85; - c[0] = b + '!'; - - fwrite(c, 5, 1, stdout); - col += 5; - } - - data += 4; - length -= 4; - - if (col >= 75) - { - putchar('\n'); - col = 0; - } - } - - if (last_line) - { - if (length > 0) - { - memset(data + length, 0, 4 - length); - b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3]; - - c[4] = (b % 85) + '!'; - b /= 85; - c[3] = (b % 85) + '!'; - b /= 85; - c[2] = (b % 85) + '!'; - b /= 85; - c[1] = (b % 85) + '!'; - b /= 85; - c[0] = b + '!'; - - fwrite(c, length + 1, 1, stdout); - } - - puts("~>"); - col = 0; - } -} - - -/* - * End of "$Id: imagetops.c 6649 2007-07-11 21:46:42Z mike $". - */ diff --git a/filter/imagetoraster.c b/filter/imagetoraster.c deleted file mode 100644 index e1add90cc..000000000 --- a/filter/imagetoraster.c +++ /dev/null @@ -1,4368 +0,0 @@ -/* - * "$Id: imagetoraster.c 7306 2008-02-15 00:52:38Z mike $" - * - * Image file to raster filter for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * main() - Main entry... - * blank_line() - Clear a line buffer to the blank value... - * format_CMY() - Convert image data to CMY. - * format_CMYK() - Convert image data to CMYK. - * format_K() - Convert image data to black. - * format_KCMY() - Convert image data to KCMY. - * format_KCMYcm() - Convert image data to KCMYcm. - * format_RGBA() - Convert image data to RGBA/RGBW. - * format_W() - Convert image data to luminance. - * format_YMC() - Convert image data to YMC. - * format_YMCK() - Convert image data to YMCK. - * make_lut() - Make a lookup table given gamma and brightness values. - * raster_cb() - Validate the page header. - */ - -/* - * Include necessary headers... - */ - -#include "common.h" -#include "image-private.h" -#include -#include -#include -#include - - -/* - * Globals... - */ - -int Flip = 0, /* Flip/mirror pages */ - XPosition = 0, /* Horizontal position on page */ - YPosition = 0, /* Vertical position on page */ - Collate = 0, /* Collate copies? */ - Copies = 1; /* Number of copies */ -int Floyd16x16[16][16] = /* Traditional Floyd ordered dither */ - { - { 0, 128, 32, 160, 8, 136, 40, 168, - 2, 130, 34, 162, 10, 138, 42, 170 }, - { 192, 64, 224, 96, 200, 72, 232, 104, - 194, 66, 226, 98, 202, 74, 234, 106 }, - { 48, 176, 16, 144, 56, 184, 24, 152, - 50, 178, 18, 146, 58, 186, 26, 154 }, - { 240, 112, 208, 80, 248, 120, 216, 88, - 242, 114, 210, 82, 250, 122, 218, 90 }, - { 12, 140, 44, 172, 4, 132, 36, 164, - 14, 142, 46, 174, 6, 134, 38, 166 }, - { 204, 76, 236, 108, 196, 68, 228, 100, - 206, 78, 238, 110, 198, 70, 230, 102 }, - { 60, 188, 28, 156, 52, 180, 20, 148, - 62, 190, 30, 158, 54, 182, 22, 150 }, - { 252, 124, 220, 92, 244, 116, 212, 84, - 254, 126, 222, 94, 246, 118, 214, 86 }, - { 3, 131, 35, 163, 11, 139, 43, 171, - 1, 129, 33, 161, 9, 137, 41, 169 }, - { 195, 67, 227, 99, 203, 75, 235, 107, - 193, 65, 225, 97, 201, 73, 233, 105 }, - { 51, 179, 19, 147, 59, 187, 27, 155, - 49, 177, 17, 145, 57, 185, 25, 153 }, - { 243, 115, 211, 83, 251, 123, 219, 91, - 241, 113, 209, 81, 249, 121, 217, 89 }, - { 15, 143, 47, 175, 7, 135, 39, 167, - 13, 141, 45, 173, 5, 133, 37, 165 }, - { 207, 79, 239, 111, 199, 71, 231, 103, - 205, 77, 237, 109, 197, 69, 229, 101 }, - { 63, 191, 31, 159, 55, 183, 23, 151, - 61, 189, 29, 157, 53, 181, 21, 149 }, - { 254, 127, 223, 95, 247, 119, 215, 87, - 253, 125, 221, 93, 245, 117, 213, 85 } - }; -int Floyd8x8[8][8] = - { - { 0, 32, 8, 40, 2, 34, 10, 42 }, - { 48, 16, 56, 24, 50, 18, 58, 26 }, - { 12, 44, 4, 36, 14, 46, 6, 38 }, - { 60, 28, 52, 20, 62, 30, 54, 22 }, - { 3, 35, 11, 43, 1, 33, 9, 41 }, - { 51, 19, 59, 27, 49, 17, 57, 25 }, - { 15, 47, 7, 39, 13, 45, 5, 37 }, - { 63, 31, 55, 23, 61, 29, 53, 21 } - }; -int Floyd4x4[4][4] = - { - { 0, 8, 2, 10 }, - { 12, 4, 14, 6 }, - { 3, 11, 1, 9 }, - { 15, 7, 13, 5 } - }; - -cups_ib_t OnPixels[256], /* On-pixel LUT */ - OffPixels[256]; /* Off-pixel LUT */ - - -/* - * Local functions... - */ - -static void blank_line(cups_page_header2_t *header, unsigned char *row); -static void format_CMY(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); -static void format_CMYK(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); -static void format_K(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); -static void format_KCMYcm(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); -static void format_KCMY(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); -#define format_RGB format_CMY -static void format_RGBA(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); -static void format_W(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); -static void format_YMC(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); -static void format_YMCK(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); -static void make_lut(cups_ib_t *, int, float, float); -static int raster_cb(cups_page_header2_t *header, int preferred_bits); - - -/* - * 'main()' - Main entry... - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments */ - char *argv[]) /* I - Command-line arguments */ -{ - int i; /* Looping var */ - cups_image_t *img; /* Image to print */ - float xprint, /* Printable area */ - yprint, - xinches, /* Total size in inches */ - yinches; - float xsize, /* Total size in points */ - ysize, - xsize2, - ysize2; - float aspect; /* Aspect ratio */ - int xpages, /* # x pages */ - ypages, /* # y pages */ - xpage, /* Current x page */ - ypage, /* Current y page */ - xtemp, /* Bitmap width in pixels */ - ytemp, /* Bitmap height in pixels */ - page; /* Current page number */ - int xc0, yc0, /* Corners of the page in image coords */ - xc1, yc1; - ppd_file_t *ppd; /* PPD file */ - ppd_choice_t *choice; /* PPD option choice */ - char *resolution, /* Output resolution */ - *media_type; /* Media type */ - ppd_profile_t *profile; /* Color profile */ - ppd_profile_t userprofile; /* User-specified profile */ - cups_raster_t *ras; /* Raster stream */ - cups_page_header2_t header; /* Page header */ - int num_options; /* Number of print options */ - cups_option_t *options; /* Print options */ - const char *val; /* Option value */ - int slowcollate, /* Collate copies the slow way */ - slowcopies; /* Make copies the "slow" way? */ - float g; /* Gamma correction value */ - float b; /* Brightness factor */ - float zoom; /* Zoom facter */ - int xppi, yppi; /* Pixels-per-inch */ - int hue, sat; /* Hue and saturation adjustment */ - cups_izoom_t *z; /* Image zoom buffer */ - cups_iztype_t zoom_type; /* Image zoom type */ - int primary, /* Primary image colorspace */ - secondary; /* Secondary image colorspace */ - cups_ib_t *row, /* Current row */ - *r0, /* Top row */ - *r1; /* Bottom row */ - int y, /* Current Y coordinate on page */ - iy, /* Current Y coordinate in image */ - last_iy, /* Previous Y coordinate in image */ - yerr0, /* Top Y error value */ - yerr1; /* Bottom Y error value */ - cups_ib_t lut[256]; /* Gamma/brightness LUT */ - int plane, /* Current color plane */ - num_planes; /* Number of color planes */ - char filename[1024]; /* Name of file to print */ - - - /* - * Make sure status messages are not buffered... - */ - - setbuf(stderr, NULL); - - /* - * Ignore broken pipe signals... - */ - - signal(SIGPIPE, SIG_IGN); - - /* - * Check command-line... - */ - - if (argc < 6 || argc > 7) - { - _cupsLangPrintf(stderr, - _("Usage: %s job-id user title copies options file"), - argv[0]); - return (1); - } - - /* - * See if we need to use the imagetops and pstoraster filters instead... - */ - - options = NULL; - num_options = cupsParseOptions(argv[5], 0, &options); - - if (getenv("CLASSIFICATION") || - cupsGetOption("page-label", num_options, options)) - { - /* - * Yes, fork a copy of pstoraster and then transfer control to imagetops... - */ - - int mypipes[2]; /* New pipes for imagetops | pstoraster */ - int pid; /* PID of pstoraster */ - - - cupsFreeOptions(num_options, options); - - if (pipe(mypipes)) - { - _cupsLangPrintError("ERROR", _("Unable to create pipes for filters")); - return (errno); - } - - if ((pid = fork()) == 0) - { - /* - * Child process for pstoraster... Assign new pipe input to pstoraster... - */ - - dup2(mypipes[0], 0); - close(mypipes[0]); - close(mypipes[1]); - - execlp("pstoraster", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], - NULL); - return (errno); - } - else if (pid < 0) - { - /* - * Error! - */ - - _cupsLangPrintError("ERROR", _("Unable to fork filter")); - return (errno); - } - - /* - * Update stdout so it points at the new pstoraster... - */ - - dup2(mypipes[1], 1); - close(mypipes[0]); - close(mypipes[1]); - - /* - * Run imagetops to get the classification or page labeling that was - * requested... - */ - - execlp("imagetops", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], - argv[6], NULL); - return (errno); - } - - /* - * Copy stdin as needed... - */ - - if (argc == 6) - { - int fd; /* File to write to */ - char buffer[8192]; /* Buffer to read into */ - int bytes; /* # of bytes to read */ - - - if ((fd = cupsTempFd(filename, sizeof(filename))) < 0) - { - _cupsLangPrintError("ERROR", _("Unable to copy print file")); - return (1); - } - - fprintf(stderr, - "DEBUG: imagetoraster - copying to temp print file \"%s\".\n", - filename); - - while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0) - write(fd, buffer, bytes); - - close(fd); - } - else - strlcpy(filename, argv[6], sizeof(filename)); - - /* - * Process command-line options and write the prolog... - */ - - zoom = 0.0; - xppi = 0; - yppi = 0; - hue = 0; - sat = 100; - g = 1.0; - b = 1.0; - - Copies = atoi(argv[4]); - - ppd = SetCommonOptions(num_options, options, 0); - - if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL) - { - /* - * This IPP attribute is unnecessarily complicated... - * - * single-document, separate-documents-collated-copies, and - * single-document-new-sheet all require collated copies. - * - * separate-documents-collated-copies allows for uncollated copies. - */ - - Collate = _cups_strcasecmp(val, "separate-documents-collated-copies") != 0; - } - - if ((val = cupsGetOption("Collate", num_options, options)) != NULL && - _cups_strcasecmp(val, "True") == 0) - Collate = 1; - - if ((val = cupsGetOption("gamma", num_options, options)) != NULL) - { - /* - * Get gamma value from 1 to 10000... - */ - - g = atoi(val) * 0.001f; - - if (g < 0.001f) - g = 0.001f; - else if (g > 10.0f) - g = 10.0f; - } - - if ((val = cupsGetOption("brightness", num_options, options)) != NULL) - { - /* - * Get brightness value from 10 to 1000. - */ - - b = atoi(val) * 0.01f; - - if (b < 0.1f) - b = 0.1f; - else if (b > 10.0f) - b = 10.0f; - } - - if ((val = cupsGetOption("scaling", num_options, options)) != NULL) - zoom = atoi(val) * 0.01; - else if ((val = cupsGetOption("fitplot", num_options, options)) != NULL && - !_cups_strcasecmp(val, "true")) - zoom = 1.0; - else if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL && - !_cups_strcasecmp(val, "true")) - zoom = 1.0; - - if ((val = cupsGetOption("ppi", num_options, options)) != NULL) - if (sscanf(val, "%dx%d", &xppi, &yppi) < 2) - yppi = xppi; - - if ((val = cupsGetOption("position", num_options, options)) != NULL) - { - if (_cups_strcasecmp(val, "center") == 0) - { - XPosition = 0; - YPosition = 0; - } - else if (_cups_strcasecmp(val, "top") == 0) - { - XPosition = 0; - YPosition = 1; - } - else if (_cups_strcasecmp(val, "left") == 0) - { - XPosition = -1; - YPosition = 0; - } - else if (_cups_strcasecmp(val, "right") == 0) - { - XPosition = 1; - YPosition = 0; - } - else if (_cups_strcasecmp(val, "top-left") == 0) - { - XPosition = -1; - YPosition = 1; - } - else if (_cups_strcasecmp(val, "top-right") == 0) - { - XPosition = 1; - YPosition = 1; - } - else if (_cups_strcasecmp(val, "bottom") == 0) - { - XPosition = 0; - YPosition = -1; - } - else if (_cups_strcasecmp(val, "bottom-left") == 0) - { - XPosition = -1; - YPosition = -1; - } - else if (_cups_strcasecmp(val, "bottom-right") == 0) - { - XPosition = 1; - YPosition = -1; - } - } - - if ((val = cupsGetOption("saturation", num_options, options)) != NULL) - sat = atoi(val); - - if ((val = cupsGetOption("hue", num_options, options)) != NULL) - hue = atoi(val); - - if ((choice = ppdFindMarkedChoice(ppd, "MirrorPrint")) != NULL) - { - val = choice->choice; - choice->marked = 0; - } - else - val = cupsGetOption("mirror", num_options, options); - - if (val && (!_cups_strcasecmp(val, "true") || !_cups_strcasecmp(val, "on") || - !_cups_strcasecmp(val, "yes"))) - Flip = 1; - - /* - * Set the needed options in the page header... - */ - - if (cupsRasterInterpretPPD(&header, ppd, num_options, options, raster_cb)) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("The page setup information was not valid.")); - fprintf(stderr, "DEBUG: %s\n", cupsRasterErrorString()); - return (1); - } - - /* - * Get the media type and resolution that have been chosen... - */ - - if ((choice = ppdFindMarkedChoice(ppd, "MediaType")) != NULL) - media_type = choice->choice; - else - media_type = ""; - - if ((choice = ppdFindMarkedChoice(ppd, "Resolution")) != NULL) - resolution = choice->choice; - else - resolution = ""; - - /* - * Choose the appropriate colorspace... - */ - - switch (header.cupsColorSpace) - { - case CUPS_CSPACE_W : - case CUPS_CSPACE_SW : - if (header.cupsBitsPerColor >= 8) - { - primary = CUPS_IMAGE_WHITE; - secondary = CUPS_IMAGE_WHITE; - } - else - { - primary = CUPS_IMAGE_BLACK; - secondary = CUPS_IMAGE_BLACK; - } - break; - - default : - case CUPS_CSPACE_RGB : - case CUPS_CSPACE_RGBA : - case CUPS_CSPACE_RGBW : - case CUPS_CSPACE_SRGB : - case CUPS_CSPACE_ADOBERGB : - if (header.cupsBitsPerColor >= 8) - { - primary = CUPS_IMAGE_RGB; - secondary = CUPS_IMAGE_RGB; - } - else - { - primary = CUPS_IMAGE_CMY; - secondary = CUPS_IMAGE_CMY; - } - break; - - case CUPS_CSPACE_K : - case CUPS_CSPACE_WHITE : - case CUPS_CSPACE_GOLD : - case CUPS_CSPACE_SILVER : - primary = CUPS_IMAGE_BLACK; - secondary = CUPS_IMAGE_BLACK; - break; - - case CUPS_CSPACE_CMYK : - case CUPS_CSPACE_YMCK : - case CUPS_CSPACE_KCMY : - case CUPS_CSPACE_KCMYcm : - case CUPS_CSPACE_GMCK : - case CUPS_CSPACE_GMCS : - if (header.cupsBitsPerColor == 1) - { - primary = CUPS_IMAGE_CMY; - secondary = CUPS_IMAGE_CMY; - } - else - { - primary = CUPS_IMAGE_CMYK; - secondary = CUPS_IMAGE_CMYK; - } - break; - - case CUPS_CSPACE_CMY : - case CUPS_CSPACE_YMC : - primary = CUPS_IMAGE_CMY; - secondary = CUPS_IMAGE_CMY; - break; - - case CUPS_CSPACE_CIEXYZ : - case CUPS_CSPACE_CIELab : - case CUPS_CSPACE_ICC1 : - case CUPS_CSPACE_ICC2 : - case CUPS_CSPACE_ICC3 : - case CUPS_CSPACE_ICC4 : - case CUPS_CSPACE_ICC5 : - case CUPS_CSPACE_ICC6 : - case CUPS_CSPACE_ICC7 : - case CUPS_CSPACE_ICC8 : - case CUPS_CSPACE_ICC9 : - case CUPS_CSPACE_ICCA : - case CUPS_CSPACE_ICCB : - case CUPS_CSPACE_ICCC : - case CUPS_CSPACE_ICCD : - case CUPS_CSPACE_ICCE : - case CUPS_CSPACE_ICCF : - case CUPS_CSPACE_DEVICE1 : - case CUPS_CSPACE_DEVICE2 : - case CUPS_CSPACE_DEVICE3 : - case CUPS_CSPACE_DEVICE4 : - case CUPS_CSPACE_DEVICE5 : - case CUPS_CSPACE_DEVICE6 : - case CUPS_CSPACE_DEVICE7 : - case CUPS_CSPACE_DEVICE8 : - case CUPS_CSPACE_DEVICE9 : - case CUPS_CSPACE_DEVICEA : - case CUPS_CSPACE_DEVICEB : - case CUPS_CSPACE_DEVICEC : - case CUPS_CSPACE_DEVICED : - case CUPS_CSPACE_DEVICEE : - case CUPS_CSPACE_DEVICEF : - fprintf(stderr, "DEBUG: Colorspace %d not supported.\n", - header.cupsColorSpace); - exit(1); - break; - } - - /* - * Find a color profile matching the current options... - */ - - if ((val = cupsGetOption("profile", num_options, options)) != NULL) - { - profile = &userprofile; - sscanf(val, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f", - &(userprofile.density), &(userprofile.gamma), - userprofile.matrix[0] + 0, userprofile.matrix[0] + 1, - userprofile.matrix[0] + 2, - userprofile.matrix[1] + 0, userprofile.matrix[1] + 1, - userprofile.matrix[1] + 2, - userprofile.matrix[2] + 0, userprofile.matrix[2] + 1, - userprofile.matrix[2] + 2); - - userprofile.density *= 0.001f; - userprofile.gamma *= 0.001f; - userprofile.matrix[0][0] *= 0.001f; - userprofile.matrix[0][1] *= 0.001f; - userprofile.matrix[0][2] *= 0.001f; - userprofile.matrix[1][0] *= 0.001f; - userprofile.matrix[1][1] *= 0.001f; - userprofile.matrix[1][2] *= 0.001f; - userprofile.matrix[2][0] *= 0.001f; - userprofile.matrix[2][1] *= 0.001f; - userprofile.matrix[2][2] *= 0.001f; - } - else if (ppd != NULL) - { - fprintf(stderr, "DEBUG: Searching for profile \"%s/%s\"...\n", - resolution, media_type); - - for (i = 0, profile = ppd->profiles; i < ppd->num_profiles; i ++, profile ++) - { - fprintf(stderr, "DEBUG: \"%s/%s\" = ", profile->resolution, - profile->media_type); - - if ((strcmp(profile->resolution, resolution) == 0 || - profile->resolution[0] == '-') && - (strcmp(profile->media_type, media_type) == 0 || - profile->media_type[0] == '-')) - { - fputs("MATCH\n", stderr); - break; - } - else - fputs("no.\n", stderr); - } - - /* - * If we found a color profile, use it! - */ - - if (i >= ppd->num_profiles) - profile = NULL; - } - else - profile = NULL; - - if (profile) - cupsImageSetProfile(profile->density, profile->gamma, profile->matrix); - - cupsImageSetRasterColorSpace(header.cupsColorSpace); - - /* - * Create a gamma/brightness LUT... - */ - - make_lut(lut, primary, g, b); - - /* - * Open the input image to print... - */ - - _cupsLangPrintFilter(stderr, "INFO", _("Loading print file.")); - - if (header.cupsColorSpace == CUPS_CSPACE_CIEXYZ || - header.cupsColorSpace == CUPS_CSPACE_CIELab || - header.cupsColorSpace >= CUPS_CSPACE_ICC1) - img = cupsImageOpen(filename, primary, secondary, sat, hue, NULL); - else - img = cupsImageOpen(filename, primary, secondary, sat, hue, lut); - - if (argc == 6) - unlink(filename); - - if (img == NULL) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("The print file could not be opened.")); - ppdClose(ppd); - return (1); - } - - /* - * Scale as necessary... - */ - - if (zoom == 0.0 && xppi == 0) - { - xppi = img->xppi; - yppi = img->yppi; - } - - if (yppi == 0) - yppi = xppi; - - fprintf(stderr, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n", - xppi, yppi, zoom); - - if (xppi > 0) - { - /* - * Scale the image as neccesary to match the desired pixels-per-inch. - */ - - if (Orientation & 1) - { - xprint = (PageTop - PageBottom) / 72.0; - yprint = (PageRight - PageLeft) / 72.0; - } - else - { - xprint = (PageRight - PageLeft) / 72.0; - yprint = (PageTop - PageBottom) / 72.0; - } - - fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n", - xprint, yprint); - - xinches = (float)img->xsize / (float)xppi; - yinches = (float)img->ysize / (float)yppi; - - fprintf(stderr, "DEBUG: Image size is %.1f x %.1f inches...\n", - xinches, yinches); - - if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL) - { - xinches = xinches * atoi(val) / 100; - yinches = yinches * atoi(val) / 100; - } - - if (cupsGetOption("orientation-requested", num_options, options) == NULL && - cupsGetOption("landscape", num_options, options) == NULL) - { - /* - * Rotate the image if it will fit landscape but not portrait... - */ - - fputs("DEBUG: Auto orientation...\n", stderr); - - if ((xinches > xprint || yinches > yprint) && - xinches <= yprint && yinches <= xprint) - { - /* - * Rotate the image as needed... - */ - - fputs("DEBUG: Using landscape orientation...\n", stderr); - - Orientation = (Orientation + 1) & 3; - xsize = yprint; - yprint = xprint; - xprint = xsize; - } - } - } - else - { - /* - * Scale percentage of page size... - */ - - xprint = (PageRight - PageLeft) / 72.0; - yprint = (PageTop - PageBottom) / 72.0; - aspect = (float)img->yppi / (float)img->xppi; - - fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n", - xprint, yprint); - - fprintf(stderr, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n", - img->xppi, img->yppi, aspect); - - xsize = xprint * zoom; - ysize = xsize * img->ysize / img->xsize / aspect; - - if (ysize > (yprint * zoom)) - { - ysize = yprint * zoom; - xsize = ysize * img->xsize * aspect / img->ysize; - } - - xsize2 = yprint * zoom; - ysize2 = xsize2 * img->ysize / img->xsize / aspect; - - if (ysize2 > (xprint * zoom)) - { - ysize2 = xprint * zoom; - xsize2 = ysize2 * img->xsize * aspect / img->ysize; - } - - fprintf(stderr, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize, ysize); - fprintf(stderr, "DEBUG: Landscape size is %.2f x %.2f inches\n", xsize2, ysize2); - - if (cupsGetOption("orientation-requested", num_options, options) == NULL && - cupsGetOption("landscape", num_options, options) == NULL) - { - /* - * Choose the rotation with the largest area, but prefer - * portrait if they are equal... - */ - - fputs("DEBUG: Auto orientation...\n", stderr); - - if ((xsize * ysize) < (xsize2 * xsize2)) - { - /* - * Do landscape orientation... - */ - - fputs("DEBUG: Using landscape orientation...\n", stderr); - - Orientation = 1; - xinches = xsize2; - yinches = ysize2; - xprint = (PageTop - PageBottom) / 72.0; - yprint = (PageRight - PageLeft) / 72.0; - } - else - { - /* - * Do portrait orientation... - */ - - fputs("DEBUG: Using portrait orientation...\n", stderr); - - Orientation = 0; - xinches = xsize; - yinches = ysize; - } - } - else if (Orientation & 1) - { - fputs("DEBUG: Using landscape orientation...\n", stderr); - - xinches = xsize2; - yinches = ysize2; - xprint = (PageTop - PageBottom) / 72.0; - yprint = (PageRight - PageLeft) / 72.0; - } - else - { - fputs("DEBUG: Using portrait orientation...\n", stderr); - - xinches = xsize; - yinches = ysize; - xprint = (PageRight - PageLeft) / 72.0; - yprint = (PageTop - PageBottom) / 72.0; - } - } - - /* - * Compute the number of pages to print and the size of the image on each - * page... - */ - - xpages = ceil(xinches / xprint); - ypages = ceil(yinches / yprint); - - xprint = xinches / xpages; - yprint = yinches / ypages; - - fprintf(stderr, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n", - xpages, xprint, ypages, yprint); - - /* - * Compute the bitmap size... - */ - - if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL && - _cups_strcasecmp(choice->choice, "Custom") == 0) - { - float width, /* New width in points */ - length; /* New length in points */ - - - /* - * Use the correct width and length for the current orientation... - */ - - if (Orientation & 1) - { - width = yprint * 72.0; - length = xprint * 72.0; - } - else - { - width = xprint * 72.0; - length = yprint * 72.0; - } - - /* - * Add margins to page size... - */ - - width += ppd->custom_margins[0] + ppd->custom_margins[2]; - length += ppd->custom_margins[1] + ppd->custom_margins[3]; - - /* - * Enforce minimums... - */ - - if (width < ppd->custom_min[0]) - width = ppd->custom_min[0]; - - if (length < ppd->custom_min[1]) - length = ppd->custom_min[1]; - - fprintf(stderr, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n", - width / 72.0, length / 72.0); - - /* - * Set the new custom size... - */ - - strcpy(header.cupsPageSizeName, "Custom"); - - header.cupsPageSize[0] = width + 0.5; - header.cupsPageSize[1] = length + 0.5; - header.PageSize[0] = width + 0.5; - header.PageSize[1] = length + 0.5; - - /* - * Update page variables... - */ - - PageWidth = width; - PageLength = length; - PageLeft = ppd->custom_margins[0]; - PageRight = width - ppd->custom_margins[2]; - PageBottom = ppd->custom_margins[1]; - PageTop = length - ppd->custom_margins[3]; - - /* - * Remove margins from page size... - */ - - width -= ppd->custom_margins[0] + ppd->custom_margins[2]; - length -= ppd->custom_margins[1] + ppd->custom_margins[3]; - - /* - * Set the bitmap size... - */ - - header.cupsWidth = width * header.HWResolution[0] / 72.0; - header.cupsHeight = length * header.HWResolution[1] / 72.0; - - header.cupsBytesPerLine = (header.cupsBitsPerPixel * - header.cupsWidth + 7) / 8; - - if (header.cupsColorOrder == CUPS_ORDER_BANDED) - header.cupsBytesPerLine *= header.cupsNumColors; - } - - header.Margins[0] = PageLeft; - header.Margins[1] = PageBottom; - - fprintf(stderr, "DEBUG: PageSize = [%d %d]\n", header.PageSize[0], - header.PageSize[1]); - - switch (Orientation) - { - default : - switch (XPosition) - { - case -1 : - header.cupsImagingBBox[0] = PageLeft; - header.cupsImagingBBox[2] = PageLeft + xprint * 72; - break; - default : - header.cupsImagingBBox[0] = (PageRight + PageLeft - xprint * 72) / 2; - header.cupsImagingBBox[2] = (PageRight + PageLeft + xprint * 72) / 2; - break; - case 1 : - header.cupsImagingBBox[0] = PageRight - xprint * 72; - header.cupsImagingBBox[2] = PageRight; - break; - } - - switch (YPosition) - { - case -1 : - header.cupsImagingBBox[1] = PageBottom; - header.cupsImagingBBox[3] = PageBottom + yprint * 72; - break; - default : - header.cupsImagingBBox[1] = (PageTop + PageBottom - yprint * 72) / 2; - header.cupsImagingBBox[3] = (PageTop + PageBottom + yprint * 72) / 2; - break; - case 1 : - header.cupsImagingBBox[1] = PageTop - yprint * 72; - header.cupsImagingBBox[3] = PageTop; - break; - } - break; - - case 1 : - switch (XPosition) - { - case -1 : - header.cupsImagingBBox[0] = PageBottom; - header.cupsImagingBBox[2] = PageBottom + yprint * 72; - break; - default : - header.cupsImagingBBox[0] = (PageTop + PageBottom - yprint * 72) / 2; - header.cupsImagingBBox[2] = (PageTop + PageBottom + yprint * 72) / 2; - break; - case 1 : - header.cupsImagingBBox[0] = PageTop - yprint * 72; - header.cupsImagingBBox[2] = PageTop; - break; - } - - switch (YPosition) - { - case -1 : - header.cupsImagingBBox[1] = PageLeft; - header.cupsImagingBBox[3] = PageLeft + xprint * 72; - break; - default : - header.cupsImagingBBox[1] = (PageRight + PageLeft - xprint * 72) / 2; - header.cupsImagingBBox[3] = (PageRight + PageLeft + xprint * 72) / 2; - break; - case 1 : - header.cupsImagingBBox[1] = PageRight - xprint * 72; - header.cupsImagingBBox[3] = PageRight; - break; - } - break; - - case 2 : - switch (XPosition) - { - case 1 : - header.cupsImagingBBox[0] = PageLeft; - header.cupsImagingBBox[2] = PageLeft + xprint * 72; - break; - default : - header.cupsImagingBBox[0] = (PageRight + PageLeft - xprint * 72) / 2; - header.cupsImagingBBox[2] = (PageRight + PageLeft + xprint * 72) / 2; - break; - case -1 : - header.cupsImagingBBox[0] = PageRight - xprint * 72; - header.cupsImagingBBox[2] = PageRight; - break; - } - - switch (YPosition) - { - case 1 : - header.cupsImagingBBox[1] = PageBottom; - header.cupsImagingBBox[3] = PageBottom + yprint * 72; - break; - default : - header.cupsImagingBBox[1] = (PageTop + PageBottom - yprint * 72) / 2; - header.cupsImagingBBox[3] = (PageTop + PageBottom + yprint * 72) / 2; - break; - case -1 : - header.cupsImagingBBox[1] = PageTop - yprint * 72; - header.cupsImagingBBox[3] = PageTop; - break; - } - break; - - case 3 : - switch (XPosition) - { - case 1 : - header.cupsImagingBBox[0] = PageBottom; - header.cupsImagingBBox[2] = PageBottom + yprint * 72; - break; - default : - header.cupsImagingBBox[0] = (PageTop + PageBottom - yprint * 72) / 2; - header.cupsImagingBBox[2] = (PageTop + PageBottom + yprint * 72) / 2; - break; - case -1 : - header.cupsImagingBBox[0] = PageTop - yprint * 72; - header.cupsImagingBBox[2] = PageTop; - break; - } - - switch (YPosition) - { - case 1 : - header.cupsImagingBBox[1] = PageLeft; - header.cupsImagingBBox[3] = PageLeft + xprint * 72; - break; - default : - header.cupsImagingBBox[1] = (PageRight + PageLeft - xprint * 72) / 2; - header.cupsImagingBBox[3] = (PageRight + PageLeft + xprint * 72) / 2; - break; - case -1 : - header.cupsImagingBBox[1] = PageRight - xprint * 72; - header.cupsImagingBBox[3] = PageRight; - break; - } - break; - } - - header.ImagingBoundingBox[0] = header.cupsImagingBBox[0]; - header.ImagingBoundingBox[1] = header.cupsImagingBBox[1]; - header.ImagingBoundingBox[2] = header.cupsImagingBBox[2]; - header.ImagingBoundingBox[3] = header.cupsImagingBBox[3]; - - if (header.cupsColorOrder == CUPS_ORDER_PLANAR) - num_planes = header.cupsNumColors; - else - num_planes = 1; - - if (header.cupsBitsPerColor >= 8) - zoom_type = CUPS_IZOOM_NORMAL; - else - zoom_type = CUPS_IZOOM_FAST; - - /* - * See if we need to collate, and if so how we need to do it... - */ - - if (xpages == 1 && ypages == 1) - Collate = 0; - - slowcollate = Collate && ppdFindOption(ppd, "Collate") == NULL; - if (ppd != NULL) - slowcopies = ppd->manual_copies; - else - slowcopies = 1; - - if (Copies > 1 && !slowcollate && !slowcopies) - { - header.Collate = (cups_bool_t)Collate; - header.NumCopies = Copies; - - Copies = 1; - } - else - header.NumCopies = 1; - - /* - * Create the dithering lookup tables... - */ - - OnPixels[0] = 0x00; - OnPixels[255] = 0xff; - OffPixels[0] = 0x00; - OffPixels[255] = 0xff; - - switch (header.cupsBitsPerColor) - { - case 2 : - for (i = 1; i < 255; i ++) - { - OnPixels[i] = 0x55 * (i / 85 + 1); - OffPixels[i] = 0x55 * (i / 64); - } - break; - case 4 : - for (i = 1; i < 255; i ++) - { - OnPixels[i] = 17 * (i / 17 + 1); - OffPixels[i] = 17 * (i / 16); - } - break; - } - - /* - * Output the pages... - */ - - fprintf(stderr, "DEBUG: cupsWidth = %d\n", header.cupsWidth); - fprintf(stderr, "DEBUG: cupsHeight = %d\n", header.cupsHeight); - fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header.cupsBitsPerColor); - fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header.cupsBitsPerPixel); - fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header.cupsBytesPerLine); - fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header.cupsColorOrder); - fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header.cupsColorSpace); - fprintf(stderr, "DEBUG: img->colorspace = %d\n", img->colorspace); - - row = malloc(2 * header.cupsBytesPerLine); - ras = cupsRasterOpen(1, CUPS_RASTER_WRITE); - - for (i = 0, page = 1; i < Copies; i ++) - for (xpage = 0; xpage < xpages; xpage ++) - for (ypage = 0; ypage < ypages; ypage ++, page ++) - { - _cupsLangPrintFilter(stderr, "INFO", _("Formatting page %d."), page); - - if (Orientation & 1) - { - xc0 = img->xsize * ypage / ypages; - xc1 = img->xsize * (ypage + 1) / ypages - 1; - yc0 = img->ysize * xpage / xpages; - yc1 = img->ysize * (xpage + 1) / xpages - 1; - - xtemp = header.HWResolution[0] * yprint; - ytemp = header.HWResolution[1] * xprint; - } - else - { - xc0 = img->xsize * xpage / xpages; - xc1 = img->xsize * (xpage + 1) / xpages - 1; - yc0 = img->ysize * ypage / ypages; - yc1 = img->ysize * (ypage + 1) / ypages - 1; - - xtemp = header.HWResolution[0] * xprint; - ytemp = header.HWResolution[1] * yprint; - } - - cupsRasterWriteHeader2(ras, &header); - - for (plane = 0; plane < num_planes; plane ++) - { - /* - * Initialize the image "zoom" engine... - */ - - if (Flip) - z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, -xtemp, ytemp, - Orientation & 1, zoom_type); - else - z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, xtemp, ytemp, - Orientation & 1, zoom_type); - - /* - * Write leading blank space as needed... - */ - - if (header.cupsHeight > z->ysize && YPosition <= 0) - { - blank_line(&header, row); - - y = header.cupsHeight - z->ysize; - if (YPosition == 0) - y /= 2; - - fprintf(stderr, "DEBUG: Writing %d leading blank lines...\n", y); - - for (; y > 0; y --) - { - if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) < - header.cupsBytesPerLine) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Unable to send raster data to the " - "driver.")); - cupsImageClose(img); - exit(1); - } - } - } - - /* - * Then write image data... - */ - - for (y = z->ysize, yerr0 = 0, yerr1 = z->ysize, iy = 0, last_iy = -2; - y > 0; - y --) - { - if (iy != last_iy) - { - if (zoom_type != CUPS_IZOOM_FAST && (iy - last_iy) > 1) - _cupsImageZoomFill(z, iy); - - _cupsImageZoomFill(z, iy + z->yincr); - - last_iy = iy; - } - - /* - * Format this line of raster data for the printer... - */ - - blank_line(&header, row); - - r0 = z->rows[z->row]; - r1 = z->rows[1 - z->row]; - - switch (header.cupsColorSpace) - { - case CUPS_CSPACE_W : - format_W(&header, row, y, plane, z->xsize, z->ysize, - yerr0, yerr1, r0, r1); - break; - default : - case CUPS_CSPACE_RGB : - format_RGB(&header, row, y, plane, z->xsize, z->ysize, - yerr0, yerr1, r0, r1); - break; - case CUPS_CSPACE_RGBA : - case CUPS_CSPACE_RGBW : - format_RGBA(&header, row, y, plane, z->xsize, z->ysize, - yerr0, yerr1, r0, r1); - break; - case CUPS_CSPACE_K : - case CUPS_CSPACE_WHITE : - case CUPS_CSPACE_GOLD : - case CUPS_CSPACE_SILVER : - format_K(&header, row, y, plane, z->xsize, z->ysize, - yerr0, yerr1, r0, r1); - break; - case CUPS_CSPACE_CMY : - format_CMY(&header, row, y, plane, z->xsize, z->ysize, - yerr0, yerr1, r0, r1); - break; - case CUPS_CSPACE_YMC : - format_YMC(&header, row, y, plane, z->xsize, z->ysize, - yerr0, yerr1, r0, r1); - break; - case CUPS_CSPACE_CMYK : - format_CMYK(&header, row, y, plane, z->xsize, z->ysize, - yerr0, yerr1, r0, r1); - break; - case CUPS_CSPACE_YMCK : - case CUPS_CSPACE_GMCK : - case CUPS_CSPACE_GMCS : - format_YMCK(&header, row, y, plane, z->xsize, z->ysize, - yerr0, yerr1, r0, r1); - break; - case CUPS_CSPACE_KCMYcm : - if (header.cupsBitsPerColor == 1) - { - format_KCMYcm(&header, row, y, plane, z->xsize, z->ysize, - yerr0, yerr1, r0, r1); - break; - } - case CUPS_CSPACE_KCMY : - format_KCMY(&header, row, y, plane, z->xsize, z->ysize, - yerr0, yerr1, r0, r1); - break; - } - - /* - * Write the raster data to the driver... - */ - - if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) < - header.cupsBytesPerLine) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Unable to send raster data to the " - "driver.")); - cupsImageClose(img); - exit(1); - } - - /* - * Compute the next scanline in the image... - */ - - iy += z->ystep; - yerr0 += z->ymod; - yerr1 -= z->ymod; - if (yerr1 <= 0) - { - yerr0 -= z->ysize; - yerr1 += z->ysize; - iy += z->yincr; - } - } - - /* - * Write trailing blank space as needed... - */ - - if (header.cupsHeight > z->ysize && YPosition >= 0) - { - blank_line(&header, row); - - y = header.cupsHeight - z->ysize; - if (YPosition == 0) - y = y - y / 2; - - fprintf(stderr, "DEBUG: Writing %d trailing blank lines...\n", y); - - for (; y > 0; y --) - { - if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) < - header.cupsBytesPerLine) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Unable to send raster data to the " - "driver.")); - cupsImageClose(img); - exit(1); - } - } - } - - /* - * Free memory used for the "zoom" engine... - */ - - _cupsImageZoomDelete(z); - } - } - - /* - * Close files... - */ - - free(row); - cupsRasterClose(ras); - cupsImageClose(img); - ppdClose(ppd); - - return (0); -} - - -/* - * 'blank_line()' - Clear a line buffer to the blank value... - */ - -static void -blank_line(cups_page_header2_t *header, /* I - Page header */ - unsigned char *row) /* I - Row buffer */ -{ - int count; /* Remaining bytes */ - - - count = header->cupsBytesPerLine; - - switch (header->cupsColorSpace) - { - case CUPS_CSPACE_CIEXYZ : - while (count > 2) - { - *row++ = 242; - *row++ = 255; - *row++ = 255; - count -= 3; - } - break; - - case CUPS_CSPACE_CIELab : - case CUPS_CSPACE_ICC1 : - case CUPS_CSPACE_ICC2 : - case CUPS_CSPACE_ICC3 : - case CUPS_CSPACE_ICC4 : - case CUPS_CSPACE_ICC5 : - case CUPS_CSPACE_ICC6 : - case CUPS_CSPACE_ICC7 : - case CUPS_CSPACE_ICC8 : - case CUPS_CSPACE_ICC9 : - case CUPS_CSPACE_ICCA : - case CUPS_CSPACE_ICCB : - case CUPS_CSPACE_ICCC : - case CUPS_CSPACE_ICCD : - case CUPS_CSPACE_ICCE : - case CUPS_CSPACE_ICCF : - while (count > 2) - { - *row++ = 255; - *row++ = 128; - *row++ = 128; - count -= 3; - } - break; - - case CUPS_CSPACE_K : - case CUPS_CSPACE_CMY : - case CUPS_CSPACE_CMYK : - case CUPS_CSPACE_YMC : - case CUPS_CSPACE_YMCK : - case CUPS_CSPACE_KCMY : - case CUPS_CSPACE_KCMYcm : - case CUPS_CSPACE_GMCK : - case CUPS_CSPACE_GMCS : - case CUPS_CSPACE_WHITE : - case CUPS_CSPACE_GOLD : - case CUPS_CSPACE_SILVER : - memset(row, 0, count); - break; - - default : - memset(row, 255, count); - break; - } -} - - -/* - * 'format_CMY()' - Convert image data to CMY. - */ - -static void -format_CMY(cups_page_header2_t *header, /* I - Page header */ - unsigned char *row, /* IO - Bitmap data for device */ - int y, /* I - Current row */ - int z, /* I - Current plane */ - int xsize, /* I - Width of image data */ - int ysize, /* I - Height of image data */ - int yerr0, /* I - Top Y error */ - int yerr1, /* I - Bottom Y error */ - cups_ib_t *r0, /* I - Primary image data */ - cups_ib_t *r1) /* I - Image data for interpolation */ -{ - cups_ib_t *ptr, /* Pointer into row */ - *cptr, /* Pointer into cyan */ - *mptr, /* Pointer into magenta */ - *yptr, /* Pointer into yellow */ - bitmask; /* Current mask for pixel */ - int bitoffset; /* Current offset in line */ - int bandwidth; /* Width of a color band */ - int x, /* Current X coordinate on page */ - *dither; /* Pointer into dither array */ - - - switch (XPosition) - { - case -1 : - bitoffset = 0; - break; - default : - bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); - break; - case 1 : - bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); - break; - } - - ptr = row + bitoffset / 8; - bandwidth = header->cupsBytesPerLine / 3; - - switch (header->cupsColorOrder) - { - case CUPS_ORDER_CHUNKED : - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 64 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize ; x > 0; x --) - { - if (*r0++ > dither[x & 15]) - *ptr ^= bitmask; - bitmask >>= 1; - - if (*r0++ > dither[x & 15]) - *ptr ^= bitmask; - bitmask >>= 1; - - if (*r0++ > dither[x & 15]) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 2; - else - { - bitmask = 64; - ptr ++; - } - } - break; - - case 2 : - dither = Floyd8x8[y & 7]; - - for (x = xsize ; x > 0; x --, r0 += 3) - { - if ((r0[0] & 63) > dither[x & 7]) - *ptr ^= (0x30 & OnPixels[r0[0]]); - else - *ptr ^= (0x30 & OffPixels[r0[0]]); - - if ((r0[1] & 63) > dither[x & 7]) - *ptr ^= (0x0c & OnPixels[r0[1]]); - else - *ptr ^= (0x0c & OffPixels[r0[1]]); - - if ((r0[2] & 63) > dither[x & 7]) - *ptr++ ^= (0x03 & OnPixels[r0[2]]); - else - *ptr++ ^= (0x03 & OffPixels[r0[2]]); - } - break; - - case 4 : - dither = Floyd4x4[y & 3]; - - for (x = xsize ; x > 0; x --, r0 += 3) - { - if ((r0[0] & 15) > dither[x & 3]) - *ptr++ ^= (0x0f & OnPixels[r0[0]]); - else - *ptr++ ^= (0x0f & OffPixels[r0[0]]); - - if ((r0[1] & 15) > dither[x & 3]) - *ptr ^= (0xf0 & OnPixels[r0[1]]); - else - *ptr ^= (0xf0 & OffPixels[r0[1]]); - - if ((r0[2] & 15) > dither[x & 3]) - *ptr++ ^= (0x0f & OnPixels[r0[2]]); - else - *ptr++ ^= (0x0f & OffPixels[r0[2]]); - } - break; - - case 8 : - for (x = xsize * 3; x > 0; x --, r0 ++, r1 ++) - if (*r0 == *r1) - *ptr++ = *r0; - else - *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; - break; - } - break; - - case CUPS_ORDER_BANDED : - cptr = ptr; - mptr = ptr + bandwidth; - yptr = ptr + 2 * bandwidth; - - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize; x > 0; x --) - { - if (*r0++ > dither[x & 15]) - *cptr ^= bitmask; - if (*r0++ > dither[x & 15]) - *mptr ^= bitmask; - if (*r0++ > dither[x & 15]) - *yptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - cptr ++; - mptr ++; - yptr ++; - } - } - break; - - case 2 : - bitmask = 0xc0 >> (bitoffset & 7); - dither = Floyd8x8[y & 7]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 63) > dither[x & 7]) - *cptr ^= (bitmask & OnPixels[*r0++]); - else - *cptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *mptr ^= (bitmask & OnPixels[*r0++]); - else - *mptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *yptr ^= (bitmask & OnPixels[*r0++]); - else - *yptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask > 3) - bitmask >>= 2; - else - { - bitmask = 0xc0; - - cptr ++; - mptr ++; - yptr ++; - } - } - break; - - case 4 : - bitmask = 0xf0 >> (bitoffset & 7); - dither = Floyd4x4[y & 3]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 15) > dither[x & 3]) - *cptr ^= (bitmask & OnPixels[*r0++]); - else - *cptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *mptr ^= (bitmask & OnPixels[*r0++]); - else - *mptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *yptr ^= (bitmask & OnPixels[*r0++]); - else - *yptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask == 0xf0) - bitmask = 0x0f; - else - { - bitmask = 0xf0; - - cptr ++; - mptr ++; - yptr ++; - } - } - break; - - case 8 : - for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) - { - if (r0[0] == r1[0]) - *cptr++ = r0[0]; - else - *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; - - if (r0[1] == r1[1]) - *mptr++ = r0[1]; - else - *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; - - if (r0[2] == r1[2]) - *yptr++ = r0[2]; - else - *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; - } - break; - } - break; - - case CUPS_ORDER_PLANAR : - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - switch (z) - { - case 0 : - for (x = xsize; x > 0; x --, r0 += 3) - { - if (r0[0] > dither[x & 15]) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - - case 1 : - for (x = xsize; x > 0; x --, r0 += 3) - { - if (r0[1] > dither[x & 15]) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - - case 2 : - for (x = xsize; x > 0; x --, r0 += 3) - { - if (r0[2] > dither[x & 15]) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - } - break; - - case 2 : - bitmask = 0xc0 >> (bitoffset & 7); - dither = Floyd8x8[y & 7]; - r0 += z; - - for (x = xsize; x > 0; x --, r0 += 3) - { - if ((*r0 & 63) > dither[x & 7]) - *ptr ^= (bitmask & OnPixels[*r0]); - else - *ptr ^= (bitmask & OffPixels[*r0]); - - if (bitmask > 3) - bitmask >>= 2; - else - { - bitmask = 0xc0; - - ptr ++; - } - } - break; - - case 4 : - bitmask = 0xf0 >> (bitoffset & 7); - dither = Floyd4x4[y & 3]; - r0 += z; - - for (x = xsize; x > 0; x --, r0 += 3) - { - if ((*r0 & 15) > dither[x & 3]) - *ptr ^= (bitmask & OnPixels[*r0]); - else - *ptr ^= (bitmask & OffPixels[*r0]); - - if (bitmask == 0xf0) - bitmask = 0x0f; - else - { - bitmask = 0xf0; - - ptr ++; - } - } - break; - - case 8 : - r0 += z; - r1 += z; - - for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) - { - if (*r0 == *r1) - *ptr++ = *r0; - else - *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; - } - break; - } - break; - } -} - - -/* - * 'format_CMYK()' - Convert image data to CMYK. - */ - -static void -format_CMYK(cups_page_header2_t *header,/* I - Page header */ - unsigned char *row, /* IO - Bitmap data for device */ - int y, /* I - Current row */ - int z, /* I - Current plane */ - int xsize, /* I - Width of image data */ - int ysize, /* I - Height of image data */ - int yerr0, /* I - Top Y error */ - int yerr1, /* I - Bottom Y error */ - cups_ib_t *r0, /* I - Primary image data */ - cups_ib_t *r1) /* I - Image data for interpolation */ -{ - cups_ib_t *ptr, /* Pointer into row */ - *cptr, /* Pointer into cyan */ - *mptr, /* Pointer into magenta */ - *yptr, /* Pointer into yellow */ - *kptr, /* Pointer into black */ - bitmask; /* Current mask for pixel */ - int bitoffset; /* Current offset in line */ - int bandwidth; /* Width of a color band */ - int x, /* Current X coordinate on page */ - *dither; /* Pointer into dither array */ - int pc, pm, py; /* CMY pixels */ - - - switch (XPosition) - { - case -1 : - bitoffset = 0; - break; - default : - bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); - break; - case 1 : - bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); - break; - } - - ptr = row + bitoffset / 8; - bandwidth = header->cupsBytesPerLine / 4; - - switch (header->cupsColorOrder) - { - case CUPS_ORDER_CHUNKED : - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 128 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize ; x > 0; x --) - { - pc = *r0++ > dither[x & 15]; - pm = *r0++ > dither[x & 15]; - py = *r0++ > dither[x & 15]; - - if (pc && pm && py) - { - bitmask >>= 3; - *ptr ^= bitmask; - } - else - { - if (pc) - *ptr ^= bitmask; - bitmask >>= 1; - - if (pm) - *ptr ^= bitmask; - bitmask >>= 1; - - if (py) - *ptr ^= bitmask; - bitmask >>= 1; - } - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 128; - ptr ++; - } - } - break; - - case 2 : - dither = Floyd8x8[y & 7]; - - for (x = xsize ; x > 0; x --, r0 += 4) - { - if ((r0[0] & 63) > dither[x & 7]) - *ptr ^= (0xc0 & OnPixels[r0[0]]); - else - *ptr ^= (0xc0 & OffPixels[r0[0]]); - - if ((r0[1] & 63) > dither[x & 7]) - *ptr ^= (0x30 & OnPixels[r0[1]]); - else - *ptr ^= (0x30 & OffPixels[r0[1]]); - - if ((r0[2] & 63) > dither[x & 7]) - *ptr ^= (0x0c & OnPixels[r0[2]]); - else - *ptr ^= (0x0c & OffPixels[r0[2]]); - - if ((r0[3] & 63) > dither[x & 7]) - *ptr++ ^= (0x03 & OnPixels[r0[3]]); - else - *ptr++ ^= (0x03 & OffPixels[r0[3]]); - } - break; - - case 4 : - dither = Floyd4x4[y & 3]; - - for (x = xsize ; x > 0; x --, r0 += 4) - { - if ((r0[0] & 15) > dither[x & 3]) - *ptr ^= (0xf0 & OnPixels[r0[0]]); - else - *ptr ^= (0xf0 & OffPixels[r0[0]]); - - if ((r0[1] & 15) > dither[x & 3]) - *ptr++ ^= (0x0f & OnPixels[r0[1]]); - else - *ptr++ ^= (0x0f & OffPixels[r0[1]]); - - if ((r0[2] & 15) > dither[x & 3]) - *ptr ^= (0xf0 & OnPixels[r0[2]]); - else - *ptr ^= (0xf0 & OffPixels[r0[2]]); - - if ((r0[3] & 15) > dither[x & 3]) - *ptr++ ^= (0x0f & OnPixels[r0[3]]); - else - *ptr++ ^= (0x0f & OffPixels[r0[3]]); - } - break; - - case 8 : - for (x = xsize * 4; x > 0; x --, r0 ++, r1 ++) - if (*r0 == *r1) - *ptr++ = *r0; - else - *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; - break; - } - break; - - case CUPS_ORDER_BANDED : - cptr = ptr; - mptr = ptr + bandwidth; - yptr = ptr + 2 * bandwidth; - kptr = ptr + 3 * bandwidth; - - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize; x > 0; x --) - { - pc = *r0++ > dither[x & 15]; - pm = *r0++ > dither[x & 15]; - py = *r0++ > dither[x & 15]; - - if (pc && pm && py) - *kptr ^= bitmask; - else - { - if (pc) - *cptr ^= bitmask; - if (pm) - *mptr ^= bitmask; - if (py) - *yptr ^= bitmask; - } - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - cptr ++; - mptr ++; - yptr ++; - kptr ++; - } - } - break; - - case 2 : - bitmask = 0xc0 >> (bitoffset & 7); - dither = Floyd8x8[y & 7]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 63) > dither[x & 7]) - *cptr ^= (bitmask & OnPixels[*r0++]); - else - *cptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *mptr ^= (bitmask & OnPixels[*r0++]); - else - *mptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *yptr ^= (bitmask & OnPixels[*r0++]); - else - *yptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *kptr ^= (bitmask & OnPixels[*r0++]); - else - *kptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask > 3) - bitmask >>= 2; - else - { - bitmask = 0xc0; - - cptr ++; - mptr ++; - yptr ++; - kptr ++; - } - } - break; - - case 4 : - bitmask = 0xf0 >> (bitoffset & 7); - dither = Floyd4x4[y & 3]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 15) > dither[x & 3]) - *cptr ^= (bitmask & OnPixels[*r0++]); - else - *cptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *mptr ^= (bitmask & OnPixels[*r0++]); - else - *mptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *yptr ^= (bitmask & OnPixels[*r0++]); - else - *yptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *kptr ^= (bitmask & OnPixels[*r0++]); - else - *kptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask == 0xf0) - bitmask = 0x0f; - else - { - bitmask = 0xf0; - - cptr ++; - mptr ++; - yptr ++; - kptr ++; - } - } - break; - - case 8 : - for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) - { - if (r0[0] == r1[0]) - *cptr++ = r0[0]; - else - *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; - - if (r0[1] == r1[1]) - *mptr++ = r0[1]; - else - *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; - - if (r0[2] == r1[2]) - *yptr++ = r0[2]; - else - *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; - - if (r0[3] == r1[3]) - *kptr++ = r0[3]; - else - *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize; - } - break; - } - break; - - case CUPS_ORDER_PLANAR : - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize; x > 0; x --) - { - pc = *r0++ > dither[x & 15]; - pm = *r0++ > dither[x & 15]; - py = *r0++ > dither[x & 15]; - - if ((pc && pm && py && z == 3) || - (pc && z == 0) || (pm && z == 1) || (py && z == 2)) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - - case 2 : - bitmask = 0xc0 >> (bitoffset & 7); - dither = Floyd8x8[y & 7]; - r0 += z; - - for (x = xsize; x > 0; x --, r0 += 4) - { - if ((*r0 & 63) > dither[x & 7]) - *ptr ^= (bitmask & OnPixels[*r0]); - else - *ptr ^= (bitmask & OffPixels[*r0]); - - if (bitmask > 3) - bitmask >>= 2; - else - { - bitmask = 0xc0; - - ptr ++; - } - } - break; - - case 4 : - bitmask = 0xf0 >> (bitoffset & 7); - dither = Floyd4x4[y & 3]; - r0 += z; - - for (x = xsize; x > 0; x --, r0 += 4) - { - if ((*r0 & 15) > dither[x & 3]) - *ptr ^= (bitmask & OnPixels[*r0]); - else - *ptr ^= (bitmask & OffPixels[*r0]); - - if (bitmask == 0xf0) - bitmask = 0x0f; - else - { - bitmask = 0xf0; - - ptr ++; - } - } - break; - - case 8 : - r0 += z; - r1 += z; - - for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) - { - if (*r0 == *r1) - *ptr++ = *r0; - else - *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; - } - break; - } - break; - } -} - - -/* - * 'format_K()' - Convert image data to black. - */ - -static void -format_K(cups_page_header2_t *header, /* I - Page header */ - unsigned char *row, /* IO - Bitmap data for device */ - int y, /* I - Current row */ - int z, /* I - Current plane */ - int xsize, /* I - Width of image data */ - int ysize, /* I - Height of image data */ - int yerr0, /* I - Top Y error */ - int yerr1, /* I - Bottom Y error */ - cups_ib_t *r0, /* I - Primary image data */ - cups_ib_t *r1) /* I - Image data for interpolation */ -{ - cups_ib_t *ptr, /* Pointer into row */ - bitmask; /* Current mask for pixel */ - int bitoffset; /* Current offset in line */ - int x, /* Current X coordinate on page */ - *dither; /* Pointer into dither array */ - - - (void)z; - - switch (XPosition) - { - case -1 : - bitoffset = 0; - break; - default : - bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); - break; - case 1 : - bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); - break; - } - - ptr = row + bitoffset / 8; - - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize; x > 0; x --) - { - if (*r0++ > dither[x & 15]) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - - case 2 : - bitmask = 0xc0 >> (bitoffset & 7); - dither = Floyd8x8[y & 7]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 63) > dither[x & 7]) - *ptr ^= (bitmask & OnPixels[*r0++]); - else - *ptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask > 3) - bitmask >>= 2; - else - { - bitmask = 0xc0; - - ptr ++; - } - } - break; - - case 4 : - bitmask = 0xf0 >> (bitoffset & 7); - dither = Floyd4x4[y & 3]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 15) > dither[x & 3]) - *ptr ^= (bitmask & OnPixels[*r0++]); - else - *ptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask == 0xf0) - bitmask = 0x0f; - else - { - bitmask = 0xf0; - - ptr ++; - } - } - break; - - case 8 : - for (x = xsize; x > 0; x --, r0 ++, r1 ++) - { - if (*r0 == *r1) - *ptr++ = *r0; - else - *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; - } - break; - } -} - - -/* - * 'format_KCMY()' - Convert image data to KCMY. - */ - -static void -format_KCMY(cups_page_header2_t *header,/* I - Page header */ - unsigned char *row, /* IO - Bitmap data for device */ - int y, /* I - Current row */ - int z, /* I - Current plane */ - int xsize, /* I - Width of image data */ - int ysize, /* I - Height of image data */ - int yerr0, /* I - Top Y error */ - int yerr1, /* I - Bottom Y error */ - cups_ib_t *r0, /* I - Primary image data */ - cups_ib_t *r1) /* I - Image data for interpolation */ -{ - cups_ib_t *ptr, /* Pointer into row */ - *cptr, /* Pointer into cyan */ - *mptr, /* Pointer into magenta */ - *yptr, /* Pointer into yellow */ - *kptr, /* Pointer into black */ - bitmask; /* Current mask for pixel */ - int bitoffset; /* Current offset in line */ - int bandwidth; /* Width of a color band */ - int x, /* Current X coordinate on page */ - *dither; /* Pointer into dither array */ - int pc, pm, py; /* CMY pixels */ - - - switch (XPosition) - { - case -1 : - bitoffset = 0; - break; - default : - bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); - break; - case 1 : - bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); - break; - } - - ptr = row + bitoffset / 8; - bandwidth = header->cupsBytesPerLine / 4; - - switch (header->cupsColorOrder) - { - case CUPS_ORDER_CHUNKED : - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 128 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize ; x > 0; x --) - { - pc = *r0++ > dither[x & 15]; - pm = *r0++ > dither[x & 15]; - py = *r0++ > dither[x & 15]; - - if (pc && pm && py) - { - *ptr ^= bitmask; - bitmask >>= 3; - } - else - { - bitmask >>= 1; - if (pc) - *ptr ^= bitmask; - - bitmask >>= 1; - if (pm) - *ptr ^= bitmask; - - bitmask >>= 1; - if (py) - *ptr ^= bitmask; - } - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 128; - ptr ++; - } - } - break; - - case 2 : - dither = Floyd8x8[y & 7]; - - for (x = xsize ; x > 0; x --, r0 += 4) - { - if ((r0[3] & 63) > dither[x & 7]) - *ptr ^= (0xc0 & OnPixels[r0[3]]); - else - *ptr ^= (0xc0 & OffPixels[r0[3]]); - - if ((r0[0] & 63) > dither[x & 7]) - *ptr ^= (0x30 & OnPixels[r0[0]]); - else - *ptr ^= (0x30 & OffPixels[r0[0]]); - - if ((r0[1] & 63) > dither[x & 7]) - *ptr ^= (0x0c & OnPixels[r0[1]]); - else - *ptr ^= (0x0c & OffPixels[r0[1]]); - - if ((r0[2] & 63) > dither[x & 7]) - *ptr++ ^= (0x03 & OnPixels[r0[2]]); - else - *ptr++ ^= (0x03 & OffPixels[r0[2]]); - } - break; - - case 4 : - dither = Floyd4x4[y & 3]; - - for (x = xsize ; x > 0; x --, r0 += 4) - { - if ((r0[3] & 15) > dither[x & 3]) - *ptr ^= (0xf0 & OnPixels[r0[3]]); - else - *ptr ^= (0xf0 & OffPixels[r0[3]]); - - if ((r0[0] & 15) > dither[x & 3]) - *ptr++ ^= (0x0f & OnPixels[r0[0]]); - else - *ptr++ ^= (0x0f & OffPixels[r0[0]]); - - if ((r0[1] & 15) > dither[x & 3]) - *ptr ^= (0xf0 & OnPixels[r0[1]]); - else - *ptr ^= (0xf0 & OffPixels[r0[1]]); - - if ((r0[2] & 15) > dither[x & 3]) - *ptr++ ^= (0x0f & OnPixels[r0[2]]); - else - *ptr++ ^= (0x0f & OffPixels[r0[2]]); - } - break; - - case 8 : - for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) - { - if (r0[3] == r1[3]) - *ptr++ = r0[3]; - else - *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize; - - if (r0[0] == r1[0]) - *ptr++ = r0[0]; - else - *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; - - if (r0[1] == r1[1]) - *ptr++ = r0[1]; - else - *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; - - if (r0[2] == r1[2]) - *ptr++ = r0[2]; - else - *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; - } - break; - } - break; - - case CUPS_ORDER_BANDED : - kptr = ptr; - cptr = ptr + bandwidth; - mptr = ptr + 2 * bandwidth; - yptr = ptr + 3 * bandwidth; - - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize; x > 0; x --) - { - pc = *r0++ > dither[x & 15]; - pm = *r0++ > dither[x & 15]; - py = *r0++ > dither[x & 15]; - - if (pc && pm && py) - *kptr ^= bitmask; - else - { - if (pc) - *cptr ^= bitmask; - if (pm) - *mptr ^= bitmask; - if (py) - *yptr ^= bitmask; - } - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - cptr ++; - mptr ++; - yptr ++; - kptr ++; - } - } - break; - - case 2 : - bitmask = 0xc0 >> (bitoffset & 7); - dither = Floyd8x8[y & 7]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 63) > dither[x & 7]) - *cptr ^= (bitmask & OnPixels[*r0++]); - else - *cptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *mptr ^= (bitmask & OnPixels[*r0++]); - else - *mptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *yptr ^= (bitmask & OnPixels[*r0++]); - else - *yptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *kptr ^= (bitmask & OnPixels[*r0++]); - else - *kptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask > 3) - bitmask >>= 2; - else - { - bitmask = 0xc0; - - cptr ++; - mptr ++; - yptr ++; - kptr ++; - } - } - break; - - case 4 : - bitmask = 0xf0 >> (bitoffset & 7); - dither = Floyd4x4[y & 3]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 15) > dither[x & 3]) - *cptr ^= (bitmask & OnPixels[*r0++]); - else - *cptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *mptr ^= (bitmask & OnPixels[*r0++]); - else - *mptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *yptr ^= (bitmask & OnPixels[*r0++]); - else - *yptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *kptr ^= (bitmask & OnPixels[*r0++]); - else - *kptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask == 0xf0) - bitmask = 0x0f; - else - { - bitmask = 0xf0; - - cptr ++; - mptr ++; - yptr ++; - kptr ++; - } - } - break; - - case 8 : - for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) - { - if (r0[0] == r1[0]) - *cptr++ = r0[0]; - else - *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; - - if (r0[1] == r1[1]) - *mptr++ = r0[1]; - else - *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; - - if (r0[2] == r1[2]) - *yptr++ = r0[2]; - else - *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; - - if (r0[3] == r1[3]) - *kptr++ = r0[3]; - else - *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize; - } - break; - } - break; - - case CUPS_ORDER_PLANAR : - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize; x > 0; x --) - { - pc = *r0++ > dither[x & 15]; - pm = *r0++ > dither[x & 15]; - py = *r0++ > dither[x & 15]; - - if ((pc && pm && py && z == 0) || - (pc && z == 1) || (pm && z == 2) || (py && z == 3)) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - - case 2 : - bitmask = 0xc0 >> (bitoffset & 7); - dither = Floyd8x8[y & 7]; - if (z == 0) - r0 += 3; - else - r0 += z - 1; - - for (x = xsize; x > 0; x --, r0 += 4) - { - if ((*r0 & 63) > dither[x & 7]) - *ptr ^= (bitmask & OnPixels[*r0]); - else - *ptr ^= (bitmask & OffPixels[*r0]); - - if (bitmask > 3) - bitmask >>= 2; - else - { - bitmask = 0xc0; - - ptr ++; - } - } - break; - - case 4 : - bitmask = 0xf0 >> (bitoffset & 7); - dither = Floyd4x4[y & 3]; - if (z == 0) - r0 += 3; - else - r0 += z - 1; - - for (x = xsize; x > 0; x --, r0 += 4) - { - if ((*r0 & 15) > dither[x & 3]) - *ptr ^= (bitmask & OnPixels[*r0]); - else - *ptr ^= (bitmask & OffPixels[*r0]); - - if (bitmask == 0xf0) - bitmask = 0x0f; - else - { - bitmask = 0xf0; - - ptr ++; - } - } - break; - - case 8 : - if (z == 0) - { - r0 += 3; - r1 += 3; - } - else - { - r0 += z - 1; - r1 += z - 1; - } - - for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) - { - if (*r0 == *r1) - *ptr++ = *r0; - else - *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; - } - break; - } - break; - } -} - - -/* - * 'format_KCMYcm()' - Convert image data to KCMYcm. - */ - -static void -format_KCMYcm( - cups_page_header2_t *header, /* I - Page header */ - unsigned char *row, /* IO - Bitmap data for device */ - int y, /* I - Current row */ - int z, /* I - Current plane */ - int xsize, /* I - Width of image data */ - int ysize, /* I - Height of image data */ - int yerr0, /* I - Top Y error */ - int yerr1, /* I - Bottom Y error */ - cups_ib_t *r0, /* I - Primary image data */ - cups_ib_t *r1) /* I - Image data for interpolation */ -{ - int pc, pm, py, pk; /* Cyan, magenta, yellow, and black values */ - cups_ib_t *ptr, /* Pointer into row */ - *cptr, /* Pointer into cyan */ - *mptr, /* Pointer into magenta */ - *yptr, /* Pointer into yellow */ - *kptr, /* Pointer into black */ - *lcptr, /* Pointer into light cyan */ - *lmptr, /* Pointer into light magenta */ - bitmask; /* Current mask for pixel */ - int bitoffset; /* Current offset in line */ - int bandwidth; /* Width of a color band */ - int x, /* Current X coordinate on page */ - *dither; /* Pointer into dither array */ - - - switch (XPosition) - { - case -1 : - bitoffset = 0; - break; - default : - bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); - break; - case 1 : - bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); - break; - } - - ptr = row + bitoffset / 8; - bandwidth = header->cupsBytesPerLine / 6; - - switch (header->cupsColorOrder) - { - case CUPS_ORDER_CHUNKED : - dither = Floyd16x16[y & 15]; - - for (x = xsize ; x > 0; x --) - { - pc = *r0++ > dither[x & 15]; - pm = *r0++ > dither[x & 15]; - py = *r0++ > dither[x & 15]; - pk = pc && pm && py; - - if (pk) - *ptr++ ^= 32; /* Black */ - else if (pc && pm) - *ptr++ ^= 17; /* Blue (cyan + light magenta) */ - else if (pc && py) - *ptr++ ^= 6; /* Green (light cyan + yellow) */ - else if (pm && py) - *ptr++ ^= 12; /* Red (magenta + yellow) */ - else if (pc) - *ptr++ ^= 16; - else if (pm) - *ptr++ ^= 8; - else if (py) - *ptr++ ^= 4; - else - ptr ++; - } - break; - - case CUPS_ORDER_BANDED : - kptr = ptr; - cptr = ptr + bandwidth; - mptr = ptr + 2 * bandwidth; - yptr = ptr + 3 * bandwidth; - lcptr = ptr + 4 * bandwidth; - lmptr = ptr + 5 * bandwidth; - - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize; x > 0; x --) - { - pc = *r0++ > dither[x & 15]; - pm = *r0++ > dither[x & 15]; - py = *r0++ > dither[x & 15]; - pk = pc && pm && py; - - if (pk) - *kptr ^= bitmask; /* Black */ - else if (pc && pm) - { - *cptr ^= bitmask; /* Blue (cyan + light magenta) */ - *lmptr ^= bitmask; - } - else if (pc && py) - { - *lcptr ^= bitmask; /* Green (light cyan + yellow) */ - *yptr ^= bitmask; - } - else if (pm && py) - { - *mptr ^= bitmask; /* Red (magenta + yellow) */ - *yptr ^= bitmask; - } - else if (pc) - *cptr ^= bitmask; - else if (pm) - *mptr ^= bitmask; - else if (py) - *yptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - cptr ++; - mptr ++; - yptr ++; - kptr ++; - lcptr ++; - lmptr ++; - } - } - break; - - case CUPS_ORDER_PLANAR : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize; x > 0; x --) - { - pc = *r0++ > dither[x & 15]; - pm = *r0++ > dither[x & 15]; - py = *r0++ > dither[x & 15]; - pk = pc && pm && py; - - if (pk && z == 0) - *ptr ^= bitmask; - else if (pc && pm && (z == 1 || z == 5)) - *ptr ^= bitmask; /* Blue (cyan + light magenta) */ - else if (pc && py && (z == 3 || z == 4)) - *ptr ^= bitmask; /* Green (light cyan + yellow) */ - else if (pm && py && (z == 2 || z == 3)) - *ptr ^= bitmask; /* Red (magenta + yellow) */ - else if (pc && z == 1) - *ptr ^= bitmask; - else if (pm && z == 2) - *ptr ^= bitmask; - else if (py && z == 3) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - } -} - - -/* - * 'format_RGBA()' - Convert image data to RGBA/RGBW. - */ - -static void -format_RGBA(cups_page_header2_t *header,/* I - Page header */ - unsigned char *row, /* IO - Bitmap data for device */ - int y, /* I - Current row */ - int z, /* I - Current plane */ - int xsize, /* I - Width of image data */ - int ysize, /* I - Height of image data */ - int yerr0, /* I - Top Y error */ - int yerr1, /* I - Bottom Y error */ - cups_ib_t *r0, /* I - Primary image data */ - cups_ib_t *r1) /* I - Image data for interpolation */ -{ - cups_ib_t *ptr, /* Pointer into row */ - *cptr, /* Pointer into cyan */ - *mptr, /* Pointer into magenta */ - *yptr, /* Pointer into yellow */ - bitmask; /* Current mask for pixel */ - int bitoffset; /* Current offset in line */ - int bandwidth; /* Width of a color band */ - int x, /* Current X coordinate on page */ - *dither; /* Pointer into dither array */ - - - switch (XPosition) - { - case -1 : - bitoffset = 0; - break; - default : - bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); - break; - case 1 : - bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); - break; - } - - ptr = row + bitoffset / 8; - bandwidth = header->cupsBytesPerLine / 4; - - switch (header->cupsColorOrder) - { - case CUPS_ORDER_CHUNKED : - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 128 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize ; x > 0; x --) - { - if (*r0++ > dither[x & 15]) - *ptr ^= bitmask; - bitmask >>= 1; - - if (*r0++ > dither[x & 15]) - *ptr ^= bitmask; - bitmask >>= 1; - - if (*r0++ > dither[x & 15]) - *ptr ^= bitmask; - - if (bitmask > 2) - bitmask >>= 2; - else - { - bitmask = 128; - ptr ++; - } - } - break; - - case 2 : - dither = Floyd8x8[y & 7]; - - for (x = xsize ; x > 0; x --, r0 += 3) - { - if ((r0[0] & 63) > dither[x & 7]) - *ptr ^= (0xc0 & OnPixels[r0[0]]); - else - *ptr ^= (0xc0 & OffPixels[r0[0]]); - - if ((r0[1] & 63) > dither[x & 7]) - *ptr ^= (0x30 & OnPixels[r0[1]]); - else - *ptr ^= (0x30 & OffPixels[r0[1]]); - - if ((r0[2] & 63) > dither[x & 7]) - *ptr ^= (0x0c & OnPixels[r0[2]]); - else - *ptr ^= (0x0c & OffPixels[r0[2]]); - - ptr ++; - } - break; - - case 4 : - dither = Floyd4x4[y & 3]; - - for (x = xsize ; x > 0; x --, r0 += 3) - { - if ((r0[0] & 15) > dither[x & 3]) - *ptr ^= (0xf0 & OnPixels[r0[0]]); - else - *ptr ^= (0xf0 & OffPixels[r0[0]]); - - if ((r0[1] & 15) > dither[x & 3]) - *ptr++ ^= (0x0f & OnPixels[r0[1]]); - else - *ptr++ ^= (0x0f & OffPixels[r0[1]]); - - if ((r0[2] & 15) > dither[x & 3]) - *ptr ^= (0xf0 & OnPixels[r0[2]]); - else - *ptr ^= (0xf0 & OffPixels[r0[2]]); - - ptr ++; - } - break; - - case 8 : - for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) - { - if (r0[0] == r1[0]) - *ptr++ = r0[0]; - else - *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; - - if (r0[1] == r1[1]) - *ptr++ = r0[1]; - else - *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; - - if (r0[2] == r1[2]) - *ptr++ = r0[2]; - else - *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; - - ptr ++; - } - break; - } - break; - - case CUPS_ORDER_BANDED : - cptr = ptr; - mptr = ptr + bandwidth; - yptr = ptr + 2 * bandwidth; - - memset(ptr + 3 * bandwidth, 255, bandwidth); - - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize; x > 0; x --) - { - if (*r0++ > dither[x & 15]) - *cptr ^= bitmask; - if (*r0++ > dither[x & 15]) - *mptr ^= bitmask; - if (*r0++ > dither[x & 15]) - *yptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - cptr ++; - mptr ++; - yptr ++; - } - } - break; - - case 2 : - bitmask = 0xc0 >> (bitoffset & 7); - dither = Floyd8x8[y & 7]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 63) > dither[x & 7]) - *cptr ^= (bitmask & OnPixels[*r0++]); - else - *cptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *mptr ^= (bitmask & OnPixels[*r0++]); - else - *mptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *yptr ^= (bitmask & OnPixels[*r0++]); - else - *yptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask > 3) - bitmask >>= 2; - else - { - bitmask = 0xc0; - - cptr ++; - mptr ++; - yptr ++; - } - } - break; - - case 4 : - bitmask = 0xf0 >> (bitoffset & 7); - dither = Floyd4x4[y & 3]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 15) > dither[x & 3]) - *cptr ^= (bitmask & OnPixels[*r0++]); - else - *cptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *mptr ^= (bitmask & OnPixels[*r0++]); - else - *mptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *yptr ^= (bitmask & OnPixels[*r0++]); - else - *yptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask == 0xf0) - bitmask = 0x0f; - else - { - bitmask = 0xf0; - - cptr ++; - mptr ++; - yptr ++; - } - } - break; - - case 8 : - for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) - { - if (r0[0] == r1[0]) - *cptr++ = r0[0]; - else - *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; - - if (r0[1] == r1[1]) - *mptr++ = r0[1]; - else - *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; - - if (r0[2] == r1[2]) - *yptr++ = r0[2]; - else - *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; - } - break; - } - break; - - case CUPS_ORDER_PLANAR : - if (z == 3) - { - memset(row, 255, header->cupsBytesPerLine); - break; - } - - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - switch (z) - { - case 0 : - for (x = xsize; x > 0; x --, r0 += 3) - { - if (r0[0] > dither[x & 15]) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - - case 1 : - for (x = xsize; x > 0; x --, r0 += 3) - { - if (r0[1] > dither[x & 15]) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - - case 2 : - for (x = xsize; x > 0; x --, r0 += 3) - { - if (r0[2] > dither[x & 15]) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - } - break; - - case 2 : - bitmask = 0xc0 >> (bitoffset & 7); - dither = Floyd8x8[y & 7]; - r0 += z; - - for (x = xsize; x > 0; x --, r0 += 3) - { - if ((*r0 & 63) > dither[x & 7]) - *ptr ^= (bitmask & OnPixels[*r0]); - else - *ptr ^= (bitmask & OffPixels[*r0]); - - if (bitmask > 3) - bitmask >>= 2; - else - { - bitmask = 0xc0; - - ptr ++; - } - } - break; - - case 4 : - bitmask = 0xf0 >> (bitoffset & 7); - dither = Floyd4x4[y & 3]; - r0 += z; - - for (x = xsize; x > 0; x --, r0 += 3) - { - if ((*r0 & 15) > dither[x & 3]) - *ptr ^= (bitmask & OnPixels[*r0]); - else - *ptr ^= (bitmask & OffPixels[*r0]); - - if (bitmask == 0xf0) - bitmask = 0x0f; - else - { - bitmask = 0xf0; - - ptr ++; - } - } - break; - - case 8 : - r0 += z; - r1 += z; - - for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) - { - if (*r0 == *r1) - *ptr++ = *r0; - else - *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; - } - break; - } - break; - } -} - - -/* - * 'format_W()' - Convert image data to luminance. - */ - -static void -format_W(cups_page_header2_t *header, /* I - Page header */ - unsigned char *row, /* IO - Bitmap data for device */ - int y, /* I - Current row */ - int z, /* I - Current plane */ - int xsize, /* I - Width of image data */ - int ysize, /* I - Height of image data */ - int yerr0, /* I - Top Y error */ - int yerr1, /* I - Bottom Y error */ - cups_ib_t *r0, /* I - Primary image data */ - cups_ib_t *r1) /* I - Image data for interpolation */ -{ - cups_ib_t *ptr, /* Pointer into row */ - bitmask; /* Current mask for pixel */ - int bitoffset; /* Current offset in line */ - int x, /* Current X coordinate on page */ - *dither; /* Pointer into dither array */ - - - (void)z; - - switch (XPosition) - { - case -1 : - bitoffset = 0; - break; - default : - bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); - break; - case 1 : - bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); - break; - } - - ptr = row + bitoffset / 8; - - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize; x > 0; x --) - { - if (*r0++ > dither[x & 15]) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - - case 2 : - bitmask = 0xc0 >> (bitoffset & 7); - dither = Floyd8x8[y & 7]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 63) > dither[x & 7]) - *ptr ^= (bitmask & OnPixels[*r0++]); - else - *ptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask > 3) - bitmask >>= 2; - else - { - bitmask = 0xc0; - - ptr ++; - } - } - break; - - case 4 : - bitmask = 0xf0 >> (bitoffset & 7); - dither = Floyd4x4[y & 3]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 15) > dither[x & 3]) - *ptr ^= (bitmask & OnPixels[*r0++]); - else - *ptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask == 0xf0) - bitmask = 0x0f; - else - { - bitmask = 0xf0; - - ptr ++; - } - } - break; - - case 8 : - for (x = xsize; x > 0; x --, r0 ++, r1 ++) - { - if (*r0 == *r1) - *ptr++ = *r0; - else - *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; - } - break; - } -} - - -/* - * 'format_YMC()' - Convert image data to YMC. - */ - -static void -format_YMC(cups_page_header2_t *header, /* I - Page header */ - unsigned char *row, /* IO - Bitmap data for device */ - int y, /* I - Current row */ - int z, /* I - Current plane */ - int xsize, /* I - Width of image data */ - int ysize, /* I - Height of image data */ - int yerr0, /* I - Top Y error */ - int yerr1, /* I - Bottom Y error */ - cups_ib_t *r0, /* I - Primary image data */ - cups_ib_t *r1) /* I - Image data for interpolation */ -{ - cups_ib_t *ptr, /* Pointer into row */ - *cptr, /* Pointer into cyan */ - *mptr, /* Pointer into magenta */ - *yptr, /* Pointer into yellow */ - bitmask; /* Current mask for pixel */ - int bitoffset; /* Current offset in line */ - int bandwidth; /* Width of a color band */ - int x, /* Current X coordinate on page */ - *dither; /* Pointer into dither array */ - - - switch (XPosition) - { - case -1 : - bitoffset = 0; - break; - default : - bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); - break; - case 1 : - bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); - break; - } - - ptr = row + bitoffset / 8; - bandwidth = header->cupsBytesPerLine / 3; - - switch (header->cupsColorOrder) - { - case CUPS_ORDER_CHUNKED : - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 64 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize ; x > 0; x --, r0 += 3) - { - if (r0[2] > dither[x & 15]) - *ptr ^= bitmask; - bitmask >>= 1; - - if (r0[1] > dither[x & 15]) - *ptr ^= bitmask; - bitmask >>= 1; - - if (r0[0] > dither[x & 15]) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 2; - else - { - bitmask = 64; - ptr ++; - } - } - break; - - case 2 : - dither = Floyd8x8[y & 7]; - - for (x = xsize ; x > 0; x --, r0 += 3) - { - if ((r0[2] & 63) > dither[x & 7]) - *ptr ^= (0x30 & OnPixels[r0[2]]); - else - *ptr ^= (0x30 & OffPixels[r0[2]]); - - if ((r0[1] & 63) > dither[x & 7]) - *ptr ^= (0x0c & OnPixels[r0[1]]); - else - *ptr ^= (0x0c & OffPixels[r0[1]]); - - if ((r0[0] & 63) > dither[x & 7]) - *ptr++ ^= (0x03 & OnPixels[r0[0]]); - else - *ptr++ ^= (0x03 & OffPixels[r0[0]]); - } - break; - - case 4 : - dither = Floyd4x4[y & 3]; - - for (x = xsize ; x > 0; x --, r0 += 3) - { - if ((r0[2] & 15) > dither[x & 3]) - *ptr++ ^= (0x0f & OnPixels[r0[2]]); - else - *ptr++ ^= (0x0f & OffPixels[r0[2]]); - - if ((r0[1] & 15) > dither[x & 3]) - *ptr ^= (0xf0 & OnPixels[r0[1]]); - else - *ptr ^= (0xf0 & OffPixels[r0[1]]); - - if ((r0[0] & 15) > dither[x & 3]) - *ptr++ ^= (0x0f & OnPixels[r0[0]]); - else - *ptr++ ^= (0x0f & OffPixels[r0[0]]); - } - break; - - case 8 : - for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) - { - if (r0[2] == r1[2]) - *ptr++ = r0[2]; - else - *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; - - if (r0[1] == r1[1]) - *ptr++ = r0[1]; - else - *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; - - if (r0[0] == r1[0]) - *ptr++ = r0[0]; - else - *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; - } - break; - } - break; - - case CUPS_ORDER_BANDED : - yptr = ptr; - mptr = ptr + bandwidth; - cptr = ptr + 2 * bandwidth; - - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize; x > 0; x --) - { - if (*r0++ > dither[x & 15]) - *cptr ^= bitmask; - if (*r0++ > dither[x & 15]) - *mptr ^= bitmask; - if (*r0++ > dither[x & 15]) - *yptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - cptr ++; - mptr ++; - yptr ++; - } - } - break; - - case 2 : - bitmask = 0xc0 >> (bitoffset & 7); - dither = Floyd8x8[y & 7]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 63) > dither[x & 7]) - *cptr ^= (bitmask & OnPixels[*r0++]); - else - *cptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *mptr ^= (bitmask & OnPixels[*r0++]); - else - *mptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *yptr ^= (bitmask & OnPixels[*r0++]); - else - *yptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask > 3) - bitmask >>= 2; - else - { - bitmask = 0xc0; - - cptr ++; - mptr ++; - yptr ++; - } - } - break; - - case 4 : - bitmask = 0xf0 >> (bitoffset & 7); - dither = Floyd4x4[y & 3]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 15) > dither[x & 3]) - *cptr ^= (bitmask & OnPixels[*r0++]); - else - *cptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *mptr ^= (bitmask & OnPixels[*r0++]); - else - *mptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *yptr ^= (bitmask & OnPixels[*r0++]); - else - *yptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask == 0xf0) - bitmask = 0x0f; - else - { - bitmask = 0xf0; - - cptr ++; - mptr ++; - yptr ++; - } - } - break; - - case 8 : - for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) - { - if (r0[0] == r1[0]) - *cptr++ = r0[0]; - else - *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; - - if (r0[1] == r1[1]) - *mptr++ = r0[1]; - else - *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; - - if (r0[2] == r1[2]) - *yptr++ = r0[2]; - else - *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; - } - break; - } - break; - - case CUPS_ORDER_PLANAR : - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - switch (z) - { - case 2 : - for (x = xsize; x > 0; x --, r0 += 3) - { - if (r0[0] > dither[x & 15]) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - - case 1 : - for (x = xsize; x > 0; x --, r0 += 3) - { - if (r0[1] > dither[x & 15]) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - - case 0 : - for (x = xsize; x > 0; x --, r0 += 3) - { - if (r0[2] > dither[x & 15]) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - } - break; - - case 2 : - bitmask = 0xc0 >> (bitoffset & 7); - dither = Floyd8x8[y & 7]; - z = 2 - z; - r0 += z; - - for (x = xsize; x > 0; x --, r0 += 3) - { - if ((*r0 & 63) > dither[x & 7]) - *ptr ^= (bitmask & OnPixels[*r0]); - else - *ptr ^= (bitmask & OffPixels[*r0]); - - if (bitmask > 3) - bitmask >>= 2; - else - { - bitmask = 0xc0; - - ptr ++; - } - } - break; - - case 4 : - bitmask = 0xf0 >> (bitoffset & 7); - dither = Floyd4x4[y & 3]; - z = 2 - z; - r0 += z; - - for (x = xsize; x > 0; x --, r0 += 3) - { - if ((*r0 & 15) > dither[x & 3]) - *ptr ^= (bitmask & OnPixels[*r0]); - else - *ptr ^= (bitmask & OffPixels[*r0]); - - if (bitmask == 0xf0) - bitmask = 0x0f; - else - { - bitmask = 0xf0; - - ptr ++; - } - } - break; - - case 8 : - z = 2 - z; - r0 += z; - r1 += z; - - for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) - { - if (*r0 == *r1) - *ptr++ = *r0; - else - *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; - } - break; - } - break; - } -} - - -/* - * 'format_YMCK()' - Convert image data to YMCK. - */ - -static void -format_YMCK(cups_page_header2_t *header,/* I - Page header */ - unsigned char *row, /* IO - Bitmap data for device */ - int y, /* I - Current row */ - int z, /* I - Current plane */ - int xsize, /* I - Width of image data */ - int ysize, /* I - Height of image data */ - int yerr0, /* I - Top Y error */ - int yerr1, /* I - Bottom Y error */ - cups_ib_t *r0, /* I - Primary image data */ - cups_ib_t *r1) /* I - Image data for interpolation */ -{ - cups_ib_t *ptr, /* Pointer into row */ - *cptr, /* Pointer into cyan */ - *mptr, /* Pointer into magenta */ - *yptr, /* Pointer into yellow */ - *kptr, /* Pointer into black */ - bitmask; /* Current mask for pixel */ - int bitoffset; /* Current offset in line */ - int bandwidth; /* Width of a color band */ - int x, /* Current X coordinate on page */ - *dither; /* Pointer into dither array */ - int pc, pm, py; /* CMY pixels */ - - - switch (XPosition) - { - case -1 : - bitoffset = 0; - break; - default : - bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); - break; - case 1 : - bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); - break; - } - - ptr = row + bitoffset / 8; - bandwidth = header->cupsBytesPerLine / 4; - - switch (header->cupsColorOrder) - { - case CUPS_ORDER_CHUNKED : - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 128 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize ; x > 0; x --) - { - pc = *r0++ > dither[x & 15]; - pm = *r0++ > dither[x & 15]; - py = *r0++ > dither[x & 15]; - - if (pc && pm && py) - { - bitmask >>= 3; - *ptr ^= bitmask; - } - else - { - if (py) - *ptr ^= bitmask; - bitmask >>= 1; - - if (pm) - *ptr ^= bitmask; - bitmask >>= 1; - - if (pc) - *ptr ^= bitmask; - bitmask >>= 1; - } - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 128; - - ptr ++; - } - } - break; - - case 2 : - dither = Floyd8x8[y & 7]; - - for (x = xsize ; x > 0; x --, r0 += 4) - { - if ((r0[2] & 63) > dither[x & 7]) - *ptr ^= (0xc0 & OnPixels[r0[2]]); - else - *ptr ^= (0xc0 & OffPixels[r0[2]]); - - if ((r0[1] & 63) > dither[x & 7]) - *ptr ^= (0x30 & OnPixels[r0[1]]); - else - *ptr ^= (0x30 & OffPixels[r0[1]]); - - if ((r0[0] & 63) > dither[x & 7]) - *ptr ^= (0x0c & OnPixels[r0[0]]); - else - *ptr ^= (0x0c & OffPixels[r0[0]]); - - if ((r0[3] & 63) > dither[x & 7]) - *ptr++ ^= (0x03 & OnPixels[r0[3]]); - else - *ptr++ ^= (0x03 & OffPixels[r0[3]]); - } - break; - - case 4 : - dither = Floyd4x4[y & 3]; - - for (x = xsize ; x > 0; x --, r0 += 4) - { - if ((r0[2] & 15) > dither[x & 3]) - *ptr ^= (0xf0 & OnPixels[r0[2]]); - else - *ptr ^= (0xf0 & OffPixels[r0[2]]); - - if ((r0[1] & 15) > dither[x & 3]) - *ptr++ ^= (0x0f & OnPixels[r0[1]]); - else - *ptr++ ^= (0x0f & OffPixels[r0[1]]); - - if ((r0[0] & 15) > dither[x & 3]) - *ptr ^= (0xf0 & OnPixels[r0[0]]); - else - *ptr ^= (0xf0 & OffPixels[r0[0]]); - - if ((r0[3] & 15) > dither[x & 3]) - *ptr++ ^= (0x0f & OnPixels[r0[3]]); - else - *ptr++ ^= (0x0f & OffPixels[r0[3]]); - } - break; - - case 8 : - for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) - { - if (r0[2] == r1[2]) - *ptr++ = r0[2]; - else - *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; - - if (r0[1] == r1[1]) - *ptr++ = r0[1]; - else - *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; - - if (r0[0] == r1[0]) - *ptr++ = r0[0]; - else - *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; - - if (r0[3] == r1[3]) - *ptr++ = r0[3]; - else - *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize; - } - break; - } - break; - - case CUPS_ORDER_BANDED : - yptr = ptr; - mptr = ptr + bandwidth; - cptr = ptr + 2 * bandwidth; - kptr = ptr + 3 * bandwidth; - - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize; x > 0; x --) - { - pc = *r0++ > dither[x & 15]; - pm = *r0++ > dither[x & 15]; - py = *r0++ > dither[x & 15]; - - if (pc && pm && py) - *kptr ^= bitmask; - else - { - if (pc) - *cptr ^= bitmask; - if (pm) - *mptr ^= bitmask; - if (py) - *yptr ^= bitmask; - } - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - - cptr ++; - mptr ++; - yptr ++; - kptr ++; - } - } - break; - - case 2 : - bitmask = 0xc0 >> (bitoffset & 7); - dither = Floyd8x8[y & 7]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 63) > dither[x & 7]) - *cptr ^= (bitmask & OnPixels[*r0++]); - else - *cptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *mptr ^= (bitmask & OnPixels[*r0++]); - else - *mptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *yptr ^= (bitmask & OnPixels[*r0++]); - else - *yptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 63) > dither[x & 7]) - *kptr ^= (bitmask & OnPixels[*r0++]); - else - *kptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask > 3) - bitmask >>= 2; - else - { - bitmask = 0xc0; - - cptr ++; - mptr ++; - yptr ++; - kptr ++; - } - } - break; - - case 4 : - bitmask = 0xf0 >> (bitoffset & 7); - dither = Floyd4x4[y & 3]; - - for (x = xsize; x > 0; x --) - { - if ((*r0 & 15) > dither[x & 3]) - *cptr ^= (bitmask & OnPixels[*r0++]); - else - *cptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *mptr ^= (bitmask & OnPixels[*r0++]); - else - *mptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *yptr ^= (bitmask & OnPixels[*r0++]); - else - *yptr ^= (bitmask & OffPixels[*r0++]); - - if ((*r0 & 15) > dither[x & 3]) - *kptr ^= (bitmask & OnPixels[*r0++]); - else - *kptr ^= (bitmask & OffPixels[*r0++]); - - if (bitmask == 0xf0) - bitmask = 0x0f; - else - { - bitmask = 0xf0; - - cptr ++; - mptr ++; - yptr ++; - kptr ++; - } - } - break; - - case 8 : - for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) - { - if (r0[0] == r1[0]) - *cptr++ = r0[0]; - else - *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; - - if (r0[1] == r1[1]) - *mptr++ = r0[1]; - else - *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; - - if (r0[2] == r1[2]) - *yptr++ = r0[2]; - else - *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; - - if (r0[3] == r1[3]) - *kptr++ = r0[3]; - else - *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize; - } - break; - } - break; - - case CUPS_ORDER_PLANAR : - switch (header->cupsBitsPerColor) - { - case 1 : - bitmask = 0x80 >> (bitoffset & 7); - dither = Floyd16x16[y & 15]; - - for (x = xsize; x > 0; x --) - { - pc = *r0++ > dither[x & 15]; - pm = *r0++ > dither[x & 15]; - py = *r0++ > dither[x & 15]; - - if ((pc && pm && py && z == 3) || - (pc && z == 2) || (pm && z == 1) || (py && z == 0)) - *ptr ^= bitmask; - - if (bitmask > 1) - bitmask >>= 1; - else - { - bitmask = 0x80; - ptr ++; - } - } - break; - - case 2 : - bitmask = 0xc0 >> (bitoffset & 7); - dither = Floyd8x8[y & 7]; - if (z == 3) - r0 += 3; - else - r0 += 2 - z; - - for (x = xsize; x > 0; x --, r0 += 4) - { - if ((*r0 & 63) > dither[x & 7]) - *ptr ^= (bitmask & OnPixels[*r0]); - else - *ptr ^= (bitmask & OffPixels[*r0]); - - if (bitmask > 3) - bitmask >>= 2; - else - { - bitmask = 0xc0; - - ptr ++; - } - } - break; - - case 4 : - bitmask = 0xf0 >> (bitoffset & 7); - dither = Floyd4x4[y & 3]; - if (z == 3) - r0 += 3; - else - r0 += 2 - z; - - for (x = xsize; x > 0; x --, r0 += 4) - { - if ((*r0 & 15) > dither[x & 3]) - *ptr ^= (bitmask & OnPixels[*r0]); - else - *ptr ^= (bitmask & OffPixels[*r0]); - - if (bitmask == 0xf0) - bitmask = 0x0f; - else - { - bitmask = 0xf0; - - ptr ++; - } - } - break; - - case 8 : - if (z == 3) - { - r0 += 3; - r1 += 3; - } - else - { - r0 += 2 - z; - r1 += 2 - z; - } - - for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) - { - if (*r0 == *r1) - *ptr++ = *r0; - else - *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; - } - break; - } - break; - } -} - - -/* - * 'make_lut()' - Make a lookup table given gamma and brightness values. - */ - -static void -make_lut(cups_ib_t *lut, /* I - Lookup table */ - int colorspace, /* I - Colorspace */ - float g, /* I - Image gamma */ - float b) /* I - Image brightness */ -{ - int i; /* Looping var */ - int v; /* Current value */ - - - g = 1.0 / g; - b = 1.0 / b; - - for (i = 0; i < 256; i ++) - { - if (colorspace < 0) - v = 255.0 * b * (1.0 - pow(1.0 - (float)i / 255.0, g)) + 0.5; - else - v = 255.0 * (1.0 - b * (1.0 - pow((float)i / 255.0, g))) + 0.5; - - if (v < 0) - *lut++ = 0; - else if (v > 255) - *lut++ = 255; - else - *lut++ = v; - } -} - - -/* - * 'raster_cb()' - Validate the page header. - */ - -static int /* O - 0 if OK, -1 if not */ -raster_cb( - cups_page_header2_t *header, /* IO - Raster header */ - int preferred_bits) /* I - Preferred bits per color */ -{ - /* - * Ensure that colorimetric colorspaces use at least 8 bits per - * component... - */ - - if ((header->cupsColorSpace == CUPS_CSPACE_CIEXYZ || - header->cupsColorSpace == CUPS_CSPACE_CIELab || - header->cupsColorSpace >= CUPS_CSPACE_ICC1) && - header->cupsBitsPerColor < 8) - header->cupsBitsPerColor = 8; - - return (0); -} - - -/* - * End of "$Id: imagetoraster.c 7306 2008-02-15 00:52:38Z mike $". - */ diff --git a/filter/interpret.c b/filter/interpret.c index 017e578dc..32e6821db 100644 --- a/filter/interpret.c +++ b/filter/interpret.c @@ -3,7 +3,7 @@ * * PPD command interpreter for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1993-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -40,7 +40,7 @@ * Include necessary headers... */ -#include "image-private.h" +#include /* diff --git a/filter/libcupsimage.order b/filter/libcupsimage.order deleted file mode 100644 index e69de29bb..000000000 diff --git a/filter/pdftops.c b/filter/pdftops.c deleted file mode 100644 index 76da65dba..000000000 --- a/filter/pdftops.c +++ /dev/null @@ -1,621 +0,0 @@ -/* - * "$Id$" - * - * PDF to PostScript filter front-end for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * main() - Main entry for filter... - * cancel_job() - Flag the job as canceled. - */ - -/* - * Include necessary headers... - */ - -#include -#include -#include -#include -#include -#include -#include - - -/* - * Local functions... - */ - -static void cancel_job(int sig); - - -/* - * Local globals... - */ - -static int job_canceled = 0; - - -/* - * 'main()' - Main entry for filter... - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line args */ - char *argv[]) /* I - Command-line arguments */ -{ - int fd; /* Copy file descriptor */ - char *filename, /* PDF file to convert */ - tempfile[1024]; /* Temporary file */ - char buffer[8192]; /* Copy buffer */ - int bytes; /* Bytes copied */ - int num_options; /* Number of options */ - cups_option_t *options; /* Options */ - const char *val; /* Option value */ - int orientation, /* Output orientation */ - fit; /* Fit output to default page size? */ - ppd_file_t *ppd; /* PPD file */ - ppd_size_t *size; /* Current page size */ - int pdf_pid, /* Process ID for pdftops */ - pdf_argc, /* Number of args for pdftops */ - pstops_pid, /* Process ID of pstops filter */ - pstops_pipe[2], /* Pipe to pstops filter */ - wait_children, /* Number of child processes left */ - wait_pid, /* Process ID from wait() */ - wait_status, /* Status from child */ - exit_status = 0; /* Exit status */ - char *pdf_argv[100], /* Arguments for pdftops/gs */ - pdf_width[255], /* Paper width */ - pdf_height[255], /* Paper height */ - pstops_path[1024], /* Path to pstops program */ - *pstops_argv[7], /* Arguments for pstops filter */ - *pstops_options, /* Options for pstops filter */ - *pstops_start, /* Start of pstops filter option */ - *pstops_end; /* End of pstops filter option */ - const char *cups_serverbin; /* CUPS_SERVERBIN environment variable */ -#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) - struct sigaction action; /* Actions for POSIX signals */ -#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ - - - /* - * Make sure status messages are not buffered... - */ - - setbuf(stderr, NULL); - - /* - * Ignore broken pipe signals... - */ - - signal(SIGPIPE, SIG_IGN); - - /* - * Make sure we have the right number of arguments for CUPS! - */ - - if (argc < 6 || argc > 7) - { - _cupsLangPrintf(stderr, - _("Usage: %s job user title copies options [filename]"), - argv[0]); - return (1); - } - - /* - * Register a signal handler to cleanly cancel a job. - */ - -#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ - sigset(SIGTERM, cancel_job); -#elif defined(HAVE_SIGACTION) - memset(&action, 0, sizeof(action)); - - sigemptyset(&action.sa_mask); - action.sa_handler = cancel_job; - sigaction(SIGTERM, &action, NULL); -#else - signal(SIGTERM, cancel_job); -#endif /* HAVE_SIGSET */ - - /* - * Copy stdin if needed... - */ - - if (argc == 6) - { - /* - * Copy stdin to a temp file... - */ - - if ((fd = cupsTempFd(tempfile, sizeof(tempfile))) < 0) - { - perror("DEBUG: Unable to copy PDF file"); - return (1); - } - - fprintf(stderr, "DEBUG: pdftops - copying to temp print file \"%s\"\n", - tempfile); - - while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0) - write(fd, buffer, bytes); - - close(fd); - - filename = tempfile; - } - else - { - /* - * Use the filename on the command-line... - */ - - filename = argv[6]; - tempfile[0] = '\0'; - } - - /* - * Load the PPD file and mark options... - */ - - ppd = ppdOpenFile(getenv("PPD")); - num_options = cupsParseOptions(argv[5], 0, &options); - - ppdMarkDefaults(ppd); - cupsMarkOptions(ppd, num_options, options); - - /* - * Build the pstops command-line... - */ - - if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL) - cups_serverbin = CUPS_SERVERBIN; - - snprintf(pstops_path, sizeof(pstops_path), "%s/filter/pstops", - cups_serverbin); - - pstops_options = strdup(argv[5]); - - if ((pstops_start = strstr(pstops_options, "fitplot")) != NULL && - (!pstops_start[7] || isspace(pstops_start[7] & 255))) - { - /* - * Strip [no]fitplot option... - */ - - pstops_end = pstops_start + 7; - - if ((pstops_start - pstops_options) >= 2 && - !strncmp(pstops_start - 2, "no", 2)) - pstops_start -= 2; - - while (*pstops_end && isspace(*pstops_end & 255)) - pstops_end ++; - - _cups_strcpy(pstops_start, pstops_end); - } - - if ((pstops_start = strstr(pstops_options, "fit-to-page")) != NULL && - (!pstops_start[11] || isspace(pstops_start[11] & 255))) - { - /* - * Strip [no]fit-to-page option... - */ - - pstops_end = pstops_start + 11; - - if ((pstops_start - pstops_options) >= 2 && - !strncmp(pstops_start - 2, "no", 2)) - pstops_start -= 2; - - while (*pstops_end && isspace(*pstops_end & 255)) - pstops_end ++; - - _cups_strcpy(pstops_start, pstops_end); - } - - if ((pstops_start = strstr(pstops_options, "landscape")) != NULL && - (!pstops_start[9] || isspace(pstops_start[9] & 255))) - { - /* - * Strip [no]landscape option... - */ - - pstops_end = pstops_start + 9; - - if ((pstops_start - pstops_options) >= 2 && - !strncmp(pstops_start - 2, "no", 2)) - pstops_start -= 2; - - while (*pstops_end && isspace(*pstops_end & 255)) - pstops_end ++; - - _cups_strcpy(pstops_start, pstops_end); - } - - if ((pstops_start = strstr(pstops_options, "orientation-requested=")) != NULL) - { - /* - * Strip [no]fitplot option... - */ - - pstops_end = pstops_start + 22; - while (*pstops_end && !isspace(*pstops_end & 255)) - pstops_end ++; - - _cups_strcpy(pstops_start, pstops_end); - } - - pstops_argv[0] = argv[0]; /* Printer */ - pstops_argv[1] = argv[1]; /* Job */ - pstops_argv[2] = argv[2]; /* User */ - pstops_argv[3] = argv[3]; /* Title */ - pstops_argv[4] = argv[4]; /* Copies */ - pstops_argv[5] = pstops_options; /* Options */ - pstops_argv[6] = NULL; - - /* - * Build the command-line for the pdftops or gs filter... - */ - -#ifdef HAVE_PDFTOPS - pdf_argv[0] = (char *)"pdftops"; - pdf_argc = 1; -#else - pdf_argv[0] = (char *)"gs"; - pdf_argv[1] = (char *)"-q"; - pdf_argv[2] = (char *)"-dNOPAUSE"; - pdf_argv[3] = (char *)"-dBATCH"; - pdf_argv[4] = (char *)"-dSAFER"; -# ifdef HAVE_GHOSTSCRIPT_PS2WRITE - pdf_argv[5] = (char *)"-sDEVICE=ps2write"; -# else - pdf_argv[5] = (char *)"-sDEVICE=pswrite"; -# endif /* HAVE_GHOSTSCRIPT_PS2WRITE */ - pdf_argv[6] = (char *)"-sOUTPUTFILE=%stdout"; - pdf_argc = 7; -#endif /* HAVE_PDFTOPS */ - - if (ppd) - { - /* - * Set language level and TrueType font handling... - */ - - if (ppd->language_level == 1) - { -#ifdef HAVE_PDFTOPS - pdf_argv[pdf_argc++] = (char *)"-level1"; - pdf_argv[pdf_argc++] = (char *)"-noembtt"; -#else - pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=1"; -#endif /* HAVE_PDFTOPS */ - } - else if (ppd->language_level == 2) - { -#ifdef HAVE_PDFTOPS - pdf_argv[pdf_argc++] = (char *)"-level2"; - if (!ppd->ttrasterizer) - pdf_argv[pdf_argc++] = (char *)"-noembtt"; -#else - pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=2"; -#endif /* HAVE_PDFTOPS */ - } - else -#ifdef HAVE_PDFTOPS - pdf_argv[pdf_argc++] = (char *)"-level3"; -#else - pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=3"; -#endif /* HAVE_PDFTOPS */ - - if ((val = cupsGetOption("fitplot", num_options, options)) == NULL) - val = cupsGetOption("fit-to-page", num_options, options); - - if (val && _cups_strcasecmp(val, "no") && _cups_strcasecmp(val, "off") && - _cups_strcasecmp(val, "false")) - fit = 1; - else - fit = 0; - - /* - * Set output page size... - */ - - size = ppdPageSize(ppd, NULL); - if (size && fit) - { - /* - * Got the size, now get the orientation... - */ - - orientation = 0; - - if ((val = cupsGetOption("landscape", num_options, options)) != NULL) - { - if (_cups_strcasecmp(val, "no") != 0 && _cups_strcasecmp(val, "off") != 0 && - _cups_strcasecmp(val, "false") != 0) - orientation = 1; - } - else if ((val = cupsGetOption("orientation-requested", num_options, - options)) != NULL) - { - /* - * Map IPP orientation values to 0 to 3: - * - * 3 = 0 degrees = 0 - * 4 = 90 degrees = 1 - * 5 = -90 degrees = 3 - * 6 = 180 degrees = 2 - */ - - orientation = atoi(val) - 3; - if (orientation >= 2) - orientation ^= 1; - } - -#ifdef HAVE_PDFTOPS - if (orientation & 1) - { - snprintf(pdf_width, sizeof(pdf_width), "%.0f", size->length); - snprintf(pdf_height, sizeof(pdf_height), "%.0f", size->width); - } - else - { - snprintf(pdf_width, sizeof(pdf_width), "%.0f", size->width); - snprintf(pdf_height, sizeof(pdf_height), "%.0f", size->length); - } - - pdf_argv[pdf_argc++] = (char *)"-paperw"; - pdf_argv[pdf_argc++] = pdf_width; - pdf_argv[pdf_argc++] = (char *)"-paperh"; - pdf_argv[pdf_argc++] = pdf_height; - pdf_argv[pdf_argc++] = (char *)"-expand"; - -#else - if (orientation & 1) - { - snprintf(pdf_width, sizeof(pdf_width), "-dDEVICEWIDTHPOINTS=%.0f", - size->length); - snprintf(pdf_height, sizeof(pdf_height), "-dDEVICEHEIGHTPOINTS=%.0f", - size->width); - } - else - { - snprintf(pdf_width, sizeof(pdf_width), "-dDEVICEWIDTHPOINTS=%.0f", - size->width); - snprintf(pdf_height, sizeof(pdf_height), "-dDEVICEHEIGHTPOINTS=%.0f", - size->length); - } - - pdf_argv[pdf_argc++] = pdf_width; - pdf_argv[pdf_argc++] = pdf_height; -#endif /* HAVE_PDFTOPS */ - } -#if defined(HAVE_PDFTOPS) && defined(HAVE_PDFTOPS_WITH_ORIGPAGESIZES) - else - { - /* - * Use the page sizes of the original PDF document, this way documents - * which contain pages of different sizes can be printed correctly - */ - - pdf_argv[pdf_argc++] = (char *)"-origpagesizes"; - } -#endif /* HAVE_PDFTOPS && HAVE_PDFTOPS_WITH_ORIGPAGESIZES */ - } - -#ifdef HAVE_PDFTOPS - pdf_argv[pdf_argc++] = filename; - pdf_argv[pdf_argc++] = (char *)"-"; -#else - pdf_argv[pdf_argc++] = (char *)"-c"; - pdf_argv[pdf_argc++] = (char *)"save pop"; - pdf_argv[pdf_argc++] = (char *)"-f"; - pdf_argv[pdf_argc++] = filename; -#endif /* HAVE_PDFTOPS */ - - pdf_argv[pdf_argc] = NULL; - - /* - * Execute "pdftops/gs | pstops"... - */ - - if (pipe(pstops_pipe)) - { - perror("DEBUG: Unable to create pipe"); - - exit_status = 1; - goto error; - } - - if ((pdf_pid = fork()) == 0) - { - /* - * Child comes here... - */ - - dup2(pstops_pipe[1], 1); - close(pstops_pipe[0]); - close(pstops_pipe[1]); - -#ifdef HAVE_PDFTOPS - execv(CUPS_PDFTOPS, pdf_argv); - perror("DEBUG: Unable to execute pdftops program"); -#else - execv(CUPS_GHOSTSCRIPT, pdf_argv); - perror("DEBUG: Unable to execute gs program"); -#endif /* HAVE_PDFTOPS */ - - exit(1); - } - else if (pdf_pid < 0) - { - /* - * Unable to fork! - */ - -#ifdef HAVE_PDFTOPS - perror("DEBUG: Unable to execute pdftops program"); -#else - perror("DEBUG: Unable to execute gs program"); -#endif /* HAVE_PDFTOPS */ - - exit_status = 1; - goto error; - } - - fprintf(stderr, "DEBUG: Started filter %s (PID %d)\n", pdf_argv[0], pdf_pid); - - if ((pstops_pid = fork()) == 0) - { - /* - * Child comes here... - */ - - dup2(pstops_pipe[0], 0); - close(pstops_pipe[0]); - close(pstops_pipe[1]); - - execv(pstops_path, pstops_argv); - perror("DEBUG: Unable to execute pstops program"); - - exit(1); - } - else if (pstops_pid < 0) - { - /* - * Unable to fork! - */ - - perror("DEBUG: Unable to execute pstops program"); - - exit_status = 1; - goto error; - } - - fprintf(stderr, "DEBUG: Started filter pstops (PID %d)\n", pstops_pid); - - close(pstops_pipe[0]); - close(pstops_pipe[1]); - - /* - * Wait for the child processes to exit... - */ - - wait_children = 2; - - while (wait_children > 0) - { - /* - * Wait until we get a valid process ID or the job is canceled... - */ - - while ((wait_pid = wait(&wait_status)) < 0 && errno == EINTR) - { - if (job_canceled) - { - kill(pdf_pid, SIGTERM); - kill(pstops_pid, SIGTERM); - - job_canceled = 0; - } - } - - if (wait_pid < 0) - break; - - wait_children --; - - /* - * Report child status... - */ - - if (wait_status) - { - if (WIFEXITED(wait_status)) - { - exit_status = WEXITSTATUS(wait_status); - - fprintf(stderr, "DEBUG: PID %d (%s) stopped with status %d!\n", - wait_pid, -#ifdef HAVE_PDFTOPS - wait_pid == pdf_pid ? "pdftops" : "pstops", -#else - wait_pid == pdf_pid ? "gs" : "pstops", -#endif /* HAVE_PDFTOPS */ - exit_status); - } - else if (WTERMSIG(wait_status) == SIGTERM) - { - fprintf(stderr, - "DEBUG: PID %d (%s) was terminated normally with signal %d!\n", - wait_pid, -#ifdef HAVE_PDFTOPS - wait_pid == pdf_pid ? "pdftops" : "pstops", -#else - wait_pid == pdf_pid ? "gs" : "pstops", -#endif /* HAVE_PDFTOPS */ - exit_status); - } - else - { - exit_status = WTERMSIG(wait_status); - - fprintf(stderr, "DEBUG: PID %d (%s) crashed on signal %d!\n", wait_pid, -#ifdef HAVE_PDFTOPS - wait_pid == pdf_pid ? "pdftops" : "pstops", -#else - wait_pid == pdf_pid ? "gs" : "pstops", -#endif /* HAVE_PDFTOPS */ - exit_status); - } - } - else - { - fprintf(stderr, "DEBUG: PID %d (%s) exited with no errors.\n", wait_pid, -#ifdef HAVE_PDFTOPS - wait_pid == pdf_pid ? "pdftops" : "pstops"); -#else - wait_pid == pdf_pid ? "gs" : "pstops"); -#endif /* HAVE_PDFTOPS */ - } - } - - /* - * Cleanup and exit... - */ - - error: - - if (tempfile[0]) - unlink(tempfile); - - return (exit_status); -} - - -/* - * 'cancel_job()' - Flag the job as canceled. - */ - -static void -cancel_job(int sig) /* I - Signal number (unused) */ -{ - (void)sig; - - job_canceled = 1; -} - - -/* - * End of "$Id$". - */ diff --git a/filter/pstext.c b/filter/pstext.c deleted file mode 100644 index cfd8f08bb..000000000 --- a/filter/pstext.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * "$Id$" - * - * Common PostScript text code for CUPS. - * - * Copyright 2008-2010 by Apple Inc. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * psTextEmbedFonts() - Embed PostScript fonts. - * psTextListFonts() - List PostScript fonts. - * psTextInitialize() - Load and embed font data for UTF-8 text. - * psTextUTF8() - Output UTF-8 text at the current position. - * psTextUTF32() - Output UTF-32 text at the current position. - */ - -/* - * Include necessary headers... - */ - -#include "pstext.h" -#include - - -/* - * Composite font names... - */ - -static const char * const ps_font_names[] = -{ - "cupsNormal", - "cupsBold", - "cupsItalic", - "cupsBoldItalic" -}; - - -/* - * 'psTextEmbedFonts()'- Embed PostScript fonts. - */ - -void -psTextEmbedFonts(ps_text_t *fonts) /* I - Font data */ -{ - int i, j; /* Looping vars */ - const char *cups_datadir; /* CUPS_DATADIR environment variable */ - char *font; /* Current font */ - char filename[1024]; /* Current filename */ - FILE *fp; /* Current file */ - char line[1024]; /* Line from file */ - int ch; /* Character value */ - - - /* - * Get the data directory... - */ - - if ((cups_datadir = getenv("CUPS_DATADIR")) == NULL) - cups_datadir = CUPS_DATADIR; - - /* - * Embed each font... - */ - - for (font = (char *)cupsArrayFirst(fonts->unique); - font; - font = (char *)cupsArrayNext(fonts->unique)) - { - printf("%%%%BeginResource: font %s\n", font); - - snprintf(filename, sizeof(filename), "%s/fonts/%s", cups_datadir, font); - if ((fp = fopen(filename, "rb")) != NULL) - { - while ((j = fread(line, 1, sizeof(line), fp)) > 0) - fwrite(line, 1, j, stdout); - - fclose(fp); - } - else - { - _cupsLangPrintError("ERROR", _("Unable to open print file")); - fprintf(stderr, "DEBUG: Unable to open \"%s\".\n", filename); - } - - puts("\n%%EndResource"); - } - - /* - * Write the encoding arrays... - */ - - puts("% Character encodings"); - - for (i = 0; i < fonts->num_fonts; i ++) - { - printf("/cupsEncoding%02x [\n", i); - - for (ch = 0; ch < 256; ch ++) - { - if (fonts->glyphs[fonts->codes[i * 256 + ch]]) - printf("/%s", fonts->glyphs[fonts->codes[i * 256 + ch]]); - else if (fonts->codes[i * 256 + ch] > 255) - printf("/uni%04X", fonts->codes[i * 256 + ch]); - else - printf("/.notdef"); - - if ((ch & 7) == 7) - putchar('\n'); - } - - puts("] def"); - } - - /* - * Construct composite fonts... Start by reencoding the base fonts... - */ - - puts("% Reencode base fonts"); - - for (i = 0; i < 4; i ++) - for (j = 0; j < fonts->num_fonts; j ++) - { - printf("/%s findfont\n", fonts->fonts[j][i]); - printf("dup length 1 add dict begin\n" - " { 1 index /FID ne { def } { pop pop } ifelse } forall\n" - " /Encoding cupsEncoding%02x def\n" - " currentdict\n" - "end\n", j); - printf("/%s%02x exch definefont /%s%02x exch def\n", ps_font_names[i], j, - ps_font_names[i], j); - } - - /* - * Then merge them into composite fonts... - */ - - puts("% Create composite fonts"); - - for (i = 0; i < 4; i ++) - { - puts("8 dict begin"); - puts("/FontType 0 def/FontMatrix[1.0 0 0 1.0 0 0]def/FMapType 2 def" - "/Encoding["); - for (j = 0; j < fonts->num_fonts; j ++) - if (j == (fonts->num_fonts - 1)) - printf("%d", j); - else if ((j & 15) == 15) - printf("%d\n", j); - else - printf("%d ", j); - puts("]def/FDepVector["); - for (j = 0; j < fonts->num_fonts; j ++) - if (j == (fonts->num_fonts - 1)) - printf("%s%02x", ps_font_names[i], j); - else if ((j & 3) == 3) - printf("%s%02x\n", ps_font_names[i], j); - else - printf("%s%02x ", ps_font_names[i], j); - puts("]def currentdict end"); - printf("/%s exch definefont pop\n", ps_font_names[i]); - } - - /* - * Procedures... - */ - - puts("% Procedures to justify text...\n" - "/showcenter{dup stringwidth pop -0.5 mul 0 rmoveto show}bind def\n" - "/showleft{show}bind def\n" - "/showright{dup stringwidth pop neg 0 rmoveto show}bind def"); -} - - -/* - * 'psTextListFonts()' - List PostScript fonts. - */ - -void -psTextListFonts(ps_text_t *fonts) /* I - Font data */ -{ - char *font; /* Current font */ - - - font = (char *)cupsArrayFirst(fonts->unique); - printf("%%%%DocumentSuppliedResources: font %s\n", font); - while ((font = (char *)cupsArrayNext(fonts->unique)) != NULL) - printf("%%%%+ font %s\n", font); -} - - -/* - * 'psTextInitialize()' - Load and embed font data for UTF-8 text. - */ - -ps_text_t * /* O - Font data */ -psTextInitialize(void) -{ - ps_text_t *fonts; /* Font data */ - int i, j; /* Looping vars */ - char filename[1024]; /* Current filename */ - FILE *fp; /* Current file */ - const char *cups_datadir; /* CUPS_DATADIR environment variable */ - char line[1024], /* Line from file */ - *lineptr, /* Pointer into line */ - *valptr; /* Pointer to value in line */ - int unicode; /* Character value */ - int start, end; /* Start and end values for range */ - char glyph[64]; /* Glyph name */ - - - /* - * Get the data directory... - */ - - if ((cups_datadir = getenv("CUPS_DATADIR")) == NULL) - cups_datadir = CUPS_DATADIR; - - /* - * Initialize the PostScript text data... - */ - - fonts = (ps_text_t *)calloc(1, sizeof(ps_text_t)); - fonts->size = -1.0; - fonts->style = -1; - - /* - * Load the PostScript glyph names... - */ - - snprintf(filename, sizeof(filename), "%s/data/psglyphs", cups_datadir); - - if ((fp = fopen(filename, "r")) != NULL) - { - while (fscanf(fp, "%x%63s", &unicode, glyph) == 2) - fonts->glyphs[unicode] = _cupsStrAlloc(glyph); - - fclose(fp); - } - else - { - _cupsLangPrintError("ERROR", _("Unable to open print file")); - fprintf(stderr, "DEBUG: Unable to open \"%s\".\n", filename); - exit(1); - } - - /* - * Open the UTF-8 character set definition... - */ - - snprintf(filename, sizeof(filename), "%s/charsets/utf-8", cups_datadir); - - if ((fp = fopen(filename, "r")) == NULL) - { - /* - * Can't open charset file! - */ - - _cupsLangPrintError("ERROR", _("Unable to open print file")); - fprintf(stderr, "DEBUG: Unable to open \"%s\".\n", filename); - exit(1); - } - - if (!fgets(line, sizeof(line), fp) || strncmp(line, "charset utf8", 12)) - { - /* - * Bad/empty charset file! - */ - - fclose(fp); - _cupsLangPrintFilter(stderr, "ERROR", _("Bad charset file \"%s\"."), - filename); - exit(1); - } - - /* - * Read the font descriptions... - */ - - fonts->unique = cupsArrayNew((cups_array_func_t)strcmp, NULL); - - while (fgets(line, sizeof(line), fp) != NULL) - { - /* - * Skip comment and blank lines... - */ - - if (line[0] == '#' || line[0] == '\n') - continue; - - /* - * Read the font descriptions that should look like: - * - * start end direction width normal [bold italic bold-italic] - */ - - lineptr = line; - - start = strtol(lineptr, &lineptr, 16); - end = strtol(lineptr, &lineptr, 16); - - while (isspace(*lineptr & 255)) - lineptr ++; - - valptr = lineptr; - - while (!isspace(*lineptr & 255) && *lineptr) - lineptr ++; - - if (!*lineptr) - { - /* - * Can't have a font without all required values... - */ - - _cupsLangPrintFilter(stderr, "ERROR", - _("Bad font description line \"%s\"."), valptr); - fclose(fp); - exit(1); - } - - *lineptr++ = '\0'; - - if (!strcmp(valptr, "ltor")) - fonts->directions[fonts->num_fonts] = 1; - else if (!strcmp(valptr, "rtol")) - fonts->directions[fonts->num_fonts] = -1; - else - { - _cupsLangPrintFilter(stderr, "ERROR", _("Bad text direction \"%s\"."), - valptr); - fclose(fp); - exit(1); - } - - /* - * Got the direction, now get the width... - */ - - while (isspace(*lineptr & 255)) - lineptr ++; - - valptr = lineptr; - - while (!isspace(*lineptr & 255) && *lineptr) - lineptr ++; - - if (!*lineptr) - { - /* - * Can't have a font without all required values... - */ - - _cupsLangPrintFilter(stderr, "ERROR", - _("Bad font description line \"%s\"."), valptr); - fclose(fp); - exit(1); - } - - *lineptr++ = '\0'; - - if (!strcmp(valptr, "single")) - fonts->widths[fonts->num_fonts] = 1; - else if (!strcmp(valptr, "double")) - fonts->widths[fonts->num_fonts] = 2; - else - { - _cupsLangPrintFilter(stderr, "ERROR", _("Bad text width \"%s\"."), - valptr); - fclose(fp); - exit(1); - } - - /* - * Get the fonts... - */ - - for (i = 0; *lineptr && i < 4; i ++) - { - while (isspace(*lineptr & 255)) - lineptr ++; - - valptr = lineptr; - - while (!isspace(*lineptr & 255) && *lineptr) - lineptr ++; - - if (*lineptr) - *lineptr++ = '\0'; - - if (lineptr > valptr) - { - if (!cupsArrayFind(fonts->unique, valptr)) - cupsArrayAdd(fonts->unique, _cupsStrAlloc(valptr)); - - fonts->fonts[fonts->num_fonts][i] = _cupsStrAlloc(valptr); - } - } - - /* - * Fill in remaining fonts as needed... - */ - - for (j = i; j < 4; j ++) - fonts->fonts[fonts->num_fonts][j] = - _cupsStrAlloc(fonts->fonts[fonts->num_fonts][0]); - - /* - * Define the character mappings... - */ - - for (i = start, j = fonts->num_fonts * 256; i <= end; i ++, j ++) - { - fonts->chars[i] = j; - fonts->codes[j] = i; - } - - /* - * Move to the next font, stopping if needed... - */ - - fonts->num_fonts ++; - if (fonts->num_fonts >= 256) - break; - } - - fclose(fp); - - if (cupsArrayCount(fonts->unique) == 0) - { - _cupsLangPrintFilter(stderr, "ERROR", _("No fonts in charset file.")); - exit(1); - } - - return (fonts); -} - - -/* - * 'psTextUTF8()' - Output UTF-8 text at the current position. - */ - -void -psTextUTF8(ps_text_t *fonts, /* I - Font data */ - float size, /* I - Size in points */ - int style, /* I - Style */ - int align, /* I - Alignment */ - const char *text) /* I - UTF-8 text */ -{ - cups_utf32_t utf32[2048]; /* Temporary buffer */ - int utf32len; /* Number of characters */ - - - if (!text) - { - puts(""); - return; - } - - if ((utf32len = cupsUTF8ToUTF32(utf32, (cups_utf8_t *)text, - (int)(sizeof(utf32) / sizeof(utf32[0])))) > 0) - psTextUTF32(fonts, size, style, align, utf32, utf32len); -} - - -/* - * 'psTextUTF32()' - Output UTF-32 text at the current position. - */ - -void -psTextUTF32(ps_text_t *fonts, /* I - Font data */ - float size, /* I - Size in points */ - int style, /* I - Font style */ - int align, /* I - Alignment */ - const cups_utf32_t *text, /* I - UTF-32 text */ - int textlen) /* I - Length of text */ -{ - if (size != fonts->size || style != fonts->style) - { - printf("/%s findfont %g scalefont setfont\n", ps_font_names[style], size); - fonts->size = size; - fonts->style = style; - } - - putchar('<'); - while (textlen > 0) - { - printf("%04x", fonts->chars[*text]); - text ++; - textlen --; - } - - if (align == PS_CENTER) - puts(">showcenter"); - else if (align == PS_RIGHT) - puts(">showright"); - else - puts(">showleft"); -} - - -/* - * End of "$Id$". - */ diff --git a/filter/pstext.h b/filter/pstext.h deleted file mode 100644 index 41cbee433..000000000 --- a/filter/pstext.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * "$Id$" - * - * Common PostScript text definitions for CUPS. - * - * Copyright 2008-2010 by Apple Inc. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - */ - -/* - * Include necessary headers... - */ - -#include "common.h" -#include - - -/* - * Constants... - */ - -#define PS_NORMAL 0 /* Normal text */ -#define PS_BOLD 1 /* Bold text */ -#define PS_ITALIC 2 /* Italic text */ -#define PS_BOLDITALIC 3 /* Bold italic text */ - -#define PS_LEFT 1 /* Left-justified text */ -#define PS_CENTER 0 /* Center-justified text */ -#define PS_RIGHT -1 /* Right-justified text */ - - -/* - * Structures... - */ - -typedef struct ps_text_s /**** PostScript font data ****/ -{ - char *glyphs[65536]; /* PostScript glyphs for Unicode */ - int num_fonts; /* Number of fonts to use */ - char *fonts[256][4]; /* Fonts to use */ - cups_array_t *unique; /* Unique fonts */ - unsigned short chars[65536], /* 0xffcc (ff = font, cc = char) */ - codes[65536]; /* Unicode glyph mapping to fonts */ - int widths[256], /* Widths of each font */ - directions[256];/* Text directions for each font */ - float size; /* Current text size */ - int style; /* Current text style */ -} ps_text_t; - - -/* - * Functions... - */ - -extern void psTextEmbedFonts(ps_text_t *fonts); -extern void psTextListFonts(ps_text_t *fonts); -extern ps_text_t *psTextInitialize(void); -extern void psTextUTF8(ps_text_t *fonts, float size, int style, - int align, const char *text); -extern void psTextUTF32(ps_text_t *fonts, float size, int style, - int align, const cups_utf32_t *text, - int textlen); - - -/* - * End of "$Id$". - */ diff --git a/filter/pstops.c b/filter/pstops.c index f7dff2a47..c87ca2a78 100644 --- a/filter/pstops.c +++ b/filter/pstops.c @@ -2880,6 +2880,17 @@ start_nup(pstops_doc_t *doc, /* I - Document information */ break; } + /* + * Mirror the page as needed... + */ + + if (doc->mirror) + doc_printf(doc, "%.1f 0.0 translate -1 1 scale\n", PageWidth); + + /* + * Offset and scale as necessary for fitplot/fit-to-page/number-up... + */ + if (Duplex && doc->number_up > 1 && ((number / doc->number_up) & 1)) doc_printf(doc, "%.1f %.1f translate\n", PageWidth - PageRight, PageBottom); else if (doc->number_up > 1 || doc->fitplot) @@ -3234,13 +3245,6 @@ start_nup(pstops_doc_t *doc, /* I - Document information */ bboxx + margin, bboxy + margin, bboxw - 2 * margin, bboxl - 2 * margin); } - - /* - * Mirror the page as needed... - */ - - if (doc->mirror) - doc_printf(doc, "%.1f 0.0 translate -1 1 scale\n", PageWidth); } diff --git a/filter/raster.c b/filter/raster.c index 07d3caa87..cff03d37d 100644 --- a/filter/raster.c +++ b/filter/raster.c @@ -45,13 +45,7 @@ * Include necessary headers... */ -#include "image-private.h" -#if defined(WIN32) || defined(__EMX__) -# include -# include /* for htonl() definition */ -#else -# include -#endif /* WIN32 || __EMX__ */ +#include /* @@ -347,7 +341,8 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ int count; /* Repetition count */ - if (r == NULL || r->mode != CUPS_RASTER_READ || r->remaining == 0) + if (r == NULL || r->mode != CUPS_RASTER_READ || r->remaining == 0 || + r->header.cupsBytesPerLine == 0) return (0); if (!r->compressed) @@ -933,7 +928,7 @@ cups_raster_read_header( cups_raster_update(r); - return (1); + return (r->header.cupsBytesPerLine != 0 && r->header.cupsHeight != 0); } diff --git a/filter/testimage.c b/filter/testimage.c deleted file mode 100644 index 57e3a197d..000000000 --- a/filter/testimage.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * "$Id$" - * - * Image library test program for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1993-2006 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * main() - Main entry... - */ - -/* - * Include necessary headers... - */ - -#include "image.h" - - -/* - * 'main()' - Main entry... - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments */ - char *argv[]) /* I - Command-line arguments */ -{ - cups_image_t *img; /* Image to print */ - cups_icspace_t primary; /* Primary image colorspace */ - FILE *out; /* Output PPM/PGM file */ - cups_ib_t *line; /* Line from file */ - int y, /* Current line */ - width, /* Width of image */ - height, /* Height of image */ - depth; /* Depth of image */ - - - if (argc != 3) - { - puts("Usage: testimage filename.ext filename.[ppm|pgm]"); - return (1); - } - - if (strstr(argv[2], ".ppm") != NULL) - primary = CUPS_IMAGE_RGB; - else - primary = CUPS_IMAGE_WHITE; - - img = cupsImageOpen(argv[1], primary, CUPS_IMAGE_WHITE, 100, 0, NULL); - - if (!img) - { - perror(argv[1]); - return (1); - } - - out = fopen(argv[2], "wb"); - - if (!out) - { - perror(argv[2]); - cupsImageClose(img); - return (1); - } - - width = cupsImageGetWidth(img); - height = cupsImageGetHeight(img); - depth = cupsImageGetDepth(img); - line = calloc(width, depth); - - fprintf(out, "P%d\n%d\n%d\n255\n", - cupsImageGetColorSpace(img) == CUPS_IMAGE_WHITE ? 5 : 6, - width, height); - - for (y = 0; y < height; y ++) - { - cupsImageGetRow(img, 0, y, width, line); - fwrite(line, width, depth, out); - } - - cupsImageClose(img); - fclose(out); - - return (0); -} - - -/* - * End of "$Id$". - */ diff --git a/filter/testraster.c b/filter/testraster.c index 64219fb12..4519aa25d 100644 --- a/filter/testraster.c +++ b/filter/testraster.c @@ -28,13 +28,7 @@ * Include necessary headers... */ -#include "image-private.h" -#ifdef WIN32 -# include -#else -# include -# include -#endif /* WIN32 */ +#include /* diff --git a/filter/textcommon.c b/filter/textcommon.c deleted file mode 100644 index 8101cafba..000000000 --- a/filter/textcommon.c +++ /dev/null @@ -1,1214 +0,0 @@ -/* - * "$Id: textcommon.c 6649 2007-07-11 21:46:42Z mike $" - * - * Common text filter routines for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * TextMain() - Standard main entry for text filters. - * compare_keywords() - Compare two C/C++ keywords. - * getutf8() - Get a UTF-8 encoded wide character... - */ - -/* - * Include necessary headers... - */ - -#include "textcommon.h" -#include - - -/* - * Globals... - */ - -int WrapLines = 1, /* Wrap text in lines */ - SizeLines = 60, /* Number of lines on a page */ - SizeColumns = 80, /* Number of columns on a line */ - PageColumns = 1, /* Number of columns on a page */ - ColumnGutter = 0, /* Number of characters between text columns */ - ColumnWidth = 80, /* Width of each column */ - PrettyPrint = 0, /* Do pretty code formatting */ - Copies = 1; /* Number of copies */ -lchar_t **Page = NULL; /* Page characters */ -int NumPages = 0; /* Number of pages in document */ -float CharsPerInch = 10; /* Number of character columns per inch */ -float LinesPerInch = 6; /* Number of lines per inch */ -int NumKeywords = 0; /* Number of known keywords */ -char **Keywords = NULL; /* List of known keywords */ - - -/* - * Local globals... - */ - -static char *code_keywords[] = /* List of known C/C++ keywords... */ - { - "and", - "and_eq", - "asm", - "auto", - "bitand", - "bitor", - "bool", - "break", - "case", - "catch", - "char", - "class", - "compl", - "const", - "const_cast", - "continue", - "default", - "delete", - "do", - "double", - "dynamic_cast", - "else", - "enum", - "explicit", - "extern", - "false", - "float", - "for", - "friend", - "goto", - "if", - "inline", - "int", - "long", - "mutable", - "namespace", - "new", - "not", - "not_eq", - "operator", - "or", - "or_eq", - "private", - "protected", - "public", - "register", - "reinterpret_cast", - "return", - "short", - "signed", - "sizeof", - "static", - "static_cast", - "struct", - "switch", - "template", - "this", - "throw", - "true", - "try", - "typedef", - "typename", - "union", - "unsigned", - "virtual", - "void", - "volatile", - "while", - "xor", - "xor_eq" - }, - *sh_keywords[] = /* List of known Boure/Korn/zsh/bash keywords... */ - { - "alias", - "bg", - "break", - "case", - "cd", - "command", - "continue", - "do", - "done", - "echo", - "elif", - "else", - "esac", - "eval", - "exec", - "exit", - "export", - "fc", - "fg", - "fi", - "for", - "function", - "getopts", - "if", - "in", - "jobs", - "kill", - "let", - "limit", - "newgrp", - "print", - "pwd", - "read", - "readonly", - "return", - "select", - "set", - "shift", - "test", - "then", - "time", - "times", - "trap", - "typeset", - "ulimit", - "umask", - "unalias", - "unlimit", - "unset", - "until", - "wait", - "whence" - "while", - }, - *csh_keywords[] = /* List of known csh/tcsh keywords... */ - { - "alias", - "aliases", - "bg", - "bindkey", - "break", - "breaksw", - "builtins", - "case", - "cd", - "chdir", - "complete", - "continue", - "default", - "dirs", - "echo", - "echotc", - "else", - "end", - "endif", - "eval", - "exec", - "exit", - "fg", - "foreach", - "glob", - "goto", - "history", - "if", - "jobs", - "kill", - "limit", - "login", - "logout", - "ls", - "nice", - "nohup", - "notify", - "onintr", - "popd", - "pushd", - "pwd", - "rehash", - "repeat", - "set", - "setenv", - "settc", - "shift", - "source", - "stop", - "suspend", - "switch", - "telltc", - "then", - "time", - "umask", - "unalias", - "unbindkey", - "unhash", - "unlimit", - "unset", - "unsetenv", - "wait", - "where", - "which", - "while" - }, - *perl_keywords[] = /* List of known perl keywords... */ - { - "abs", - "accept", - "alarm", - "and", - "atan2", - "bind", - "binmode", - "bless", - "caller", - "chdir", - "chmod", - "chomp", - "chop", - "chown", - "chr", - "chroot", - "closdir", - "close", - "connect", - "continue", - "cos", - "crypt", - "dbmclose", - "dbmopen", - "defined", - "delete", - "die", - "do", - "dump", - "each", - "else", - "elsif", - "endgrent", - "endhostent", - "endnetent", - "endprotoent", - "endpwent", - "endservent", - "eof", - "eval", - "exec", - "exists", - "exit", - "exp", - "fcntl", - "fileno", - "flock", - "for", - "foreach", - "fork", - "format", - "formline", - "getc", - "getgrent", - "getgrgid", - "getgrnam", - "gethostbyaddr", - "gethostbyname", - "gethostent", - "getlogin", - "getnetbyaddr", - "getnetbyname", - "getnetent", - "getpeername", - "getpgrp", - "getppid", - "getpriority", - "getprotobyname", - "getprotobynumber", - "getprotoent", - "getpwent", - "getpwnam", - "getpwuid", - "getservbyname", - "getservbyport", - "getservent", - "getsockname", - "getsockopt", - "glob", - "gmtime", - "goto", - "grep", - "hex", - "if", - "import", - "index", - "int", - "ioctl", - "join", - "keys", - "kill", - "last", - "lc", - "lcfirst", - "length", - "link", - "listen", - "local", - "localtime", - "log", - "lstat", - "map", - "mkdir", - "msgctl", - "msgget", - "msgrcv", - "msgsend", - "my", - "next", - "no", - "not", - "oct", - "open", - "opendir", - "or", - "ord", - "pack", - "package", - "pipe", - "pop", - "pos", - "print", - "printf", - "push", - "quotemeta", - "rand", - "read", - "readdir", - "readlink", - "recv", - "redo", - "ref", - "rename", - "require", - "reset", - "return", - "reverse", - "rewinddir", - "rindex", - "rmdir", - "scalar", - "seek", - "seekdir", - "select", - "semctl", - "semget", - "semop", - "send", - "setgrent", - "sethostent", - "setnetent", - "setpgrp", - "setpriority", - "setprotoent", - "setpwent", - "setservent", - "setsockopt", - "shift", - "shmctl", - "shmget", - "shmread", - "shmwrite", - "shutdown", - "sin", - "sleep", - "socket", - "socketpair", - "sort", - "splice", - "split", - "sprintf", - "sqrt", - "srand", - "stat", - "study", - "sub", - "substr", - "symlink", - "syscall", - "sysread", - "sysseek", - "system", - "syswrite", - "tell", - "telldir", - "tie", - "tied", - "time", - "times" - "times", - "truncate", - "uc", - "ucfirst", - "umask", - "undef", - "unless", - "unlink", - "unpack", - "unshift", - "untie", - "until", - "use", - "utime", - "values", - "vec", - "wait", - "waitpid", - "wantarray", - "warn", - "while", - "write" - }; - - -/* - * Local functions... - */ - -static int compare_keywords(const void *, const void *); -static int getutf8(FILE *fp); - - -/* - * 'TextMain()' - Standard main entry for text filters. - */ - -int /* O - Exit status */ -TextMain(const char *name, /* I - Name of filter */ - int argc, /* I - Number of command-line arguments */ - char *argv[]) /* I - Command-line arguments */ -{ - FILE *fp; /* Print file */ - ppd_file_t *ppd; /* PPD file */ - int i, /* Looping var */ - ch, /* Current char from file */ - lastch, /* Previous char from file */ - attr, /* Current attribute */ - line, /* Current line */ - column, /* Current column */ - page_column; /* Current page column */ - int num_options; /* Number of print options */ - cups_option_t *options; /* Print options */ - const char *val; /* Option value */ - char keyword[64], /* Keyword string */ - *keyptr; /* Pointer into string */ - int keycol; /* Column where keyword starts */ - int ccomment; /* Inside a C-style comment? */ - int cstring; /* Inside a C string */ - - - /* - * Make sure status messages are not buffered... - */ - - setbuf(stderr, NULL); - - /* - * Check command-line... - */ - - if (argc < 6 || argc > 7) - { - _cupsLangPrintf(stderr, - _("Usage: %s job-id user title copies options [file]"), - name); - return (1); - } - - /* - * If we have 7 arguments, print the file named on the command-line. - * Otherwise, send stdin instead... - */ - - if (argc == 6) - fp = stdin; - else - { - /* - * Try to open the print file... - */ - - if ((fp = fopen(argv[6], "rb")) == NULL) - { - perror("DEBUG: unable to open print file - "); - return (1); - } - } - - /* - * Process command-line options and write the prolog... - */ - - options = NULL; - num_options = cupsParseOptions(argv[5], 0, &options); - - if ((val = cupsGetOption("prettyprint", num_options, options)) != NULL && - _cups_strcasecmp(val, "no") && _cups_strcasecmp(val, "off") && - _cups_strcasecmp(val, "false")) - { - PageLeft = 72.0f; - PageRight = PageWidth - 36.0f; - PageBottom = PageBottom > 36.0f ? PageBottom : 36.0f; - PageTop = PageLength - 36.0f; - CharsPerInch = 12; - LinesPerInch = 8; - - if ((val = getenv("CONTENT_TYPE")) == NULL) - { - PrettyPrint = PRETTY_PLAIN; - NumKeywords = 0; - Keywords = NULL; - } - else if (_cups_strcasecmp(val, "application/x-cshell") == 0) - { - PrettyPrint = PRETTY_SHELL; - NumKeywords = sizeof(csh_keywords) / sizeof(csh_keywords[0]); - Keywords = csh_keywords; - } - else if (_cups_strcasecmp(val, "application/x-csource") == 0) - { - PrettyPrint = PRETTY_CODE; - NumKeywords = sizeof(code_keywords) / sizeof(code_keywords[0]); - Keywords = code_keywords; - } - else if (_cups_strcasecmp(val, "application/x-perl") == 0) - { - PrettyPrint = PRETTY_PERL; - NumKeywords = sizeof(perl_keywords) / sizeof(perl_keywords[0]); - Keywords = perl_keywords; - } - else if (_cups_strcasecmp(val, "application/x-shell") == 0) - { - PrettyPrint = PRETTY_SHELL; - NumKeywords = sizeof(sh_keywords) / sizeof(sh_keywords[0]); - Keywords = sh_keywords; - } - else - { - PrettyPrint = PRETTY_PLAIN; - NumKeywords = 0; - Keywords = NULL; - } - } - - ppd = SetCommonOptions(num_options, options, 1); - - if ((val = cupsGetOption("wrap", num_options, options)) == NULL) - WrapLines = 1; - else - WrapLines = !_cups_strcasecmp(val, "true") || !_cups_strcasecmp(val, "on") || - !_cups_strcasecmp(val, "yes"); - - if ((val = cupsGetOption("columns", num_options, options)) != NULL) - { - PageColumns = atoi(val); - - if (PageColumns < 1) - { - _cupsLangPrintFilter(stderr, "ERROR", _("Bad columns value %d."), - PageColumns); - return (1); - } - } - - if ((val = cupsGetOption("cpi", num_options, options)) != NULL) - { - CharsPerInch = atof(val); - - if (CharsPerInch <= 0.0) - { - _cupsLangPrintFilter(stderr, "ERROR", _("Bad cpi value %f."), - CharsPerInch); - return (1); - } - } - - if ((val = cupsGetOption("lpi", num_options, options)) != NULL) - { - LinesPerInch = atof(val); - - if (LinesPerInch <= 0.0) - { - _cupsLangPrintFilter(stderr, "ERROR", _("Bad lpi value %f."), - LinesPerInch); - return (1); - } - } - - if (PrettyPrint) - PageTop -= 216.0f / LinesPerInch; - - Copies = atoi(argv[4]); - - WriteProlog(argv[3], argv[2], getenv("CLASSIFICATION"), - cupsGetOption("page-label", num_options, options), ppd); - - /* - * Read text from the specified source and print it... - */ - - lastch = 0; - column = 0; - line = 0; - page_column = 0; - attr = 0; - keyptr = keyword; - keycol = 0; - ccomment = 0; - cstring = 0; - - while ((ch = getutf8(fp)) >= 0) - { - /* - * Control codes: - * - * BS Backspace (0x08) - * HT Horizontal tab; next 8th column (0x09) - * LF Line feed; forward full line (0x0a) - * VT Vertical tab; reverse full line (0x0b) - * FF Form feed (0x0c) - * CR Carriage return (0x0d) - * ESC 7 Reverse full line (0x1b 0x37) - * ESC 8 Reverse half line (0x1b 0x38) - * ESC 9 Forward half line (0x1b 0x39) - */ - - switch (ch) - { - case 0x08 : /* BS - backspace for boldface & underline */ - if (column > 0) - column --; - - keyptr = keyword; - keycol = column; - break; - - case 0x09 : /* HT - tab to next 8th column */ - if (PrettyPrint && keyptr > keyword) - { - *keyptr = '\0'; - keyptr = keyword; - - if (bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *), - compare_keywords)) - { - /* - * Put keywords in boldface... - */ - - i = page_column * (ColumnWidth + ColumnGutter); - - while (keycol < column) - { - Page[line][keycol + i].attr |= ATTR_BOLD; - keycol ++; - } - } - } - - column = (column + 8) & ~7; - - if (column >= ColumnWidth && WrapLines) - { /* Wrap text to margins */ - line ++; - column = 0; - - if (line >= SizeLines) - { - page_column ++; - line = 0; - - if (page_column >= PageColumns) - { - WritePage(); - page_column = 0; - } - } - } - - keycol = column; - - attr &= ~ATTR_BOLD; - break; - - case 0x0d : /* CR */ -#ifndef __APPLE__ - /* - * All but MacOS/Darwin treat CR as was intended by ANSI - * folks, namely to move to column 0/1. Some programs still - * use this to do boldfacing and underlining... - */ - - column = 0; - break; -#else - /* - * MacOS/Darwin still need to treat CR as a line ending. - */ - - { - int nextch; - if ((nextch = getc(fp)) != 0x0a) - ungetc(nextch, fp); - else - ch = nextch; - } -#endif /* !__APPLE__ */ - - case 0x0a : /* LF - output current line */ - if (PrettyPrint && keyptr > keyword) - { - *keyptr = '\0'; - keyptr = keyword; - - if (bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *), - compare_keywords)) - { - /* - * Put keywords in boldface... - */ - - i = page_column * (ColumnWidth + ColumnGutter); - - while (keycol < column) - { - Page[line][keycol + i].attr |= ATTR_BOLD; - keycol ++; - } - } - } - - line ++; - column = 0; - keycol = 0; - - if (!ccomment && !cstring) - attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE); - - if (line >= SizeLines) - { - page_column ++; - line = 0; - - if (page_column >= PageColumns) - { - WritePage(); - page_column = 0; - } - } - break; - - case 0x0b : /* VT - move up 1 line */ - if (line > 0) - line --; - - keyptr = keyword; - keycol = column; - - if (!ccomment && !cstring) - attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE); - break; - - case 0x0c : /* FF - eject current page... */ - if (PrettyPrint && keyptr > keyword) - { - *keyptr = '\0'; - keyptr = keyword; - - if (bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *), - compare_keywords)) - { - /* - * Put keywords in boldface... - */ - - i = page_column * (ColumnWidth + ColumnGutter); - - while (keycol < column) - { - Page[line][keycol + i].attr |= ATTR_BOLD; - keycol ++; - } - } - } - - page_column ++; - column = 0; - keycol = 0; - line = 0; - - if (!ccomment && !cstring) - attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE); - - if (page_column >= PageColumns) - { - WritePage(); - page_column = 0; - } - break; - - case 0x1b : /* Escape sequence */ - ch = getutf8(fp); - if (ch == '7') - { - /* - * ESC 7 Reverse full line (0x1b 0x37) - */ - - if (line > 0) - line --; - } - else if (ch == '8') - { - /* - * ESC 8 Reverse half line (0x1b 0x38) - */ - - if ((attr & ATTR_RAISED) && line > 0) - { - attr &= ~ATTR_RAISED; - line --; - } - else if (attr & ATTR_LOWERED) - attr &= ~ATTR_LOWERED; - else - attr |= ATTR_RAISED; - } - else if (ch == '9') - { - /* - * ESC 9 Forward half line (0x1b 0x39) - */ - - if ((attr & ATTR_LOWERED) && line < (SizeLines - 1)) - { - attr &= ~ATTR_LOWERED; - line ++; - } - else if (attr & ATTR_RAISED) - attr &= ~ATTR_RAISED; - else - attr |= ATTR_LOWERED; - } - break; - - default : /* All others... */ - if (ch < ' ') - break; /* Ignore other control chars */ - - if (PrettyPrint > PRETTY_PLAIN) - { - /* - * Do highlighting of C/C++ keywords, preprocessor commands, - * and comments... - */ - - if (ch == ' ' && (attr & ATTR_BOLD)) - { - /* - * Stop bolding preprocessor command... - */ - - attr &= ~ATTR_BOLD; - } - else if (!(isalnum(ch & 255) || ch == '_') && keyptr > keyword) - { - /* - * Look for a keyword... - */ - - *keyptr = '\0'; - keyptr = keyword; - - if (!(attr & ATTR_ITALIC) && - bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *), - compare_keywords)) - { - /* - * Put keywords in boldface... - */ - - i = page_column * (ColumnWidth + ColumnGutter); - - while (keycol < column) - { - Page[line][keycol + i].attr |= ATTR_BOLD; - keycol ++; - } - } - } - else if ((isalnum(ch & 255) || ch == '_') && !ccomment && !cstring) - { - /* - * Add characters to the current keyword (if they'll fit). - */ - - if (keyptr == keyword) - keycol = column; - - if (keyptr < (keyword + sizeof(keyword) - 1)) - *keyptr++ = ch; - } - else if (ch == '\"' && lastch != '\\' && !ccomment && !cstring) - { - /* - * Start a C string constant... - */ - - cstring = -1; - attr = ATTR_BLUE; - } - else if (ch == '*' && lastch == '/' && !cstring && - PrettyPrint != PRETTY_SHELL) - { - /* - * Start a C-style comment... - */ - - ccomment = 1; - attr = ATTR_ITALIC | ATTR_GREEN; - } - else if (ch == '/' && lastch == '/' && !cstring && - PrettyPrint == PRETTY_CODE) - { - /* - * Start a C++-style comment... - */ - - attr = ATTR_ITALIC | ATTR_GREEN; - } - else if (ch == '#' && !cstring && PrettyPrint != PRETTY_CODE) - { - /* - * Start a shell-style comment... - */ - - attr = ATTR_ITALIC | ATTR_GREEN; - } - else if (ch == '#' && column == 0 && !ccomment && !cstring && - PrettyPrint == PRETTY_CODE) - { - /* - * Start a preprocessor command... - */ - - attr = ATTR_BOLD | ATTR_RED; - } - } - - if (column >= ColumnWidth && WrapLines) - { /* Wrap text to margins */ - column = 0; - line ++; - - if (line >= SizeLines) - { - page_column ++; - line = 0; - - if (page_column >= PageColumns) - { - WritePage(); - page_column = 0; - } - } - } - - /* - * Add text to the current column & line... - */ - - if (column < ColumnWidth) - { - i = column + page_column * (ColumnWidth + ColumnGutter); - - if (PrettyPrint) - Page[line][i].attr = attr; - else if (ch == ' ' && Page[line][i].ch) - ch = Page[line][i].ch; - else if (ch == Page[line][i].ch) - Page[line][i].attr |= ATTR_BOLD; - else if (Page[line][i].ch == '_') - Page[line][i].attr |= ATTR_UNDERLINE; - else if (ch == '_') - { - Page[line][i].attr |= ATTR_UNDERLINE; - - if (Page[line][i].ch) - ch = Page[line][i].ch; - } - else - Page[line][i].attr = attr; - - Page[line][i].ch = ch; - } - - if (PrettyPrint) - { - if ((ch == '{' || ch == '}') && !ccomment && !cstring && - column < ColumnWidth) - { - /* - * Highlight curley braces... - */ - - Page[line][column].attr |= ATTR_BOLD; - } - else if ((ch == '/' || ch == '*') && lastch == '/' && - column < ColumnWidth && PrettyPrint != PRETTY_SHELL) - { - /* - * Highlight first comment character... - */ - - Page[line][column - 1].attr = attr; - } - else if (ch == '\"' && lastch != '\\' && !ccomment && cstring > 0) - { - /* - * End a C string constant... - */ - - cstring = 0; - attr &= ~ATTR_BLUE; - } - else if (ch == '/' && lastch == '*' && ccomment) - { - /* - * End a C-style comment... - */ - - ccomment = 0; - attr &= ~(ATTR_ITALIC | ATTR_GREEN); - } - - if (cstring < 0) - cstring = 1; - } - - column ++; - break; - } - - /* - * Save this character for the next cycle. - */ - - lastch = ch; - } - - /* - * Write any remaining page data... - */ - - if (line > 0 || page_column > 0 || column > 0) - WritePage(); - - /* - * Write the epilog and return... - */ - - WriteEpilogue(); - - if (ppd != NULL) - ppdClose(ppd); - - return (0); -} - - -/* - * 'compare_keywords()' - Compare two C/C++ keywords. - */ - -static int /* O - Result of strcmp */ -compare_keywords(const void *k1, /* I - First keyword */ - const void *k2) /* I - Second keyword */ -{ - return (strcmp(*((const char **)k1), *((const char **)k2))); -} - - -/* - * 'getutf8()' - Get a UTF-8 encoded wide character... - */ - -static int /* O - Character or -1 on error */ -getutf8(FILE *fp) /* I - File to read from */ -{ - int ch; /* Current character value */ - int next; /* Next character from file */ - - - /* - * Read the first character and process things accordingly... - * - * UTF-8 maps 16-bit characters to: - * - * 0 to 127 = 0xxxxxxx - * 128 to 2047 = 110xxxxx 10yyyyyy (xxxxxyyyyyy) - * 2048 to 65535 = 1110xxxx 10yyyyyy 10zzzzzz (xxxxyyyyyyzzzzzz) - * - * We also accept: - * - * 128 to 191 = 10xxxxxx - * - * since this range of values is otherwise undefined unless you are - * in the middle of a multi-byte character... - * - * This code currently does not support anything beyond 16-bit - * characters, in part because PostScript doesn't support more than - * 16-bit characters... - */ - - if ((ch = getc(fp)) == EOF) - return (EOF); - - if (ch < 0xc0) /* One byte character? */ - return (ch); - else if ((ch & 0xe0) == 0xc0) - { - /* - * Two byte character... - */ - - if ((next = getc(fp)) == EOF) - return (EOF); - else - return (((ch & 0x1f) << 6) | (next & 0x3f)); - } - else if ((ch & 0xf0) == 0xe0) - { - /* - * Three byte character... - */ - - if ((next = getc(fp)) == EOF) - return (EOF); - - ch = ((ch & 0x0f) << 6) | (next & 0x3f); - - if ((next = getc(fp)) == EOF) - return (EOF); - else - return ((ch << 6) | (next & 0x3f)); - } - else - { - /* - * More than three bytes... We don't support that... - */ - - return (EOF); - } -} - - -/* - * End of "$Id: textcommon.c 6649 2007-07-11 21:46:42Z mike $". - */ diff --git a/filter/textcommon.h b/filter/textcommon.h deleted file mode 100644 index 20eb5e606..000000000 --- a/filter/textcommon.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * "$Id: textcommon.h 6649 2007-07-11 21:46:42Z mike $" - * - * Common text filter definitions for CUPS. - * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1997-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - */ - -/* - * Include necessary headers... - */ - -#include "common.h" - - -/* - * C++ magic... - */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/* - * Constants... - */ - -#define ATTR_NORMAL 0x00 -#define ATTR_BOLD 0x01 -#define ATTR_ITALIC 0x02 -#define ATTR_BOLDITALIC 0x03 -#define ATTR_FONT 0x03 - -#define ATTR_UNDERLINE 0x04 -#define ATTR_RAISED 0x08 -#define ATTR_LOWERED 0x10 -#define ATTR_RED 0x20 -#define ATTR_GREEN 0x40 -#define ATTR_BLUE 0x80 - -#define PRETTY_OFF 0 -#define PRETTY_PLAIN 1 -#define PRETTY_CODE 2 -#define PRETTY_SHELL 3 -#define PRETTY_PERL 4 -#define PRETTY_HTML 5 - - -/* - * Structures... - */ - -typedef struct /**** Character/attribute structure... ****/ -{ - unsigned short ch, /* Character */ - attr; /* Any attributes */ -} lchar_t; - - -/* - * Globals... - */ - -extern int WrapLines, /* Wrap text in lines */ - SizeLines, /* Number of lines on a page */ - SizeColumns, /* Number of columns on a line */ - PageColumns, /* Number of columns on a page */ - ColumnGutter, /* Number of characters between text columns */ - ColumnWidth, /* Width of each column */ - PrettyPrint, /* Do pretty code formatting? */ - Copies; /* Number of copies to produce */ -extern lchar_t **Page; /* Page characters */ -extern int NumPages; /* Number of pages in document */ -extern float CharsPerInch, /* Number of character columns per inch */ - LinesPerInch; /* Number of lines per inch */ -extern int UTF8, /* Use UTF-8 encoding? */ - NumKeywords; /* Number of known keywords */ -extern char **Keywords; /* List of known keywords... */ - - -/* - * Required functions... - */ - -extern int TextMain(const char *name, int argc, char *argv[]); -extern void WriteEpilogue(void); -extern void WritePage(void); -extern void WriteProlog(const char *title, const char *user, - const char *classification, const char *label, - ppd_file_t *ppd); - - -/* - * C++ magic... - */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -/* - * End of "$Id: textcommon.h 6649 2007-07-11 21:46:42Z mike $". - */ diff --git a/filter/texttops.c b/filter/texttops.c deleted file mode 100644 index af549cefa..000000000 --- a/filter/texttops.c +++ /dev/null @@ -1,1165 +0,0 @@ -/* - * "$Id: texttops.c 7720 2008-07-11 22:46:21Z mike $" - * - * Text to PostScript filter for CUPS. - * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * main() - Main entry for text to PostScript filter. - * WriteEpilogue() - Write the PostScript file epilogue. - * WritePage() - Write a page of text. - * WriteProlog() - Write the PostScript file prolog with options. - * write_line() - Write a row of text. - * write_string() - Write a string of text. - */ - -/* - * Include necessary headers... - */ - -#include "textcommon.h" -#include - - -/* - * Globals... - */ - -char *Glyphs[65536]; /* PostScript glyphs for Unicode */ -int NumFonts; /* Number of fonts to use */ -char *Fonts[256][4]; /* Fonts to use */ -unsigned short Chars[65536]; /* 0xffcc (ff = font, cc = char) */ -unsigned short Codes[65536]; /* Unicode glyph mapping to fonts */ -int Widths[256]; /* Widths of each font */ -int Directions[256];/* Text directions for each font */ - - -/* - * Local functions... - */ - -static void write_line(int row, lchar_t *line); -static void write_string(int col, int row, int len, lchar_t *s); -static void write_text(const char *s); - - -/* - * 'main()' - Main entry for text to PostScript filter. - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments */ - char *argv[]) /* I - Command-line arguments */ -{ - return (TextMain("texttops", argc, argv)); -} - - -/* - * 'WriteEpilogue()' - Write the PostScript file epilogue. - */ - -void -WriteEpilogue(void) -{ - puts("%%Trailer"); - printf("%%%%Pages: %d\n", NumPages); - puts("%%EOF"); - - free(Page[0]); - free(Page); -} - - -/* - * 'WritePage()' - Write a page of text. - */ - -void -WritePage(void) -{ - int line; /* Current line */ - - - NumPages ++; - printf("%%%%Page: %d %d\n", NumPages, NumPages); - - puts("gsave"); - - if (PrettyPrint) - printf("%d H\n", NumPages); - - for (line = 0; line < SizeLines; line ++) - write_line(line, Page[line]); - - puts("grestore"); - puts("showpage"); - - memset(Page[0], 0, sizeof(lchar_t) * SizeColumns * SizeLines); -} - - -/* - * 'WriteProlog()' - Write the PostScript file prolog with options. - */ - -void -WriteProlog(const char *title, /* I - Title of job */ - const char *user, /* I - Username */ - const char *classification, /* I - Classification */ - const char *label, /* I - Page label */ - ppd_file_t *ppd) /* I - PPD file info */ -{ - int i, j, k; /* Looping vars */ - char *charset; /* Character set string */ - char filename[1024]; /* Glyph filenames */ - FILE *fp; /* Glyph files */ - const char *datadir; /* CUPS_DATADIR environment variable */ - char line[1024], /* Line from file */ - *lineptr, /* Pointer into line */ - *valptr; /* Pointer to value in line */ - int ch, unicode; /* Character values */ - int start, end; /* Start and end values for range */ - char glyph[64]; /* Glyph name */ - time_t curtime; /* Current time */ - struct tm *curtm; /* Current date */ - char curdate[255]; /* Current date (text format) */ - int num_fonts; /* Number of unique fonts */ - char *fonts[1024]; /* Unique fonts */ - static char *names[] = /* Font names */ - { - "cupsNormal", - "cupsBold", - "cupsItalic" - }; - - - /* - * Get the data directory... - */ - - if ((datadir = getenv("CUPS_DATADIR")) == NULL) - datadir = CUPS_DATADIR; - - /* - * Adjust margins as necessary... - */ - - if (classification || label) - { - /* - * Leave room for labels... - */ - - PageBottom += 36; - PageTop -= 36; - } - - /* - * Allocate memory for the page... - */ - - SizeColumns = (PageRight - PageLeft) / 72.0 * CharsPerInch; - SizeLines = (PageTop - PageBottom) / 72.0 * LinesPerInch; - - if (SizeColumns <= 0 || SizeColumns > 32767 || - SizeLines <= 0 || SizeLines > 32767) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Unable to print %dx%d text page."), - SizeColumns, SizeLines); - exit(1); - } - - if ((Page = calloc(sizeof(lchar_t *), SizeLines)) == NULL) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Unable to print %dx%d text page."), - SizeColumns, SizeLines); - exit(1); - } - - if ((Page[0] = calloc(sizeof(lchar_t), SizeColumns * SizeLines)) == NULL) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Unable to print %dx%d text page."), - SizeColumns, SizeLines); - exit(1); - } - - for (i = 1; i < SizeLines; i ++) - Page[i] = Page[0] + i * SizeColumns; - - if (PageColumns > 1) - { - ColumnGutter = CharsPerInch / 2; - ColumnWidth = (SizeColumns - ColumnGutter * (PageColumns - 1)) / - PageColumns; - } - else - ColumnWidth = SizeColumns; - - if (ColumnWidth <= 0) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Unable to print %d text columns."), PageColumns); - exit(1); - } - - /* - * Output the DSC header... - */ - - curtime = time(NULL); - curtm = localtime(&curtime); - strftime(curdate, sizeof(curdate), "%c", curtm); - - puts("%!PS-Adobe-3.0"); - printf("%%%%BoundingBox: 0 0 %.0f %.0f\n", PageWidth, PageLength); - printf("%%cupsRotation: %d\n", (Orientation & 3) * 90); - puts("%%Creator: texttops/" CUPS_SVERSION); - printf("%%%%CreationDate: %s\n", curdate); - WriteTextComment("Title", title); - WriteTextComment("For", user); - puts("%%Pages: (atend)"); - - /* - * Initialize globals... - */ - - NumFonts = 0; - memset(Fonts, 0, sizeof(Fonts)); - memset(Glyphs, 0, sizeof(Glyphs)); - memset(Chars, 0, sizeof(Chars)); - memset(Codes, 0, sizeof(Codes)); - - /* - * Load the PostScript glyph names and the corresponding character - * set definition... - */ - - snprintf(filename, sizeof(filename), "%s/data/psglyphs", datadir); - - if ((fp = fopen(filename, "r")) != NULL) - { - while (fscanf(fp, "%x%63s", &unicode, glyph) == 2) - Glyphs[unicode] = strdup(glyph); - - fclose(fp); - } - else - { - _cupsLangPrintError("ERROR", _("Unable to open psglyphs")); - exit(1); - } - - /* - * Get the output character set... - */ - - charset = getenv("CHARSET"); - if (charset != NULL && strcmp(charset, "us-ascii") != 0) - { - snprintf(filename, sizeof(filename), "%s/charsets/%s", datadir, charset); - - if ((fp = fopen(filename, "r")) == NULL) - { - /* - * Can't open charset file! - */ - - _cupsLangPrintError("ERROR", _("Unable to open charset file")); - exit(1); - } - - /* - * Opened charset file; now see if this is really a charset file... - */ - - if (fgets(line, sizeof(line), fp) == NULL) - { - /* - * Bad/empty charset file! - */ - - fclose(fp); - _cupsLangPrintFilter(stderr, "ERROR", _("Bad charset file \"%s\"."), - filename); - exit(1); - } - - if (strncmp(line, "charset", 7) != 0) - { - /* - * Bad format/not a charset file! - */ - - fclose(fp); - _cupsLangPrintFilter(stderr, "ERROR", _("Bad charset file \"%s\"."), - filename); - exit(1); - } - - /* - * See if this is an 8-bit or UTF-8 character set file... - */ - - line[strlen(line) - 1] = '\0'; /* Drop \n */ - for (lineptr = line + 7; isspace(*lineptr & 255); lineptr ++); /* Skip whitespace */ - - if (strcmp(lineptr, "utf8") == 0) - { - /* - * UTF-8 (Unicode) text... - */ - - NumFonts = 0; - - while (fgets(line, sizeof(line), fp) != NULL) - { - /* - * Skip comment and blank lines... - */ - - if (line[0] == '#' || line[0] == '\n') - continue; - - /* - * Read the font descriptions that should look like: - * - * start end direction width normal [bold italic bold-italic] - */ - - lineptr = line; - - start = strtol(lineptr, &lineptr, 16); - end = strtol(lineptr, &lineptr, 16); - - while (isspace(*lineptr & 255)) - lineptr ++; - - valptr = lineptr; - - while (!isspace(*lineptr & 255) && *lineptr) - lineptr ++; - - if (!*lineptr) - { - /* - * Can't have a font without all required values... - */ - - _cupsLangPrintFilter(stderr, "ERROR", - _("Bad font description line: %s"), valptr); - fclose(fp); - exit(1); - } - - *lineptr++ = '\0'; - - if (strcmp(valptr, "ltor") == 0) - Directions[NumFonts] = 1; - else if (strcmp(valptr, "rtol") == 0) - Directions[NumFonts] = -1; - else - { - _cupsLangPrintFilter(stderr, "ERROR", _("Bad text direction: %s"), - valptr); - fclose(fp); - exit(1); - } - - /* - * Got the direction, now get the width... - */ - - while (isspace(*lineptr & 255)) - lineptr ++; - - valptr = lineptr; - - while (!isspace(*lineptr & 255) && *lineptr) - lineptr ++; - - if (!*lineptr) - { - /* - * Can't have a font without all required values... - */ - - _cupsLangPrintFilter(stderr, "ERROR", - _("Bad font description line: %s"), valptr); - fclose(fp); - exit(1); - } - - *lineptr++ = '\0'; - - if (strcmp(valptr, "single") == 0) - Widths[NumFonts] = 1; - else if (strcmp(valptr, "double") == 0) - Widths[NumFonts] = 2; - else - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Bad text width: %s"), valptr); - fclose(fp); - exit(1); - } - - /* - * Get the fonts... - */ - - for (i = 0; *lineptr && i < 4; i ++) - { - while (isspace(*lineptr & 255)) - lineptr ++; - - valptr = lineptr; - - while (!isspace(*lineptr & 255) && *lineptr) - lineptr ++; - - if (*lineptr) - *lineptr++ = '\0'; - - if (lineptr > valptr) - Fonts[NumFonts][i] = strdup(valptr); - } - - /* - * Fill in remaining fonts as needed... - */ - - for (j = i; j < 4; j ++) - Fonts[NumFonts][j] = strdup(Fonts[NumFonts][0]); - - /* - * Define the character mappings... - */ - - for (i = start, j = NumFonts * 256; i <= end; i ++, j ++) - { - Chars[i] = j; - Codes[j] = i; - } - - /* - * Move to the next font, stopping if needed... - */ - - NumFonts ++; - if (NumFonts >= 256) - break; - } - - fclose(fp); - } - else - { - _cupsLangPrintFilter(stderr, "ERROR", _("Bad charset type: %s"), lineptr); - fclose(fp); - exit(1); - } - } - else - { - /* - * Standard ASCII output just uses Courier, Courier-Bold, and - * possibly Courier-Oblique. - */ - - NumFonts = 1; - - Fonts[0][ATTR_NORMAL] = strdup("Courier"); - Fonts[0][ATTR_BOLD] = strdup("Courier-Bold"); - Fonts[0][ATTR_ITALIC] = strdup("Courier-Oblique"); - Fonts[0][ATTR_BOLDITALIC] = strdup("Courier-BoldOblique"); - - Widths[0] = 1; - Directions[0] = 1; - - /* - * Define US-ASCII characters... - */ - - for (i = 32; i < 127; i ++) - { - Chars[i] = i; - Codes[i] = i; - } - } - - /* - * Generate a list of unique fonts to use... - */ - - for (i = 0, num_fonts = 0; i < NumFonts; i ++) - for (j = PrettyPrint ? 2 : 1; j >= 0; j --) - { - for (k = 0; k < num_fonts; k ++) - if (strcmp(Fonts[i][j], fonts[k]) == 0) - break; - - if (k >= num_fonts) - { - /* - * Add new font... - */ - - fonts[num_fonts] = Fonts[i][j]; - num_fonts ++; - } - } - - /* - * List the fonts that will be used... - */ - - for (i = 0; i < num_fonts; i ++) - if (i == 0) - printf("%%%%DocumentNeededResources: font %s\n", fonts[i]); - else - printf("%%%%+ font %s\n", fonts[i]); - - puts("%%DocumentSuppliedResources: procset texttops 1.1 0"); - - for (i = 0; i < num_fonts; i ++) - { - if (ppd != NULL) - { - fprintf(stderr, "DEBUG: ppd->num_fonts = %d\n", ppd->num_fonts); - - for (j = 0; j < ppd->num_fonts; j ++) - { - fprintf(stderr, "DEBUG: ppd->fonts[%d] = %s\n", j, ppd->fonts[j]); - - if (strcmp(fonts[i], ppd->fonts[j]) == 0) - break; - } - } - else - j = 0; - - if ((ppd != NULL && j >= ppd->num_fonts) || - strncmp(fonts[i], "Courier", 7) == 0 || - strcmp(fonts[i], "Symbol") == 0) - { - /* - * Need to embed this font... - */ - - printf("%%%%+ font %s\n", fonts[i]); - } - } - - puts("%%EndComments"); - - puts("%%BeginProlog"); - - /* - * Download any missing fonts... - */ - - for (i = 0; i < num_fonts; i ++) - { - if (ppd != NULL) - { - for (j = 0; j < ppd->num_fonts; j ++) - if (strcmp(fonts[i], ppd->fonts[j]) == 0) - break; - } - else - j = 0; - - if ((ppd != NULL && j >= ppd->num_fonts) || - strncmp(fonts[i], "Courier", 7) == 0 || - strcmp(fonts[i], "Symbol") == 0) - { - /* - * Need to embed this font... - */ - - printf("%%%%BeginResource: font %s\n", fonts[i]); - - /**** MRS: Need to use CUPS_FONTPATH env var! ****/ - /**** Also look for Fontmap file or name.pfa, name.pfb... ****/ - snprintf(filename, sizeof(filename), "%s/fonts/%s", datadir, fonts[i]); - if ((fp = fopen(filename, "rb")) != NULL) - { - while ((j = fread(line, 1, sizeof(line), fp)) > 0) - fwrite(line, 1, j, stdout); - - fclose(fp); - } - - puts("\n%%EndResource"); - } - } - - /* - * Write the encoding array(s)... - */ - - puts("% character encoding(s)"); - - for (i = 0; i < NumFonts; i ++) - { - printf("/cupsEncoding%02x [\n", i); - - for (ch = 0; ch < 256; ch ++) - { - if (Glyphs[Codes[i * 256 + ch]]) - printf("/%s", Glyphs[Codes[i * 256 + ch]]); - else if (Codes[i * 256 + ch] > 255) - printf("/uni%04X", Codes[i * 256 + ch]); - else - printf("/.notdef"); - - if ((ch & 7) == 7) - putchar('\n'); - } - - puts("] def"); - } - - /* - * Create the fonts... - */ - - if (NumFonts == 1) - { - /* - * Just reencode the named fonts... - */ - - puts("% Reencode fonts"); - - for (i = PrettyPrint ? 2 : 1; i >= 0; i --) - { - printf("/%s findfont\n", Fonts[0][i]); - puts("dup length 1 add dict begin\n" - " { 1 index /FID ne { def } { pop pop } ifelse } forall\n" - " /Encoding cupsEncoding00 def\n" - " currentdict\n" - "end"); - printf("/%s exch definefont pop\n", names[i]); - } - } - else - { - /* - * Construct composite fonts... Start by reencoding the base fonts... - */ - - puts("% Reencode base fonts"); - - for (i = PrettyPrint ? 2 : 1; i >= 0; i --) - for (j = 0; j < NumFonts; j ++) - { - printf("/%s findfont\n", Fonts[j][i]); - printf("dup length 1 add dict begin\n" - " { 1 index /FID ne { def } { pop pop } ifelse } forall\n" - " /Encoding cupsEncoding%02x def\n" - " currentdict\n" - "end\n", j); - printf("/%s%02x exch definefont /%s%02x exch def\n", names[i], j, - names[i], j); - } - - /* - * Then merge them into composite fonts... - */ - - puts("% Create composite fonts..."); - - for (i = PrettyPrint ? 2 : 1; i >= 0; i --) - { - puts("8 dict begin"); - puts("/FontType 0 def/FontMatrix[1.0 0 0 1.0 0 0]def/FMapType 2 def/Encoding["); - for (j = 0; j < NumFonts; j ++) - if (j == (NumFonts - 1)) - printf("%d", j); - else if ((j & 15) == 15) - printf("%d\n", j); - else - printf("%d ", j); - puts("]def/FDepVector["); - for (j = 0; j < NumFonts; j ++) - if (j == (NumFonts - 1)) - printf("%s%02x", names[i], j); - else if ((j & 3) == 3) - printf("%s%02x\n", names[i], j); - else - printf("%s%02x ", names[i], j); - puts("]def currentdict end"); - printf("/%s exch definefont pop\n", names[i]); - } - } - - /* - * Output the texttops procset... - */ - - puts("%%BeginResource: procset texttops 1.1 0"); - - puts("% Define fonts"); - - printf("/FN /cupsNormal findfont [%.3f 0 0 %.3f 0 0] makefont def\n", - 120.0 / CharsPerInch, 68.0 / LinesPerInch); - printf("/FB /cupsBold findfont [%.3f 0 0 %.3f 0 0] makefont def\n", - 120.0 / CharsPerInch, 68.0 / LinesPerInch); - if (PrettyPrint) - printf("/FI /cupsItalic findfont [%.3f 0 0 %.3f 0 0] makefont def\n", - 120.0 / CharsPerInch, 68.0 / LinesPerInch); - - puts("% Common procedures"); - - puts("/N { FN setfont moveto } bind def"); - puts("/B { FB setfont moveto } bind def"); - printf("/U { gsave 0.5 setlinewidth 0 %.3f rmoveto " - "0 rlineto stroke grestore } bind def\n", -6.8 / LinesPerInch); - - if (PrettyPrint) - { - if (ColorDevice) - { - puts("/S { 0.0 setgray show } bind def"); - puts("/r { 0.5 0.0 0.0 setrgbcolor show } bind def"); - puts("/g { 0.0 0.5 0.0 setrgbcolor show } bind def"); - puts("/b { 0.0 0.0 0.5 setrgbcolor show } bind def"); - } - else - { - puts("/S { 0.0 setgray show } bind def"); - puts("/r { 0.2 setgray show } bind def"); - puts("/g { 0.2 setgray show } bind def"); - puts("/b { 0.2 setgray show } bind def"); - } - - puts("/I { FI setfont moveto } bind def"); - - puts("/n {"); - puts("\t20 string cvs % convert page number to string"); - if (NumFonts > 1) - { - /* - * Convert a number to double-byte chars... - */ - - puts("\tdup length % get length"); - puts("\tdup 2 mul string /P exch def % P = string twice as long"); - puts("\t0 1 2 index 1 sub { % loop through each character in the page number"); - puts("\t\tdup 3 index exch get % get character N from the page number"); - puts("\t\texch 2 mul dup % compute offset in P"); - puts("\t\tP exch 0 put % font 0"); - puts("\t\t1 add P exch 2 index put % character"); - puts("\t\tpop % discard character"); - puts("\t} for % do for loop"); - puts("\tpop pop % discard string and length"); - puts("\tP % put string on stack"); - } - puts("} bind def"); - - printf("/T"); - write_text(title); - puts("def"); - - printf("/D"); - write_text(curdate); - puts("def"); - - puts("/H {"); - puts("\tgsave"); - puts("\t0.9 setgray"); - - if (Duplex) - { - puts("\tdup 2 mod 0 eq {"); - printf("\t\t%.3f %.3f translate } {\n", - PageWidth - PageRight, PageTop + 72.0f / LinesPerInch); - printf("\t\t%.3f %.3f translate } ifelse\n", - PageLeft, PageTop + 72.0f / LinesPerInch); - } - else - printf("\t%.3f %.3f translate\n", - PageLeft, PageTop + 72.0f / LinesPerInch); - - printf("\t0 0 %.3f %.3f rectfill\n", PageRight - PageLeft, - 144.0f / LinesPerInch); - - puts("\tFB setfont"); - puts("\t0 setgray"); - - if (Duplex) - { - puts("\tdup 2 mod 0 eq {"); - printf("\t\tT stringwidth pop neg %.3f add %.3f } {\n", - PageRight - PageLeft - 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - printf("\t\t%.3f %.3f } ifelse\n", 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - } - else - printf("\t%.3f %.3f\n", 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - - puts("\tmoveto T show"); - - printf("\tD dup stringwidth pop neg 2 div %.3f add %.3f\n", - (PageRight - PageLeft) * 0.5, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - puts("\tmoveto show"); - - if (Duplex) - { - puts("\tdup n exch 2 mod 0 eq {"); - printf("\t\t%.3f %.3f } {\n", 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - printf("\t\tdup stringwidth pop neg %.3f add %.3f } ifelse\n", - PageRight - PageLeft - 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - } - else - printf("\tn dup stringwidth pop neg %.3f add %.3f\n", - PageRight - PageLeft - 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - - puts("\tmoveto show"); - puts("\tgrestore"); - puts("} bind def"); - } - else - puts("/S { show } bind def"); - - puts("%%EndResource"); - - puts("%%EndProlog"); -} - - -/* - * 'write_line()' - Write a row of text. - */ - -static void -write_line(int row, /* I - Row number (0 to N) */ - lchar_t *line) /* I - Line to print */ -{ - int i; /* Looping var */ - int col; /* Current column */ - int attr; /* Current attribute */ - int font, /* Font to use */ - lastfont, /* Last font */ - mono; /* Monospaced? */ - lchar_t *start; /* First character in sequence */ - - - for (col = 0; col < SizeColumns;) - { - while (col < SizeColumns && (line->ch == ' ' || line->ch == 0)) - { - col ++; - line ++; - } - - if (col >= SizeColumns) - break; - - if (NumFonts == 1) - { - /* - * All characters in a single font - assume monospaced... - */ - - attr = line->attr; - start = line; - - while (col < SizeColumns && line->ch != 0 && attr == line->attr) - { - col ++; - line ++; - } - - write_string(col - (line - start), row, line - start, start); - } - else - { - /* - * Multiple fonts; break up based on the font... - */ - - attr = line->attr; - start = line; - lastfont = Chars[line->ch] / 256; - mono = strncmp(Fonts[lastfont][0], "Courier", 7) == 0; - col ++; - line ++; - - if (mono) - { - while (col < SizeColumns && line->ch != 0 && attr == line->attr) - { - font = Chars[line->ch] / 256; - if (strncmp(Fonts[font][0], "Courier", 7) != 0 || - font != lastfont) - break; - - col ++; - line ++; - } - } - - if (Directions[lastfont] > 0) - write_string(col - (line - start), row, line - start, start); - else - { - /* - * Do right-to-left text... - */ - - while (col < SizeColumns && line->ch != 0 && attr == line->attr) - { - if (Directions[Chars[line->ch] / 256] > 0 && - !ispunct(line->ch & 255) && !isspace(line->ch & 255)) - break; - - col ++; - line ++; - } - - for (i = 1; start < line; i ++, start ++) - if (!isspace(start->ch & 255)) - write_string(col - i, row, 1, start); - } - } - } -} - - -/* - * 'write_string()' - Write a string of text. - */ - -static void -write_string(int col, /* I - Start column */ - int row, /* I - Row */ - int len, /* I - Number of characters */ - lchar_t *s) /* I - String to print */ -{ - int ch; /* Current character */ - float x, y; /* Position of text */ - unsigned attr; /* Character attributes */ - - - /* - * Position the text and set the font... - */ - - if (Duplex && (NumPages & 1) == 0) - { - x = PageWidth - PageRight; - y = PageTop; - } - else - { - x = PageLeft; - y = PageTop; - } - - x += (float)col * 72.0f / (float)CharsPerInch; - y -= (float)(row + 0.843) * 72.0f / (float)LinesPerInch; - - attr = s->attr; - - if (attr & ATTR_RAISED) - y += 36.0 / (float)LinesPerInch; - else if (attr & ATTR_LOWERED) - y -= 36.0 / (float)LinesPerInch; - - if (x == (int)x) - printf("%.0f ", x); - else - printf("%.3f ", x); - - if (y == (int)y) - printf("%.0f ", y); - else - printf("%.3f ", y); - - if (attr & ATTR_BOLD) - putchar('B'); - else if (attr & ATTR_ITALIC) - putchar('I'); - else - putchar('N'); - - if (attr & ATTR_UNDERLINE) - printf(" %.3f U", (float)len * 72.0 / (float)CharsPerInch); - - if (NumFonts > 1) - { - /* - * Write a hex string... - */ - - putchar('<'); - - while (len > 0) - { - printf("%04x", Chars[s->ch]); - - len --; - s ++; - } - - putchar('>'); - } - else - { - /* - * Write a quoted string... - */ - - putchar('('); - - while (len > 0) - { - ch = Chars[s->ch]; - - if (ch < 32 || ch > 126) - { - /* - * Quote 8-bit and control characters... - */ - - printf("\\%03o", ch); - } - else - { - /* - * Quote the parenthesis and backslash as needed... - */ - - if (ch == '(' || ch == ')' || ch == '\\') - putchar('\\'); - - putchar(ch); - } - - len --; - s ++; - } - - putchar(')'); - } - - if (PrettyPrint) - { - if (attr & ATTR_RED) - puts("r"); - else if (attr & ATTR_GREEN) - puts("g"); - else if (attr & ATTR_BLUE) - puts("b"); - else - puts("S"); - } - else - puts("S"); -} - - -/* - * 'write_text()' - Write a text string, quoting/encoding as needed. - */ - -static void -write_text(const char *s) /* I - String to write */ -{ - int ch; /* Actual character value (UTF8) */ - const unsigned char *utf8; /* UTF8 text */ - - - if (NumFonts > 1) - { - /* - * 8/8 encoding... - */ - - putchar('<'); - - utf8 = (const unsigned char *)s; - - while (*utf8) - { - if (*utf8 < 0xc0) - ch = *utf8 ++; - else if ((*utf8 & 0xe0) == 0xc0) - { - /* - * Two byte character... - */ - - ch = ((utf8[0] & 0x1f) << 6) | (utf8[1] & 0x3f); - utf8 += 2; - } - else - { - /* - * Three byte character... - */ - - ch = ((((utf8[0] & 0x1f) << 6) | (utf8[1] & 0x3f)) << 6) | - (utf8[2] & 0x3f); - utf8 += 3; - } - - printf("%04x", Chars[ch]); - } - - putchar('>'); - } - else - { - /* - * Standard 8-bit encoding... - */ - - putchar('('); - - while (*s) - { - if (*s < 32 || *s > 126) - printf("\\%03o", *s); - else - { - if (*s == '(' || *s == ')' || *s == '\\') - putchar('\\'); - - putchar(*s); - } - - s ++; - } - - putchar(')'); - } -} - - -/* - * End of "$Id: texttops.c 7720 2008-07-11 22:46:21Z mike $". - */ diff --git a/fonts/Makefile b/fonts/Makefile deleted file mode 100644 index c87c3e644..000000000 --- a/fonts/Makefile +++ /dev/null @@ -1,118 +0,0 @@ -# -# "$Id: Makefile 7871 2008-08-27 21:12:43Z mike $" -# -# Fonts makefile for CUPS. -# -# Copyright 2007-2011 by Apple Inc. -# Copyright 1993-2006 by Easy Software Products. -# -# These coded instructions, statements, and computer programs are the -# property of Apple Inc. and are protected by Federal copyright -# law. Distribution and use rights are outlined in the file "LICENSE.txt" -# which should have been included with this file. If this file is -# file is missing or damaged, see the license at "http://www.cups.org/". -# - -include ../Makedefs - -# -# Font files... -# - -FONTS = \ - Monospace \ - Monospace-Bold \ - Monospace-BoldOblique \ - Monospace-Oblique - - -# -# Make everything... -# - -all: - - -# -# Make library targets... -# - -libs: - - -# -# Make unit tests... -# - -unittests: - - -# -# Clean all config and object files... -# - -clean: - - -# -# Dummy depend target... -# - -depend: - - -# -# Install all targets... -# - -install: all install-data install-headers install-libs install-exec - - -# -# Install data files... -# - -install-data: - $(INSTALL_DIR) -m 755 $(DATADIR)/fonts - if test "x$(BANNERTOPS)" != x -o "x$(TEXTTOPS)" != x; then \ - for file in $(FONTS); do \ - $(INSTALL_DATA) $$file $(DATADIR)/fonts; \ - done \ - fi - - -# -# Install programs... -# - -install-exec: - - -# -# Install headers... -# - -install-headers: - - -# -# Install libraries... -# - -install-libs: - - -# -# Uninstall files... -# - -uninstall: - for file in $(FONTS); do \ - $(RM) $(DATADIR)/fonts/$$file; \ - done - $(RMDIR) $(DATADIR)/fonts - - -# -# End of "$Id: Makefile 7871 2008-08-27 21:12:43Z mike $". -# diff --git a/fonts/Monospace b/fonts/Monospace deleted file mode 100644 index 2512b85fa..000000000 --- a/fonts/Monospace +++ /dev/null @@ -1,2744 +0,0 @@ -%!PS-AdobeFont-1.0: Monospace 1.15 -%%DocumentSuppliedResources: font Monospace -%%Title: Monospace -%Version: 1.15 -%%CreationDate: Thu Oct 27 10:50:21 2005 -%%Creator: mike -%Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. -%Copyright: DejaVu changes are in public domain - -% Generated by FontForge 20051018 (http://fontforge.sf.net/) -%%EndComments - -FontDirectory/Monospace known{/Monospace findfont dup/UniqueID known{dup -/UniqueID get 4166841 eq exch/FontType get 1 eq and}{pop false}ifelse -{save true}{false}ifelse}{false}ifelse -11 dict begin -/FontType 1 def -/FontMatrix [0.000488281 0 0 0.000488281 0 0 ]readonly def -/FontName /Monospace def -/FontBBox {-109 -1034 1342 2133 }readonly def -/UniqueID 4166841 def -/PaintType 0 def -/FontInfo 11 dict dup begin - /version (1.15) readonly def - /Notice (Copyright \050c\051 2003 by Bitstream, Inc. All Rights Reserved.\012DejaVu changes are in public domain\012) readonly def -% Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. -% DejaVu changes are in public domain - /FullName (Monospace) readonly def - /FamilyName (Monospace) readonly def - /Weight (Book) readonly def - /FSType 0 def - /ItalicAngle 0 def - /isFixedPitch true def - /UnderlinePosition -213 def - /UnderlineThickness 141 def - /ascent 1556 def -end readonly def -/Encoding 256 array - 0 1 255 { 1 index exch /.notdef put} for -dup 32/space put -dup 33/exclam put -dup 34/quotedbl put -dup 35/numbersign put -dup 36/dollar put -dup 37/percent put -dup 38/ampersand put -dup 39/quotesingle put -dup 40/parenleft put -dup 41/parenright put -dup 42/asterisk put -dup 43/plus put -dup 44/comma put -dup 45/hyphen put -dup 46/period put -dup 47/slash put -dup 48/zero put -dup 49/one put -dup 50/two put -dup 51/three put -dup 52/four put -dup 53/five put -dup 54/six put -dup 55/seven put -dup 56/eight put -dup 57/nine put -dup 58/colon put -dup 59/semicolon put -dup 60/less put -dup 61/equal put -dup 62/greater put -dup 63/question put -dup 64/at put -dup 65/A put -dup 66/B put -dup 67/C put -dup 68/D put -dup 69/E put -dup 70/F put -dup 71/G put -dup 72/H put -dup 73/I put -dup 74/J put -dup 75/K put -dup 76/L put -dup 77/M put -dup 78/N put -dup 79/O put -dup 80/P put -dup 81/Q put -dup 82/R put -dup 83/S put -dup 84/T put -dup 85/U put -dup 86/V put -dup 87/W put -dup 88/X put -dup 89/Y put -dup 90/Z put -dup 91/bracketleft put -dup 92/backslash put -dup 93/bracketright put -dup 94/asciicircum put -dup 95/underscore put -dup 96/grave put -dup 97/a put -dup 98/b put -dup 99/c put -dup 100/d put -dup 101/e put -dup 102/f put -dup 103/g put -dup 104/h put -dup 105/i put -dup 106/j put -dup 107/k put -dup 108/l put -dup 109/m put -dup 110/n put -dup 111/o put -dup 112/p put -dup 113/q put -dup 114/r put -dup 115/s put -dup 116/t put -dup 117/u put -dup 118/v put -dup 119/w put -dup 120/x put -dup 121/y put -dup 122/z put -dup 123/braceleft put -dup 124/bar put -dup 125/braceright put -dup 126/asciitilde put -dup 160/nonbreakingspace put -dup 161/exclamdown put -dup 162/cent put -dup 163/sterling put -dup 164/currency put -dup 165/yen put -dup 166/brokenbar put -dup 167/section put -dup 168/dieresis put -dup 169/copyright put -dup 170/ordfeminine put -dup 171/guillemotleft put -dup 172/logicalnot put -dup 173/sfthyphen put -dup 174/registered put -dup 175/macron put -dup 176/degree put -dup 177/plusminus put -dup 178/twosuperior put -dup 179/threesuperior put -dup 180/acute put -dup 181/mu put -dup 182/paragraph put -dup 183/periodcentered put -dup 184/cedilla put -dup 185/onesuperior put -dup 186/ordmasculine put -dup 187/guillemotright put -dup 188/onequarter put -dup 189/onehalf put -dup 190/threequarters put -dup 191/questiondown put -dup 192/Agrave put -dup 193/Aacute put -dup 194/Acircumflex put -dup 195/Atilde put -dup 196/Adieresis put -dup 197/Aring put -dup 198/AE put -dup 199/Ccedilla put -dup 200/Egrave put -dup 201/Eacute put -dup 202/Ecircumflex put -dup 203/Edieresis put -dup 204/Igrave put -dup 205/Iacute put -dup 206/Icircumflex put -dup 207/Idieresis put -dup 208/Eth put -dup 209/Ntilde put -dup 210/Ograve put -dup 211/Oacute put -dup 212/Ocircumflex put -dup 213/Otilde put -dup 214/Odieresis put -dup 215/multiply put -dup 216/Oslash put -dup 217/Ugrave put -dup 218/Uacute put -dup 219/Ucircumflex put -dup 220/Udieresis put -dup 221/Yacute put -dup 222/Thorn put -dup 223/germandbls put -dup 224/agrave put -dup 225/aacute put -dup 226/acircumflex put -dup 227/atilde put -dup 228/adieresis put -dup 229/aring put -dup 230/ae put -dup 231/ccedilla put -dup 232/egrave put -dup 233/eacute put -dup 234/ecircumflex put -dup 235/edieresis put -dup 236/igrave put -dup 237/iacute put -dup 238/icircumflex put -dup 239/idieresis put -dup 240/eth put -dup 241/ntilde put -dup 242/ograve put -dup 243/oacute put -dup 244/ocircumflex put -dup 245/otilde put -dup 246/odieresis put -dup 247/divide put -dup 248/oslash put -dup 249/ugrave put -dup 250/uacute put -dup 251/ucircumflex put -dup 252/udieresis put -dup 253/yacute put -dup 254/thorn put -dup 255/ydieresis put -readonly def -currentdict end -currentfile eexec -17F6ABC0BD4E5B049FA8ED1415B73797205424D2E47FC5DF8590627DC99082760E8B3E17 -0C18AF49528FA9DB386CE480B471EC8797784FB466233A879056FB46290A8F49442020C3 -E00AF7FDB602BAC1C4F8636E32FDDB936FC70C567B075E18878EA286E1D24CC1E14B50B7 -DCDD17FD5295A3F44E0DA80366E61263EA00234FA095739BDE371FED9A24338A8CAB0F53 -5964F1515D62E477A2F1C2BEEA2DF171E3962F0DE53E2763D7DE117F6B5328691D69C4D8 -D071D89F6AB4731DFE0A1FCC4F32351620B2B48E12AEAD940270EF4990B511E7D052C3A4 -2AAEF583BD41B85778646ED2E9A86A73A1089F502672860E7A7A9CFC2F7B2E221C6C9080 -7B7E7B4218C9B10B574C73E195D6C97D1EDC5FA365221BD82148D1ADEA7F235FFC14AD5A -47E11207058A7A9059FF373F66FEA5A9113CE0BCAF084AAE135556FE84AA4C5A9070BD77 -E7D39A94BA711FDFE442366E9F27F14EF80FFF2C342189C2E28D9FC541F049944C1CF913 -2A014935BF47B42C4E0847A335B4E6CE5016C1B8FC0C3E153C07ADF3C0B00CE001DDF36F -DE0CC04A25FA1635707299ACB277BFF663DE9558664D1DE90465FBC67BAEA7B1851FCC85 -7364E4BB97470017B40C4D54096C4AE2469A5D037963C7F009DD25A32C20487FF1F1F0A0 -124BF0B10891BC1FBDC65F9192B7236A694E1CFD1388CD27288222AE80032683C803533D -E6C39DF03BFA02DB5F35C1B99531836F38F6F04192AE3228C0F19841842F5C907529175B -6BF7B4A8D7B3F27FB39A58B7D3CF11A306701B548C3DC231102A45496B5535C96FBF0412 -004ED0658F28F845F4B0C5F02A680737A738A559E8E6BFCA7584C0A9FAB1B5D3C8995508 -856337933B9A49D0624F25CC06C8243C2A8816426753B631100403B630D81FCA4D08527F -3AE881DA5332F16C4D8B15F3CBD4DF36430C2199BE5CD27CCF4BE86F5519C046E73442E3 -AEC3F3DAD10948A6AF7740BE87874A288FB27851EF698B571A027E5787BB45BA566A2822 -69423D624D118CA8D14B389A93193F1C8CF64CDC3F0153D4B8CA8AA843C2C26AAC2971DA -7F52B17B21ACE56A7021C6255A2707BFF033A1477C42C0B5D2001820FC9A8BFFB4E9DBAB -B595E925C78C9CF87420160DC0B549CBD8A3D12352AFE06CFEF38A2D3715AECCF86E0919 -790BA8FEAE050576C4DFCB416E2DF5FA3B25192F16A935C9CA82C87CC997CA5909B956FA -1622B10EAD7465B8FE6B347675D7C363581C9B52C9D020AD5CF983284D9359F4C8F9E91B -C073DAFC702EA788540E72A08668BEA885605C8D42E5F6BAE086F3591C614D438FAB01E1 -3D69768ED2249FF1079E2EE704F9672DF9DF9C8A41CADAE9013809F1DA83673A8398B477 -A13B4B0093E151F6489A2D9BC119A66232A1AB85F31979FBA9EE7F163FD59FE14C72FAFF -A1CFCC482619E13021FEC7F10C6730E5A7FCAEE84EB5011F13E407591BCE6353D5AD0634 -D4414B008C95F31170FD8F33F83C6B02DDDF05401012E7260A3DD0213857AF9072EF5DA7 -389AE027997C2D7130443A4B2E505A9F17B00E84E142E4ECBFF3AEF2C2C4E84F162E2F7E -436222EBA20B0DB87346084A2BF64B70B1796729F845D456702C7625AD2CA3D232345C9C -12B9DCBDFAB9B8F697E5E4EF2D473D119F81A46F6FD8A03AAC73211F36FF824DE6E03788 -BD669A0E7F2813A4AA830C8EF8BE445CABE6019318806D10C5952157FF8F8286C1EE7015 -45C8F60EFA854EAE66835A2046A6915D395F1E0366A459E43236162A929ABE6ECDB26B57 -EAE7CE3731E0DB75ED207292FD83B6B288231E4F3F8170DCB831DF571EC07CE2D698CB6B -88C63F342E89FA1BE8879269D9F818C4F740C38EB419A8A814E52AC7CA90187730F43520 -115D7388390F20A8119771ED45AE1E58C1DD30B171E7B5B2E75DC63EDF55BCB9D7BF3119 -5E4BC6D91227A24B996F83BF8AA17D3A1DFD34B32E91C4F51C229796662763D1668E884B -E9BE85D60132A4C45ECFA6FEBEFFD3E34AF21DA897B24A5B836D4DF2E81D1B51FE682095 -63128FFE15E36687F7720F3C980EDED7A794EB420F3E0465B1E93755F64A9C54A24058FE -E496317919512048C2B01062574EAA66A2F86D01F58D9D252F2A84E7B44A057D8DE0EF2F -EF7B752B46B1643D7E57D2871CC15D0DAC4852901205AEB7C996A957C4A0605AAC287AA6 -581DD2C8ED591B89BA7126687F970D7D49E84AD96BCE16AFE6508B25E85D530D9A9F7A11 -E788CBC50E80F8A4ECD26C241C37078EDC447DFF2A43ED7BF1E00B6F227926A9913ACEB0 -98B833E54B3FD10F9D0CE4B8ED76549239A7F4FE846B9D57F26B53229856681CA7D3EFB0 -22CCF57311C872CD0D0342A2FFC59E2F13B32D530B0268A4D01A14193D1B17001E205355 -1E42338F7BAE7D9B02780A3D972AE4E904DD34761AA66159CEF52B226277596A2A9433D6 -4B5AA165D9595B99829EEA6E26F4E10DE1B6E0F33BDBB010A036D221B7F4191F4420B6EF -621566F238B0ACC9A7C41B90823D9DA08E327896CAE4AEE60F860240EC8A89C03E44E2CD -D4E767F4D457275E3F7AD41D4983D7C6BCEE26E6A7EBAD234DADE81B2C98C1F3F396979C -04A4E00E6F4AFDDDBE9D9EB775D1A1EE76399AEC7D30D3CD09AFD73601ADF5593B56D0B1 -4471810AF628AF86D1237E3690509FBAB8FB2F4D041CDA612467B254CBBF83780C60C1C7 -AED265168AFC379F832EBA6D6DFA2CE6FBE127690B37309F6A613608BA98A5B77E9ED5E4 -E7C373750542C245C20D10035D1163AE93970F3A8CCA7B5A57DD0503060637DEA1CDC404 -713E1DE9E328DD8D902D24E0C70B17620EA2217B7E51589626FF6923A0D76DE1B480DFC9 -CE2B7BE62919C80623B7E39BBBE748E8E70242233CCCC5899AE70F1A3B380418564AAB15 -E4CCB6BE3A9329C58D8843AA7D287D851168FB531FA694CAE2B9D77C13720A9499C13D50 -B4D6AB2A5BCAE592D465FBADE34CF7316886A7287918889EEB7FE26AB47B5319F833422D -803421C29FBCCF0D64657D945676C968938B633371EA7B3114BE2C23FD20581CDE846A7F -C5C57C4A4BFBE5A649B20E3756BA94FA8C45D0542134790D6105890BB01C961ACB87C761 -743FBA8F2549015D6B171EFD0390ECDB7744E185BB9D88BA42C4CCD61CF9AAC20B6E4C0D -A70F20091A75C9250C9F9287CDDD78D39400A85D28C70E38B38D33903E7496D3EE1FE98D -B047C84C59A60A58DA8DAC47A058A825544C1B4F4CBDFDD99A04BB691854A20A773544DA -A39EC11B14C864220F74CC2307075EBB4847AFF216614A471B1B169DCFF4F89FE390CB97 -46089C958316DEFEDDDF9F3BE4A6BCD0423836A7AC3F7A29CC863418B703668188C962D3 -6803BCEF438B47363A40762165AB9671A46F9253DDE8AFC38DAE53F7E34230ADE2830956 -F5B7EB9BE9E0086B7FB715173272B381B494085744ED8F2EDFAA567E2DFEC2861A231157 -818D7DC0898DCB8B8AE30BC0F1A65F018BBDFF3ACBA4436B5E824B6B4CC0F4402856E259 -F1D5F1C770A1589A621F9747B5F7E81908016DD977ADED8019C39BF5CB9AB35CA82CC83E -AEC842F6913929F8339EC1DCB27A53E3E1006174E2C8CBE4756F6762395DFB5AD85947BC -63137E05269807A5958D5A346528162B4C1B485E858DDB2ED3AF35A0485CBDECE9A2893D -C28B94DABA77498C26861FEF72571B5B66477862642465030FA5633E47B24BB8697E5A20 -73945D8E2338E554D66EAF307D9035AC9678414E799EC56AD03EB72A72B227DC18C3B27E -8AA1679D14FFBABF22FD2EE80C94AD06C34FE7F7597A82E1EFF272F2FCD72AECE10D5102 -BA8682441BAB1E8DD83EFAD74757A96051DE07782FE7B7D7BDF36DF39A434E59F1D2630D -93B66D1AD1A9565211B13427A036019C538D4C4314905257E8FEB31FC5DD316F606D7BFB -9CC3829EBCEAAF3722E465C60AB1D7CBA1D2D229CC28D11DF8FAFD2169339C0B61AEC73B -6FC855B5567FBF05D9088734DDD8755700C80A5C942915811567F103D0CB70611DE63F61 -9B2908AEED0B33A1CD43A84785FF49EE977D5C45E1ADE13672FBB01DB79096DFF6036904 -30B27DD8C0609AB745C238EC6F73B1CB8234794DDD9E1A41681CC004362DB2A97B8A96E9 -C981F7848C4BA5ECCE7CB87713B6B7C7CDB7450AFA5FA6719A8EF035D672A136AD494139 -8E777EBDBCA5DC8A9DFD54654883221071167CB4756FCD042891D85E4B2F5F306F39CD0F -B2E267665EC0A394A150D73A9AFE7C1098609BB6247A6DD24B01BD3B78DA1E49AAAFF696 -D27A53696FC27DA3B017224587D43372CD3406CCE3AC952D73C9AF01058C8EFFBD0C177B -204C6DF2CFC597FF177ADCAB6FCBD5F0267B00CA18311A4250FD04DF3809D4DB2C0E4778 -3D905D787362901E1171745B2A66848A3B617F29FE183DF6F746F9011AB14925AAFA1C4C -159C27D3BF8537D6FAA40A20B47745BD7148C698C450F18D0ADEBA3095F0379B7D0B4354 -E1BFFF0C63C7D745F0085D7239612CB0E5EF4B8FAEF7C19A7300881206500AC612D0C42C -66F4B99C32AF8CFFB05749260B56B7B425B550C427368E45AB7BB682C9D3E07FAF35DC89 -0AC6191384133DA9DCA3F3977243D277E0A1B833E37C4399B67DC083168310ED294ABA2B -6A96F5F1F7E8A18E5C8A95CE1E224DBBFFCBE5E54BCD199625EBB5E5DDF1F2795DD53D81 -86A5EEE389B4EA7402B14D2BA4B3D9A1F50079AE9809A0B0A5061764A3320D9AB4B5CF1C -4BCAAA4CB0F2926A46397B9D8F3B3956E647FCF3034A34B6BAB88BD4C53FB84638DA56D2 -2C65DB9BDEB68FCAD5CAB7B184EAEC585677704583CE9372F90471EA5B68FC5D1DD702A0 -A7668E6C7416E4A5CD646EFD2359DBB7367492BC0B4E6BAFA13D3D3975604E1A187A6E61 -EF6087394EAC2F8FA9FB4C040A994545480329FF5FF9B4727A39356F8A4043A74A9A7E2D -250826ADD481F91B9DB916A9FD5FE4469A9861A96BDF6BD3DAE13293B9DC2A318A35D7FF -DBCD241F2FB394644895A3F53C457C752A72E8167E6B7D4495B3C1DF0EC53127509988F1 -49D6C49CDA35B00652F148D3CAEFA3EFD8954E80766AEFCB85953366389FD4DF6D70E36E -B321BDB176FE7B75CC31A73F4DB7BDF5E0B45C23FFAD7B7EE35B9B6E9EA4141F4F98430B -D93BE0FCF80D63D7860E9B43D161DA7A68C2BD51E2E95ED7B54A91466D0716603CC41E83 -7004D94DABC5D971330DF98672136E372129A77CB496C7200FE3E287F7936E8002B54C51 -25B364B6E07943A078E2C018678B7E159C1DFDE7633CC3633B38D50C54B98B45DF4A972B -93B4B4013F8F1EC0083B09F3FAFD2CE2B2ED5791DDC0945679A122F21B4C5D67DA6E5A5F -2A5893AD3AA7AFD891ABC6860F14EE16DDE548520DC88C2CE6099861B038EB25A01589D3 -2F4AE37FAA4D171416651CCE37FA4EB8D063A0977988E50F9036C0A9C8E99E6D586EED28 -E0FEFBE7406386EB9FBDCBD8DF820F6371C99C6F7A4F2E3F43FD2792A9A2D3F81BD3DC6E -DEB59B1B4DACC2F278A0C6C1D3B841A73525F311504CEFC8538CD53C487F612D9045AB40 -8B8A76195907E3B679CE68322703C2F80A50401BD44BB5D14080A46F859075C9B51BF0A2 -C42321EDE4254F558FE33357746631F407C16675320B8DF3E24E0FBE2E93BF718CBCCF5F -F21F013313BAF474F239CD0FE72EB03279791A95BB322DF5C4725763052185CD5CDEDC76 -071B4B2337B406337237A2A6490D75598CF6010D22582B8A12871C17003839A8A8C42E92 -EFC92B7EF0763D7B6481965F890802C7AD345F2FFB5A444DE404C833D1D9DB1CEE2DABB6 -42DB540CB398BD2C16A7383E649A0714154E72D94438FF904755399C1674F5E01CD45590 -CD04C4FE3292356650A3D431D7600426A1475B5919722726468C247BCD565965DA6E4A83 -28644CB1FD2A23B1B45F74E6B4BA9AE065BE873BBB80505D16D54D9DE69026CF1DE8DEBD -E472F067C70CB4104D23ED0CC9BF68055283A6CC2AAF48FC59A580DA8597F95EBB8F61FB -C4F6B12FEE888AD60897383AB17D227C0CEF95E86F149ED6B71C2FD67F5A996E8B34C5EE -23DFFEE49200A250611E32FE3300AEE9BF13790703B6AC983C965F1C52D2BE0BE876D4A8 -85FCE072D5D584B12CF2CF91BD7D7F9EDA1D6FD62F40AB5682312D6138030FA1EBE9B194 -1DA4ABAE5A781EA979F608C6F0D5481CF48AACE9F79031574204447596555188C3D6048D -B9D7D8D1F0B67DD5F3468E7C7B647DCD1AC3B3C95E1DA6DA05816B49DC8BB86E85C0094C -6C9A703B88F020363930195842A753EE42B4BEC13B668101203BBB7D5CF7E9C3E39716B9 -85F4BA374147BC7B13BC2515C8A500596D35152A102FA248B9E30D6050C11045B9A81213 -7C228594EE2725F43CCE59D3F1669F0B4722B2171811C2A12B1905C0B40EF1B1957731A3 -A20D29302DB48D061351430549F57084C31D008391BC9D20534EA98CA6F951E00FDE49F6 -22913C19F44E489CF9A80274B43CA60CA5C517C821426D5BFA185649ADC0F1AFFE8ABFBC -A0A03CF0DB690CAF902219A5580EEB11DD3ED650979550454929EFDCC32C7E8418B80F54 -F0CAD6049E2EB23D5DBC2D680772F03E8F3D19913E6F771AC65C1575AA6968CC6857633A -C2520C09AE900BA1CED6C5C21C2CF8BCA8D676A539F22DFE03B4134AA8181CB38BB0F69F -C83517AB3AAB165F2A1FA474E067627199406D26881E8066E509D3C39A1A8C4BF99D4D46 -922EEA6D05F7EBDD33A33774F24A650B9170D2CBC9A69317CF90010F9688EC72B3DFD2B7 -0EAE5DE97C03A5CBC355E8A57F7C36D9AF8DA95B4A307965074244B72B5689F6DA0FD360 -DD95C184A7037397C0598153F96AEBF3E059B042A3251AEBAFDB90631C7A7E52C89E7623 -07487D51B8A019BE505E4078DF87A79565DAEAFCBDCF4D99E658A3A6F33C252CC8FDEA27 -CC974B91269FB2FD905A619159300A0274E79C1F52ACACBF68E03CBA15523A0B2081C739 -3D397D3D4BDF3094FBC5D20852EF7766A4C83B708E2F75008756044AB2B55C57559CF7A4 -636F74B49D18E81057BE38166F87DF24C73B337533DCAFC8F7D4EF0A3C4C6B82E9BFA3E4 -F3116E011FFC4A89B7FB72CFF1B0229D6D578AC85DC6E6C3CB956193689607D6D7A48367 -0D7C529E5C5C223E081E3C6F1F3A2B8BA8EB5C4DBD19F9A5566694EDDAB69837B65C8299 -63A95E321181E4BA0B097FBDF72647838C8B49DE3AA88B6F755317FB1785E12DDA71F944 -49D3D1DBC0C167B3793747D9D6EBF6FA13A74FE1FFB6A2EBBDDE14A21040380DA4BC9088 -C60ED587EDF6E2A00BC041990F00C7568373598310FBB5FE87A1656E381A2C449C63B236 -5BDA6D3C51D1E5A1A0ED408221B2FA8397FE2FC992F990DB3E772F3EA54CB468AD471FB8 -0FB1E1A9CC6444B98D2993F5DAAC9B5CDE3ED8AD6FD8DE80001DC7D67A09B39BA8D0B35A -CEFD510CF34838F06C72047309CFA29787631CD33E0E4457DF26244706966FCAD9A90668 -A155F9BC4214693A80C3440F56C2A01D87AD998493130C344E9560A88F9969585B6D2D4C -AEDCA0D1954D6C84E0F717C48548C60B39D0013FC95E3DA0C13796130F3E0D8A240F8ACC -4BFD93D26A7185DE5AA0C493EF230D0A5EB0DDFBD49A66A61D814D2D03EE94B40A25F8C6 -5F615B8C4402B4FFF0A882316E9123C0267E0773E048658ECF5C0008EC18976EE2F8CB4C -E5B4C17F857B83E16622180B70F0433488E58826B39221566EAE2A9C350177F10D9737CA -6ED009C263E3198F02D7A3514B3AA1AE7B0BDBE901D84DC256855A3DFCC83BF51C9B3CCA -1FD2756DC6D54280E164E942530CC560BDD8FA6AEAD30EF5BD8A4A30EE5755C7A4D7C550 -F0399CCEB87FB781EF298DBA53BF7FC3373388DDE9AE21AFE51A7EADFE83767E8A112DBF -C595A9B0E833CE7F8ECE227028F10E36B8147340F6C0152DADF434AB60CC64BD9158E0E8 -C30F38FD0D5D7573D43FC3AA9403BE945DF46D040AAD91FF69D0B0FDDAF19EDE36F089AB -D8E00D8417C463C1CB3292E6AC20CAF026C74FE0F97CF8D7956678D1A104002A68D53664 -A82EAA93112A3BD2B55113F37E8588E78C0429E482259A2A0C11F745A74429FBABB8A53C -D40101CE27011FE51335D3417E41ED1A8D260EAAB7C3F118B426DF541FFBDA96C4FA9859 -66B99AAB27B4DBFD28304F386879C6DF62242B689DE14BEAA08BF07AE4A38B203B024F88 -808C5E227B6AE750142874E5E59B23AB9B36025B6D67EAE9B8DB60B9A04A388525D1F50D -C46F8172AD8DACEB870ABB56944F916B492DD6E9D296049973D661689E8A416014D4D2C2 -782EAB49362E9FBFD5BD6F0C95F243BE717535005F99A22FF28A7A02A5F4BA4B1F505449 -61ED383753ADD0D2952FA9313CAA827F3D8F8977C98D760E4BBDC134DFBC0A008230D337 -35A048B81A94A8CB7034DE777595158CBABDB648F1A2325655EB64B42C24D190C2979F9F -AB4C9DA55299AEADE3801F9956E3C62A77A16746073EBBD364AC634B37671C8F153B8EF7 -D9F110CEE184CE3394349EBFD88E43D15B309DAFF263F4BECF1C581FC4CE876B68D3F1C5 -EB2F001FBA2809FDC3F834833F39B74C9E5018C8A7CBEECDFCB121EDCE0282988BC5BF4D -156D91F53B4EF6B9FF7D95CF1B39B679F06190A10C3FFF40D461000E3F8E422AC042148F -E12B5A776BB1F15D44D41CED498A9AEFD2CAF59CDCDE5C4158B8CA1CBDF4FB5AE83D99B1 -A39770AA15397D85F77F42846B0893AE39A0F4612A62A7D963B767DFB1E92A0B73FC65CC -EDBAD8D74D2C24E08B2D551538DD954D94A80B92E897E8C10D1725988EAF003E9BABE962 -2C9C8D278A6BF1935574C80C6815BDF0BB7011FBEA53A59C0C45D1978A1D3E6A7BCC87F4 -2C5FDC7886044CE5798F06096AB7FB360316E1BFCE3E719A1EA906E0C5949E00DE7AED0D -E6C25832D30CE1867387C8254F51171A9037C8CBC6D339B4647E9077D605C13E30324180 -A433FF9F3A7BBC3B0B775A860F7BAB63D7538E2092F902F019D29FE8DD198EBD85DF0564 -D39C10DC176F698641996117778D7F899153CB26D568C057DA39FBE2D21ACF39E0756E16 -7FB5AF562F190A7B940A8F4BFF98AE156D74CE4C8CEAAB103FE6F06B7D578E5D7675DBA7 -27FCC0B96031ADF2D3F204EF9DF63D8A4263EBE46B74F1A2CB67D620FF5B2585A53C7CB0 -DA53F6F219B277BE9F8735014BDF61936C3377A6D1348D3C670A65CD057B32DBBFFFF5E4 -D830E9CA83BABE9298431F93884E2083D6ED6DA68A30C7372539DE05E8CC9DD8A748C810 -462687C6B9B75B305C3A31BC32A122365DEB55AF6F6D2BA9468247BC0853E7144E46AAE7 -E0D7C76E8BA15289ED307E0943F5E3A05F051AD2C2EBDC7E2BA46F91B4CA94308D1D2FF3 -FCAB4EDDF761FFCF83C23C979E4D318A51A26424D78E5B215EA33F04E1BE296A9693F065 -9309FF404423775875D73F230FCD5CFB1AEF0F6CE5674F865C300105791111C1AAFC98A1 -557123E1C34749937C8BDE11E41C21B1B0FC53E8C5D199D3289DE09C7D7A95EB23D5192B -AAA67A13DABCDDF6C48115036065984276B126F294D6BDDFB90BE9319F3A3D031A22BBC6 -05766A7BC934472D23812B37720AC3403189F34F2CAC2B674B04D3B3B46B6662B1C2489A -2964D8EE5EAAC87A8AC7208E5E87358DDBEF9EBB52B96102CDB82D8BCC5D8A404DA247FC -C304D7153187BB579C75F71DA411E4B0FA80D2131D11C6BD693F3AA001FB349FA11B5FB4 -9DDC4B2A6443A8932AC4813795934D61D38BAEB1847EE5D3A7D01708524B3933B442709E -CBF2D39460259D44CE01645BCBCDC2BB9588C855936C6100009D867FBDC902475BB43DA2 -F7A309AE56082F18E670A25BA12213EB7D9BF6679452CD4814353BC62C1ECD5E1A7C50EE -43277A1D5D124BA9F596E19A29C24C234B1102893D2BEEA07F22450E26BE882D0FDC2AEA -5457AFEAD360063AF6A079958A343F444DC6EE7126AB88ED079C0165CF95765CC52DBBB7 -3CBECD85BB4F1176C4608201A6E2D3FA69C439B4AB2A9D5441F519DDC85C35C2DEE504DF -5ED9E958F768E9FED68D18748C8521FD6163FFE0DECF1BA44B11A261A4997D13E045C255 -0CD95881B9BC5D65A7C4AF0DA73A637F4979A3B54B9857402738B1E9FF94CDC075F51817 -CDFE1DC677E938F4ADB9E4CE4DDF4F12EE6C72352175B8389F39F84181C189F1BA529E9D -8D84B7E36790C1F57CE2117811E986D00B58EEFF6C8121934AF2FC54D09C486A5D9CA8F7 -6887CF4D7FE4841F3222F0C4E4F7D92C014FB4D48DB83FA87C243D453915BD6BDF5278BF -1C16090730765D68AD17160744DFD19AC8A754915E669074D4F3A9A1F37F7D720B38D5E1 -5D734093944BA853010ED6C6CC7D5D885D6A1366B2FEE42E54718A2DC1BBD437830EF66E -A0F540524597090FC7C762F19C3946274500428C3C3AAD98D9611484C8CD302D64991438 -1F7E531BEC859E6D6624ADE92B17C4D88AE651E49658CD23840C404E1E2EEA4F56D6725F -E514D3AE47AB1127EA69CE677705C603CAEB0DA31233E15ACC5D78ECBB90DBA3878F19FF -F2A62395FE3B8EEDCCBA872A42334251BB515C34F513D2FB745033E903863C24A7F8A47F -0DE02964F1D3AA92E60BEC967BE17A207ACCC4512B8E8D62E767608FEC0D4F0C6D339364 -0332BFDAA278713788075972FE7B5799FCCA94BDE4C881CE667C4B7D10F1A4CE65766CC1 -F3486E0F23DC940A93B3D88EA329FAB54F531034113FC7970DC304A20FA97FFE7116C6D7 -1504BC0FED9A1C8E617AFED697DD3FA441CB5894D783512E1FFB859EA5686F64381EE1A3 -471572DA94B4D7AAC35E3E77EC8ABBB310D46A70C5AB691B050019B1408DB7D155AD3F75 -27E8FEF1F1492E8C96C96A0EAA70AEE119B244995F1DDAC5F9E1B4EDD07AA389382345EE -2873FF17B725037B66F7B5B3CB74237808E8A1E8FA6B597F418D62D174E716C0A857219C -DD489083E9086E5A3564A8D0925003BB0935792B38A458F451CD15D8824E457132B50F8F -1A486AE2AFAAB124EB8D387A4AD23B552803298F23AB33D96547E1A028FDEE361836B59B -879F544757214D635D0AD01C8B8D8FD61B852E3F6BFC9281C99D1F360032349FB484BF27 -256B591CAF48AE5A6A1117BFB824F3850E95E75AB6FF948233763934CB18CD290BAE9E53 -747FA478BDB6E343336F58D89E05BAE9B912D484171ED576DE30D6516D68FF80CC6BC36B -62CCBF407447126E8B3D6D07DF3C187AAB240B84B5D07CEF0CEE8AAD28DEE446F321C622 -0A7E0026C64802A9A006887A170FBCB19B4C29CE1D4E089F5193171CA3D3EBDC1A1286A0 -60C648D24BBBB8791BC400BFCAC653A673F4C3A59C44D364D408B72437C06DAD89512F6B -9526FF964C3B2646DA7E34E3DC95D2408ED3816C6177133287B88C896EA7D575D1389971 -2A9D3A2E689C003CE2D5DC4073ED052F37A3183BDCE5EB3B509385AC8268DDC54A33F8B6 -865FD8D63ED1C51B89B07DFCA39914F10AE7233C7A62EC9B83A8C6E3CFDA24528B1D1F80 -3C74A108E7239456B412EDCDDD5995A6E56535CC9D47E871B0CF8B36BED4818FDD112A70 -2704D417B79347BA3CF24A1B116937BDCCACF86D8D4C544AE863DA44A29C308F740F5DD2 -3FABD1DC281D722590624DAE38EB4A119F5F271C42169287D8E37D34EDAD684EA20CF29E -EF4B6BA4D65E41E9E8BD9EF2321C2453DD84C5AA056017E7F5321A3C11614D810D0095E0 -5DA9C4ED65463C672FF360E0104F58A79D7C399F058A9C6BC6298AE226E06F294787A1BB -0EF6E1AEF499BEE46F2AD81296667E2896098DC7535E1415E7BC0C3844E308807AD7E5ED -59EFB26E2E6E5FA00B7CB6B1A160DB111AA0072ECB249F30A29643BE8F51276A0DA7ECA6 -03136C0147C73658D218BAD2A6DD880C62186178E527901CA62511326630815850E0F4B3 -7D3EF6B96BACDC9EAE70FDCE411297A167780F749BF79652EC2BDD4E620CFB45B8AA9AC7 -9BFDDF782E3B3A6FA9A0B20F8CD7362AE18479685828245B6069F437171A4678C6C1547B -5E4E998C8835104327C75298AB50A6A0D2ECFCA02D466C08669A93BDCD3BB186F04770DC -6AB7C774D2258C4E8C54D56C4EC2FE59EB24697C8BACB485E4DC203630B052FE09D83C97 -781AAA7CDDDD22804591A689B563D318FF5D269ABFD3278C345F6028127C672C3D3D8168 -5739CD11FF84E88C3BF219A41AC1C1272BE1D130A8D01EC18A83906CBC0E02FB4F430026 -5FC5E19B6A5BF67379EA2AD989A1BE64B8BC230CCE5E6782514D465C736B904F42D18417 -EF0A985121A8B155C06E1D0ED8BB3EE89226D931C9A8A0F5E80882DA98C72E346DEA25CA -C3962B6C5879B6AEA1F91DE7FFF9453F98FF1FB2805B21994C0DB8DCCB8872273BD7D964 -EBA87F2FFBC46DB4FB8FDDB5840A162CD6F6BAF0377B43E5DC9DF9054B1AF843D5A4A38A -481EB2DCF93C088FB019F8209BDD37502B8190281BA5F0A91171AE14E313617E74B751AC -AB74070193E0F231497C20484851F0182889D77581BBE0B1539663F844854D59F93CB6EB -A5CC3D2B3FCCF8D6C3758F5F333033513DB561A9E318F599797BCF0FC43391DD600A91F0 -B478A983687DADDCF974419A58F98338D9FEF2036373B5CAE2CCBC0169413BEE50EA39E0 -AA6E922F751B981FCBAA8702428C7FEEC0BAA712989D5F1CB3692F5EE3A014F716D42CB1 -42FA136A7ED845F781C18C1ECA0B6B10699AFDE08BA05393E413BFCA01C7A097933F87CE -45D7A7339F2793483DFB43A26B277C5B5D5A3A51CDDD80D0D6C1FA7D16E03DA0F7D86E50 -85D4516BEB44D0AA911A7945B244CD4A83FEC04985877D15CAB67EC734B1749D837AAE24 -1832A1B555172307301CF5D25EF9DB48B9BB1979893FF637A3C3A86A6D1688F0B45A411E -C8C02AEFA1764F5BB2423707FAE1439295E75E365785FE9B9E5C485779D124604AA59F95 -B8A4025E3D8246CE7AEB3F659B0309C77B6D10FDB120F6A4DF76EE00EF3607EF9D22EBAD -0DBA789B86339482B98F91CB29598365A5E735EA4B7AB18AE1AA8AB8BFCB207C558BDEE6 -F6865D10C8B3487D342C1F6E74CC0B13B522BC054AD4EA9EDAEA215359465BB97CEB6F7C -657ABE5577BCDBA7DD3A61B2C99F552BB70479328AD21F95C8A1F98D019CB23B6EED8808 -658742B1AF408ECF70B36ACCD4F06E4D160EA52DEF62E9CED463FB758C6121724B6E31A3 -A097A7D21B0D5A021B28FC000C68F6A4126A5418EB129AA699D04482EEBE82AFE18A7D3D -0608E71F5899272A4E614E34005578746F6A9D082E29E2F03EF54E9F55D393AD28477E27 -C780AC02449FDFE3314490520FEBA7B38A16E94A302569CFF6958FCDC79561F3F93FC71E -14E780E4F1E9DA30A9B1CFF569368069B140F5B8E67EDA15D0F25404A32362327A0FEE9F -9AE430D517AA8465C72E9490C31153E3528F08843A100BEC4D4BFB6C5E87CA088D4D4C18 -2E398D02AD5D8007CA369A83881AC0C886E72D91A48EC085002017066262AD81925B365B -7E594F3DF58C55A9DD737F2069BF951DB68720AA4043BD6F039AB927F7149DDB7830AC67 -293A70B6906135DFF159B352BE8AE55F1D03AB3BF5642CE1B1A49F773FFA1FBFCFFF851B -3DA54CC2A5BCC6C2EB2BC5CD41676EB08B727526CBC01FC9C7A076A5342BAABD5341B6B7 -3ED8A27013ECA0861430BE51B07CED3522A6031EE04E74F985F10D3776A206BBA86FD199 -64B37F1A8998F4BCD2599A891C5A61C131B23D29788719C15728644886443D12492C87ED -8EDFEC9C5620F7AE2C5CAA568333C26C8866A2E2651408D2BA3B40B68875FE271283A331 -F8EACD13FAED2342A5A3A74A1E76B74283898D8B265E0FC9CD3597CFE85FB55B56AC02A7 -55298DAC4A7471FE68872B311B690E5BC0AFCAFC4CD7EBB5326E453BB07A94843935CB49 -095EE8C7AB1BDFB71011CE6A8AB7F51363DCB97AF77C5C1CF0996F7F1A33BA929E9D32F3 -FABF10FF45E9E53A4A80B808548BF1D70383418B57C986341796FC5E1309EED60AD85476 -A7FE1AB5AE38258D917F267ADA978D02FA7F44200954F8230FEAABC0D7ED444864C91AE4 -4D6BFCB7E09DB0014B6E11FE753C6CF12592156B7946465D1D51C8FDFF1671B9DF64FD18 -0680EBDFE37D5B19B60BAF8A1081C8107C0C207941025CCBADF11423B7F09356B7D2B25E -3C8386FA4F41617DE67D7BE0C3790F853CDCDF996CAE79A0D0113AE8293426662D18E2F2 -92452A9F2D9B3845FC5B9ED4088DB9CC86886D82FE7310F2A158BD57739A0A1C36A7EF21 -6167ADE2542E5124FDD3143D353122182A9AA36A530C96AEFA8ADACF50A5B0266B59E396 -AEA8DF4FBB2AD02EBF24B49D4BEBEA6F1555B5515FE3052CCE0C540D20A82D6EAEA1196D -5A2C029DFC79E48CE0448F7A9FD83C7F107B40E55383E9656321497CB2742756FBDC2646 -A850AFBB90C1573979B32A29CD3E1C7A3350C9E1727E884CA842E9C60601092595D44011 -BB4F24E8A505EEB5397445011750A059265CF4212B4A5EACF7CEF1E922722B365987886E -481215C980DAA2114E03DCC02D1BF8B29098F54733B3090E4DCFF294E01915AF5AA3889A -99F6656F8BB7DBB5844EE7A9FA0FDB8AE67A2634BCFF57B248772F9B5F2E9CF95410060E -22C51E6437EE48FECCF819B1655F052CE6C6EF2175A54652EBC6C38F7BF60799733741CB -D7E030198D32B9956AE908436200C6EFF6611568EF351402A3EF854B0736390F7A16B7A1 -50EDD6E39B2E0D42439FD75C1D0311C8C45138AEE49A7DA2F742AE3C21E19F6ABD62198B -6DC17A3A315AA746961425A18051A0C0C5653D40F9A6D3A542F430DFE71ADAA74586FA56 -9EB935247FBF47098C4D85417C0A3C6E567F7A65B7C23C1060AFD086186E394896D1DE26 -9244085D469240E8391ECD7B219A887F01853AEF9A3191AE70D8D11FB13C7578348599D1 -95186180E4AA0C3419322A318487A712CCC0EE9954C87A6FF2FB447278EA942C101E925C -95DF648D275C836F03A4D1FA85144C7D57622FAD6BEFDDDD7AE2E931D430E29885E83E81 -4C7DF4DFE157A423A163E1372999E34A0689EF8F66EAFA66BCE76DC6CD5F3317BC7801E7 -F090410D2AB40B640777C30476CF9BD7446A9860594FEA131D308D9AEF8F96B7B8731ADB -CAAA0FB8585DBBE770852E8A76A43FDF93FE9566F81A02C2AAB4014CD74CFC1682F33686 -418EE5FB80C2DC2A155F16292FB6B5C35B230038A91814B625EBEC0089B75E7F3019490C -32BE5B78620FEC427B756A3A8085E42ED93304D80108A5D957E479933173EDF77913E5AB -C5B84133CF6B09FEAAC3A41068883696A3E2FAA73FD401E4A5E58F3F7258207159970234 -FD586D1C34EAE89F2213B28F3597EEE1C0D11CA93310C8A294C88119600944A539795B41 -E332CFAC0E578B7E9E9CDB291FAC7B0CA3C125FD3D783E4D955DA04AF2EA8B5C97869104 -84FB27D05B95C8C8FA91C84AD9BE171106D0AF6AF582343250BA953452E1237EFB0142AE -5837EBB076D5C7B6F25AF4625465CC89B27977E6CB71AD1D4058AA871CF3FC749BC4B87D -D7F75D3D18E455C67705EBD876D9073D828D4D083ECD7925822732C07E1581B1FCE4A337 -EC7644EAFEE206C62C1A64E10F0F1603CFC09C98FC36E61A59E9DF4C1D410BA2B775C44E -91001A452798FFD0954AD15D9D20823B52740716F40354E503816CDF0EDD7B6B97879260 -1204972E0B4F8E783317388D31B2DAD3132653A0585F9EF80BA68093A79B773836CD6E62 -CEF409A9A4007D3D7760167F0719F5A12DACD27BF8E0903C75A2BF680048538EF924B616 -FADD681B2E850B2C6AF69E86C491CCB41F8F9FB000F76155B651133D09135EDE439B6A99 -D4B35A49E2AF4F82A369ADAA500C873732664D50879258A9C663196BC29FBBAF20A7FC9E -7DC8904DB9536C92E45F958AD46C067DEFC27FDCB71A7A1E2391FA6B6306B71ADBF3D6EB -1544F077E38D93C9ED11B2CE62D3E94064FE75DBA762BADF76E071BCC5507244670FAF79 -F5B0E11CD72FDF68DDD6C03E6D42E4D505F88554662BCD0CB4F5A0A33CAE7BF80854E715 -8B4E020F2D7517F8B5AAE67675E7518C6A14F00938F36E23DA2172719B351F0A19CE3691 -12DB35771C4EC37F61669D570932E14B82E3B419ADBF6D0E201587E0DC75A1DEE6262DC2 -6EFB9A02174CE7C7BA8E626ED0BB8732AA3618909F69F2D4147F3018494E22ABDC63C89E -DFEE86E6B21DA05163A32415E6142528918A6936F05948C14B2E34FB4694D5F664AA766C -5FEFBBA0F344FFA065F5394F621DB9E6427EA543BBAAF77515D7EEFC5186ED5F9EC74A97 -FD1663195D941CD67C91A5217C8D5C7F1BB848C6A3BD03A2BE6A48C1B2E8BE247D02C01D -B04A994F207D25D5FC46939095986DDDE77FCBF9698D3748D12888D33A7E429AE13C8194 -D624AE196D2F1F384F2B31801B2C3FF3217046A5E11890FE1D63DB4159CFAC405D657BA4 -E47734669D01E953B6702B972981C08A0B028F5655F7C8BD1DDFE145BA1D57129CB9D5E1 -8996C0A0E01285E799F4753CA5879F862A765B6927D7AE8FB474E8169708E1D30E2780A4 -F6893E46DA3F20CBA50BC6B8A310A9BB06713EB126961C97A9F2A4393D663E078026657C -AAC7E6C723215F0FBE58AF074418AE70EC0E710C97A1CF4A0FF853A8051F18BF4AA7DA5D -5B52CE39EB779B75843F14E7736363EB213F3DA581741C7D21D8DC268063C46E97FB0B2F -B525AEC2C6F2D25E0EC43F91225719B4087A92D3A44DF7B5333C64B92862755D5D9566C7 -FFAA3554AB50821AF913213B8738D8FBEB7CF5BDC7E8F191EB3B66A8AC1DD9EF0D5FB967 -B9B1833D8C67F0B6AB2A32F00D20FA51E841BFA6ED035779536EB6EEB30CB751C81D7270 -FF877E2A0EB624FC8CB8D40830B9FE2762FDA8F5A861A0006CE1397598A712DEB751647A -2E5AA196BD31465961D4CFB2F9E8C5C20BE1C92592B3E457CDD05B11DCEF03127B494B8E -4AAE645ED3D891973EE5D633A24B19B06B0F2389FD5ECE0FC1C5091B8334209AC3DE128F -8772D373142113CD296AE0DE58B844496A70FBBC89C09629E095EB1E36DB8E73155735C6 -A4029C1CB8D935F3B563F68AFB6D1DE6D40A59A1F7092466355C7C1A5C3792353FC4A598 -73E5DB876C029895CC933DA80DC11368BB19DEA413FAF2F7652AC6A18ADD92A7D647883A -4201773313B677A7A1D0F4985FC8714CD9632C8266BF7317E557E79CE1EAFF26C5E19F95 -698799264FC251C8382158ED39E613F3BE87660A5F1F2C6F7D9EC08A901E4800463E6498 -65F2FCFAB56F971730824AED3970830FDF3E57802A4CE2DF1EC509522D0FF75EE464A502 -D77A0E9095DEAA555B6EAB3506F2B13B817B60AA418891969AB75873FB0553874048C1F0 -0A9C61105A9215572B1343571CD14FF0AFA30B040AA95AF309F412692288FF9D941CB245 -5B8FE672B4E78D6FDD3AD9EFBE0EAC354C7AD246456CE0C8166441D72762B6518B6EA8F3 -15898649D17F406FC07C50F87F04C9DC12284D655F3A4A14A3D55E80E2D3D054828CE8A4 -2E33D9963903C2BD11AC757687014D2DED8D1238BEBB7260A96D973B062ECE3D429BEF7B -63B4394A2B1DE4F56D0729A7956030F8757762F13A90E211B7B245F3E968446F5AB19621 -5C0A0F6F13957C0584357FB760C68D41A89049B5FFC42A021B1AE9217BCFFFF0063877C9 -4E884FF624D80BFE56F79CA93EBD70844BD30D51D57E19634287881CEFF135EC18ED3873 -596C7C9656B31BE31655F2630934492EE1FC3E44B9607F1AD8F4E162C356A1383AE4E797 -0D2FD92A69282CD16663B2B9D199702FD3CA9B6CC7FB12A7A0C2713B3F5E81F844BEEB2D -F3EE1F31BB05BF57377B9356B776D84711164A49AD69C338D8AA3EAC2F616E735E5677FB -D54A8140DBA442BFC8CE397B2F7F200E9B8AE8417733F90B2ABD1C70F81259D944090B92 -845767E935B2BB7D5181EF5B3D50FC31585BAC37CFA267B966DE999D3B40B2023F132ED9 -C72F827C28D41751D67B98ED61FE3E611A4AD1AB2C45F303677C79A49F774F710004E604 -0AE91BEFC6C8DB58218637DE4923CDB315E941E5E124AFED06CBD0B75484B7B9DB3179FC -5759BCE19BE50D07541DDEDF00C0BFCB084FD3BDD10C4EEC22DB607D65C29A6D78178AC5 -AEF0CB466EAE31EEBFC7B25B2AE157C69BC0747EA3222297F4DD937E1523B9864B62A666 -A4ABB9B4B3A908DA0C37059E847AC1405D2E4246A3CB9AD3B39BF3BEF16D48F769B69422 -7D6743C49F6DBCBA1113DF16B64272848F092C34103B40DC3118AF1CAB1E743BE858404C -3A9831ACE27D3DE50EC75F982D9DC1B6E34BC678A07D214B0A22AA146AB298647927FA54 -222DA2AE878C8A0FCFDCBF90A76CCE2D6CD623818121598C31D0485C900827C91AB17ED8 -3DEE367788418FA250F9841DEBBC95114D82CFF93E8C6164C65CED77D5DDAB4F65FDF19A -26FDF57FC3AFB4F4D155B1AF747A668724F1E2FBCAB941987A17D4B455A74F4E5DB5BD62 -496B197DF439701DD993EB50F92D161ED2E37170EE2D1DFA169C2AA43752C765FAA87107 -3DE44D8BAA93E6511DC365B68157C81C8F3DAC8C624E58EB22CEEB668A058E23F3DAA93A -D05C5B1DF3DB0C88D6FD40113A851F1387E9E2EBD2460EB7FB642BDF4CEDF1B22DBC51B4 -2DD058AEF2CB32B20A30F1948A363458FE07B146012FC3842DE485E687408187A89B93E5 -FFBE019CEE53E8A46C3BD54D12D35DD09D638B7033F0E8B48CC29FC898128F2359AEF423 -192C75DFE9EFD8FB5CD2ACD71811F5B8BA259E9F4179CB1385F85C9B1CEDE79C47ABE400 -0ED992A100198FFBFA4ED40B9B55FD2053DC49A2ADCFF0D18FBF9964BB2976D676FE54E5 -5051BF7FE08C5C70E8AB9A363F98DF09D22AFCFC8290E828CFA5E965574043B310D9A570 -98EC92E2876DDADC2AB52B05564EEF2A64AE2327DBD80795618500D96F296E178CEB3042 -F1BC49CD8112A5A373D6A72A8248DF6D682245A134FCB990F9FAB1CFEE41DCCAB9CCA831 -2B833D6D21BDE04BB26F445093A8C7334F58F3B0FE626C0832DB7BE2EE788357695F3B49 -FDF2B8225E7ABB6FF7A51EA4F03F3F4CA1BE00F70D74416FFAC47C4A8480D12FDBDF2450 -5D53A882988C5747FD8729FFD263C88749AAD3FB70B064AF33BD21630FD5853FC8EEBC7D -91CF02EAD8C57CE136A4B223AF4BAF7D7C08BF31F1718318BBFA9D416594EBC59E8D0BF1 -A2AC0249835FC1C274065D9A28D0B8D751B9677FBE7D970771A8FD96700F00A13AF76158 -AB7437F5EC667D32D8287ECB8A1794383896EA4BD9AE047EBE471A9500E94C3B9EDD0AD8 -24C9D9DAFD1F058929D21244D81A276712454324322A3CFE36FE1CD8172F502F427322F8 -FC8ABF150BF749B132A9E93FCD99AE015F1D75D923F9743C23F0F2264ADE0BD0AA7C1C8A -4BDDEDE18EBA55BBC33B3C9E9204B1418D7B1CF592A5707805C13D62C284B991C817B643 -00FAB2E0457E59E07CAEBDEA55F1D8FC9F6938509E1A11168539B92705BCC03115D29137 -45D24D1533D6988DBDC21795FB59E25850B74A265C47FF6F7A548066FA6203C503BE4E7E -1590689F1A4F73B7B39AD4ED10D89ADA19673655EBE215CADBA0FBD85DF65326ADDA0305 -FFF9BE785E52F0797A345F8A49A58A704106EB220F88F27180B3630AA358BBEE6E27908D -512882ED69166A628B32F06FF47D9D05214A4C8728305DF287A48150F2652EFCB1B7CB95 -AD2746D2F4C10847800E9EBEF69188B770D583A079C79DA8D7FD9349E925E9A9A30F2D8B -35EE7115158B3B353AD7E4E4E740D93289F2CDBE6A75E6BCC8A0A3221CCE578D3A974521 -9C418768B4E332783174173ACAAC86FB61F81DCABA0F46FD3B90D46BBD8F6469C30DA380 -A5A356499394FD428F7DA46DABF232202A8A293B2DA79B4933D0790630A57DDB232E9E25 -4DA8C370F1B3EBBF9182C71EA3BB243DA9685B9B8C1DC22D73B3BE40AE56B08716D1F035 -586556DC0DFC07AAA66F5B3084B7BF87D0AF89BC6AF8CE1CB73B56A39515D44DFADEF15C -E018E31E7B4C61B109A6E105505AB97FB8CD2E53D37BAA3B1C2EC25DB055D87245A8BE47 -94A6E03B71A5F1D13B6E5A7E6C5594CAFC6E303CCC61E01516262F9BCAC1B745EE5B2AA8 -C0E8209C20A1EF19E93222C31B95E4B4FCD0F78F7821FE995494A98BD756FE546700A590 -FFB496FF6852E53470E1A5AB253464BDC12CFF3B5DACF8EBB0B99E822322F21999337A6E -5E849866939D87B2F16DA93B9F8CA7C83BDC49A4F8C5EA64E8F8A1C00E0BEA534C499C84 -4F39E38A06EAA1102A1DFC0E25643EF8A6245427D8E77EA2AC7B352463671EB6DE8571A3 -84D98E1B35C3213F13132FE76D03AA87E5918FE48CBCB8A2F3EA9B1886BB540095D97BD6 -188DA701888410081B8BF49C7043BD8C48E18A51042E92B542176964E292BEAA06E310C7 -FDBFB496D6B7BA5B07A1D36D516EC19C37E1DD06B9F6F85BF740D26FD0DFC09ABC3D4A11 -CEEC922B651C147BDC3124DECBABCC8986F5D48556CCC5AF38F7EAAED9D719B983DE7742 -67F8CEB3302B8CCA7DB832794C3C4F0156E72BED47BFA0F7E4B25E13C0222584601BA304 -FE38C5E96D3B5E709B6F5FBC623FC9BC36A4C4E8D82452D260F13186EBA95EE4DB5D4ACC -945D0A3C5C1800C1D3198D509F7B8ED0A0E33612E25B9344F1D53CD949CF9F65463B7C58 -4E12D78D3E6CF003F9A4185A37ABC6D5BD7F331CCC01540452A36524DBB34EC2FA260C07 -824D76439B0059A8127F940EFC1FF165005123C6B43C9700034D5AB9C7FA1AB62E9FD91D -ABDE5F3D5C03A771B0554ABE655545E133AB8C230517D51830492F29E86963AA55E9B79D -79013BB52D623E660A4D356C293233B79E7263ECE8F8B6EB3E56C82C2051111F49D45D12 -5148AB7554D601BEAA3037CDC84ABA8825658A09C008D19163FE5FD06D56D1A687EBB6CB -1C9812EE0E765F14077116182F67D3006048F8BE549CC71A354048520E66860A0D9350A8 -864ACEF55EF91E17EFEAB4D6266C9BAA1D6D3D309073C9DE287BC0619D7E37EAAC4B7CDA -D320D993B7B8F387FB039AA7E1F84AEF034E7845A1B1B5306AD8FDA2834B59F18E6F1A09 -66221CD9531258458E428EA237FCC45BCBB9C5DDE72061FEF2FDE731706A4C92E5B0B255 -49F60FD845C45D940B4C5A4F38740A40DA356A56B8D155477C04A26B747941180F6EEC05 -A5BA892A0D8E4638A812BC405E2775EC3A2D0E3C288D0DEBFF53582FCEAC6936C152B8F7 -6F9D556F2474BF5ACE2B63550FB94C36E29A8501CAA4C22FDCF908C62012639ACAA7619F -01BF96A552A662DB5664E1DB1A4FDC4E5E9050088D730C8E1F387CBF93619952DD8E23B1 -4A385AC6C222AEB44127DA14539A079EB16991F0CA2D851467828C23A4D524CD5AD92FF8 -0439F6F47D703E9BBAE227628420C2DE818A9D2A6BF085B5262E026C7A04ABE831065F31 -68772805AAA986AD811CB78F3FF8A0FA7A211127BDDA087C1459520F9420CB06AA4518BA -A8935A97BB88A62EC76AB2990D8D414392E31C68A91E9DA122ADC8AF3BF4CE550CB1D22E -B2DC916E735D19215C489BD7B62B842970214B0D809639706303AE7CA8E270ECE748D283 -A8370B4F6A37092EC768426FDAEADFADF8598591AFE55984ECAAD3177973A78EAD02CBC3 -F7DB13A7864EC1E7A68ECC54EDE88E7A62A4AEFA9DB238BAF1A22079F23930CBF7CBE82C -2B98E37F28A47054BD47B48637179F4C57164B26F4EE0B484FC8692AADB29EA0C770C789 -8FDC78DD58B009B4901A678305A0DA4E89B2152A596E13FAAA822DDEFCAA30BD2FFBB1A3 -5DC54BEB87BF96E4C3D25334D86761D7D78C50D71DD13BEC2830A96761CBDDBFADED0A3B -6A0EFC34F96CF540E238410D22EE85AFD0AF104A624D3F9EE5F04D9D8805D7BB502E0223 -AFD0CE95C2B32B30030AC7385BC898C282A5EA204957853640D4BF963C97540744F4D888 -72006B2239C9EB3390FE16B4C3415F6EC97827597FF791B3D1B3BEE6D0329604ADD0C131 -6B24B8544ABAD72B337F00B8FE300BB4EC7372EFE3AC8156328238B94E66E1EC7CAEF9B4 -D58DED07D9CC777719E2C973EDF779310890AF183F94254B2CA3277120A03222FAD58E4A -ED28AAB3DA49B5ACF246666A597BF2656CE2960FC95BC24CEAC5431F73074538B8715071 -FF284765EB54207CA22596B3BECAE73DFC68A4F9A287B8DE7DFC27D0F860771239436FB2 -587B07C1FCA6C74A020A819701431808AAB5B6291992D83DC28F2D943AD0DE2D94BEFBE8 -A15AFEB7057DD4A97B4C172CCCDB490E6F9FC265636A35A2DC556648B5F9F80D180FA320 -AC69A0A61A3954BCAD612FABC12D486A0F2FF0457073F61F2A74345B1ECA9DEDCF26EAD8 -D02D3F4678C7AA82907721A828984C6196464440B2255DB9171706819E0BCB7169EB6722 -912EBFDC6CD488FA34A5556F28D2B448A7187B1E15255202DC9DE4F609682B0B6D2F61E0 -4EFEF15CAE39FD3F6F7B32F226C759A17E6C611BBA79D93186C853BD59D73B19E514D770 -89CE29127F5B36F1C0D661597A6FBF85C15307F624630DB6564BC755145BD19088CBA598 -86B29328DA2452957E306EE08CD942AD6FE6697231EB43DBD8D37B4ADD0B4D8947A057B2 -1D9A133A7DEEB89C1D35B3F49F803700CAE8774A4F9BFD45CE309A4342E3B7DC36B6F76A -7B51A81B70E038E3E4999D6EE027DECBCA548FB5F4DE4C49981D4617133BB3E0919C4778 -B80894FF4437120F1035520C75F882591EFD511B6F47C166C7663EA2DEEE335DB1A3106A -5FE0C49565C2AAA0BE977DB611B07D38DC41E6DB8F959798286DC0CE835CE64459558D4A -20DF59F2E8A63E2DB701619617CE4DD55E82EB396D5D701B691533D0B20C3A0C20F5054F -72EDE3BDC2393ECED94EC52C25A755B58F4E2596702FCA68B64DC554DAC85CFD99478701 -BBF2A47966CF72E683B5934F0EA5DD86F35B1556026AF02BCADE75ED3C579CC1D9430956 -9A53EB8ACBBA2551B9BF06594F66229489319F5A5A94E51281FEF7BE86AF12D8A8A1CF43 -04ACD3B27D6B9A574F09E2C41D245D8873A78D1CDDF4CC88D96D9F714FEDE70ACA30B83A -797AD3DDA7D6E52A5AF906CAC560813DB2226BA5BBEA60932640ACEAA2E7B2D412068A2E -49FE781E2544FDF8C762D947871EAA0DCFC183676B5644AE02DB3CAFABFF140BBF755966 -C9BD319925746E320AFD5B157C55E3EDB4D0DC3FA112964D68BE2A5FF08E8B31BC9E510A -F6CAAFE84C0A103117913E2C9ED8FEFF96B941AC14AE07B1CEE2308E36F617DC33CCF32D -3A52F4F6561A784FF2C1144625133FA8E30F7A86E82F675F1EB56579077EF6AE086BC2C0 -B389CDB5C5999A1FF3E51BF766227A03DEFF391312065305E5C3BFA97FE7D5E2ABD0AA7F -609D8A0E524F99B416172F7A0D174196FB411F79A7CA6F8694DF4F5DC48BB58F39460131 -D47167AF47DD3A6AF1E12C75D947F4C130BAA07174DC577B49726123F34FE9C76411FE62 -8E354B43A5F54BE0F210C7523BF018DB36CAD6DB8063F14FC3FD1B4B69706D45E615C3E2 -9F4E1FF8943FA55F1B9B4411BD0DFFA260664CACF3C2C3D9CEEDC1274B71805FEA88C3EC -E5BBA17D17E6250494278450141FD4A514CE968C33093FE07E64F168388D141E52E46DFB -1E2A9F4BB5132C1E6FE25245FBBB3B1CB7CF24FE6A134382F9863D4683AD93338D3A6726 -BAC2C4174FCF4A523453EA28F2095CC1159AE0E0927380C93DE4B979E26D56881A2647FE -0C46D0B6B50B0CA3750D6974A8DE149E252ED68FE33B26E2F04F06FE6C3FEE1E7FD72C05 -135DA55508F10522A7A2D8AB07220E73283F978B50D75FF36E789094CBA1A8E342428B89 -3B9A664939AC711933A2A1C425291A9E95C396879EF54BB6F3DA82E88CA8C34E9CDC22F1 -BAF6588CD3C54DAF5A7873501EDA6A25B793F219D3D229F6A028D34A19A9ABEFF2AAE4B8 -E62A05421D9CC0F78E2709BEB6133A0708BC174F5D745A6CC53E6DEAD27A1E6CD77832E8 -87935BB8736AFA3736E4B4313D6D1B7EB464A02B0C6DC3BC7C84630C2E9DD020AF3F6694 -90BB8CF0185DF9239E0D27B20FBBA001DA7C30F0DAFC8AFBF45C02019E4AB0AAE458B083 -1051F65D0E398A75F52FC3D617A25CDC2EA1FACD7113E0EBA0262595AB5EF65C1D54CB71 -BD87CC35C9BB992E0A63ECB8A1448619148ADADB906DB75076E0DA42BC6501F6B6717C62 -71E3881CC2D6747D0A0BC7B6B982CDA89E2B9D9870C96A86D3A4E1FA0B04140131F302D4 -A36AB220399A6E551FB6051283E405556A1591E402FA9F04B87F1E3C2AD60DE3128EBAED -2CCDAC808AA1CC5E64052FBCDC1EC710A3551B3AD6E21D20FB112543EE0DE94DED4DD8C8 -6526F470C83B1DB3536D6DD8C8E021B7A9A82C23A31A6F09E15BFBBEE0A8971B3F471437 -F0873BC669016F219A728510C712415C515D3AE02BAD8467A1E0D911448C0CB280C70F26 -14BC2E52782C1CE5E79C783BF880D1B914E44FAD64E140666274D68560DECA2194D70377 -4EC76B35669FAC269409712901F0D3555B60175AC7799E31CAB70D06EA8D9C359C9DB9B6 -A3E02F6923C498617C041C28CD7E57486569429C3E4C89944E0EB150813854E3C2EEC4D7 -37E2DBB99287ECE4279F3E0D9D8EEFED11867F0E05E40DB8858CFC5DDBE873A174D756EF -5D5E0D5F251F0FC0BFA7F69EF8D20E34B1B3B5D45501DBDB453D82F56BC6271C281A8A1E -7D0D8C9B920256EF07F4AAC8FE2189485089F52D024BE36045E0BE613F0FFFE13D223B0B -2478A20B98E76A783A98E7AFC642AC9CB333D6D39AD4E08B2BDA75686951965AFEB5D211 -57CF3DC3B911A4E45144B3D9D4AA4CF13DA039CC95A9CC8DF44CF17F3D09A1823D65CD4B -29E2408B1C3FC6C1F3980378E1098255136F0D4BF90D0C4C042F1C86D40BB762E72C7EE1 -BC530755416A0DAC2B3DA0E7BEEBE7AEA9A39825EDEBD6CA316FEBB14C701BB7EA4F7800 -3DF2462E2E429FFC3EE8904D963A0017A606EA0E526EFF1E60BF825B2ED9CB42678B6F6C -E55A893A047A4E5E38F15349B777566334153DE574290C6043694C364A3CFFFD07180F5A -44CD991A0535D13C91FA1134BC457A455022614F3AFAB921A70603C47C96B5E466942AE5 -83621BA1544F2AABC4CF7C6E8B77F52FE39F5798E2FB9F180E3C86ABAC210C57A0226E38 -75885E3572BD47BE016C361E84754FCE64AC3345393F511C99BBCD70443D497D575BD81A -47373184CD09ECD9F4A55F1CB26E921A2B8BDDDBC8052EC0B8CC812CCC2353586B0451B4 -791EB68293CB3B4C41B46723D2F138D5BAA8AA4580A5660F0DD13F25BD665D4994908BBB -74182C783EDA6C5187C32B7D5DDACE8DB1571E7061A063AA56DEE4B0B6F5544437417E0F -5F07EEDA1263224E5E44B83CB057BF54725859FED215E5B528BEFCA470C8527F40A09AE0 -20CD42E31306D1E9095137CB6E7FA08191BBCD7176B87A372A97671B9CC090936EF7E4E7 -85F1C6B541387A701828AD82A958C34DBE426FB12A03AA3BA2C97535DA8526164DCC150B -67442F7D6765D16EBE7FAF904F42A8185DD30DE284916705D3D8826DF1D37E668F9669BB -343D3200509218C5F929E0DFAA7FE3B79646F62835C808BAC29CEF8CA6D8363F0AC7291F -E45A85DF8F0B9FC14C7182170AB1F51D9D9C33D8D98713CBF0931063EA95EBB031904EC5 -7FA914B7D7B254C3B178E174F807269B2BE5F340A3674FC03D7550017B70C0E53472442B -3FDD4D1D45437DBC5AD56D690D9098D9DCDB17AAE217F73B54BA5D965EE197EEC8823FE4 -783FB5A4693273C7142728AD3F78946C0A8B7D3714DEAFED570BA2A9DF9240B61ADA22AE -3F9B21FD1D73D4A474EA14EBFE6AC82B068D08EA2988E7C610EA5097B62DBECEDA5278F7 -27824E5BA9EA442B328C3B02E03C88511DA9C72A271027176EAC2C7B6392E9E99D8B42E1 -2CDD9991E43099C503DA5FB60E5D4F8FD3CB67FFAF46A1DD243D9DF13116880E727A9271 -BB778126C01AF95B75137A0E3831BFF257CA37DE0B3B4DF3C983D091F09519365B2B812A -0B6273D30B01515013C73AC3B8D9C4520B5267E734651E013B8002D09F3B5BA7984A588C -F6115DC9EB84C1C9AA0CBC9777D8923B3230E0A2963E08743E51CDEEDE33F7DDB10AFF69 -BAC8682A2B0885B8059661599B805B9684010A3B6DA56E23E265BC209158D3ABC69BD6C7 -6B13BA17F225D990CF0A42C1A37A5EC523FD80E60DD542322B42202D77F646FE34DB9AD7 -9908DF03C1C5C351E542294D245E1098989BCBEEED311FC5E7C8ADD52E52BF6F0F1331DD -7F874B30B0A16484EE328FEBB0CA559613500BFE6994EA8357ECAEDB310CEA3235A421E1 -85471BFDAA649E3CC9128A0409C454B3C951FFEFFE648F1ADAA14D5317929411AB7D78F2 -B888B63481346F415314E1967919783F8D143EC05B7BC2D5D9F7315F41F0331911FD0018 -44E301CEAC9579DC227E0DF9FE2D217AC8D7B014CCB01DE9AE852AD42FAEF07CD5CAACAC -324F3C00E330939FF4B5B677DA731FF712A6F8A10687D29A296B0E685A4F52F3009A4608 -8A935788703C71B584A8E855683278077851E1416171568CA50BCB4EBC8DE6C952FEC45D -37FC6EA2EE7E151A96452C332221961EAED2B6262431C4C7BFFDD59EAEB9E3DBB17C3EB7 -3D90F0F872289F8AC482B4913C0A05E698C91682C37503A38C841C25A8BA855E7C1CD3EF -5F1E025E58B2EB4599D76DEF57A60CF24E814B3166042F8084B08711D1C68DA4110BFA7D -E8D3FBBEB3DE32CD01E237A403F8581AC2A015106AD81FA0DF90301D6BD887631A83623B -4EEEBFEEDA012BD6C504B450A5F43137757C2EC7DB3662748B105F8B22EC030895E0F607 -5BBBF246422A7D0D6E8953CA66170A8947034CD6EE37EB7BBD0D9F02A538AA0F3D2D2076 -8C307F9558765FA715444282C823FFA3E95640778053A383886551D4F86D490FC156636E -A5A3BD258674262202F4F76746ADD02FE0DCCD540EBD60EAB42D01FE252DBEC93598D6E2 -0312F2F4704AB003FF956FDA5C2A88F716A4EEC93503FA913CA019456AD0A8F6368CF6E5 -AD1B7CE1BB20BF0CB453379DEB3423B0649A6380ED7D0B40768730D37A9A98B2339852AA -286809BC86757FAF3DD54C18C3CDE9E72FA874BE9D82655E0551DAF13FD665BD14DC7891 -12FCA109A1C73D4B0A7F230E2F9512D0DDC8029983A1984406A5F100567B88BA186329B5 -7A68539D43F67BE6263EFA278181688FA595ED3BC7C7483C4DCDDFFC01E641C231EBD842 -D21B48105397FC32D6A8D555015760029C2CAB13AC8D603CABF46867CABA01A99B95C92C -3C224E8F59B3B327A01AE685ACFE6D67F28FA6663F6E47466DD0A6665592546D08AB7C5C -EFD20D6D5115C775E033E0DAC75F2C6411D999DFB21172A8D0D3E427F768CF7535320DBB -6053BF3A17536AF6B2C00979FED18A593F71146F9DEA8B31639AE0586B24763DF3469507 -3D1172972B5E1CB82BC46A60ACB82FC66B05D9228C67F3FB25E2D91FD11B696C9FE505CB -9BD2B2D85D3A22595C338574978048050FD13A59C41B3B0CC2868DE4E017B53935793DAA -3F6DABDA50B06F8141511C3D5093069CD1ECADB90C42431B5188D912A5DF033B633AB3EE -67E4943935EA094071001B6F8FDFA00C0E8415358DDA77F2DDF4F7E2694CA6933C804849 -54A1DB8B5B6FE3A7A970DAFDDD1107FBC4C596C379881A6B148D21733CB2700FD9F4FDAA -6DC49C40A6675C0284FB931AB93CFDE9A94FFC23BF259230AE1724F22485864833541367 -D274CE18EC890E4376F48144950FBE566FD285330486F5F23BAD7AF0A636821A122A4970 -35D77B580B5862D776826AA3735AEAE9D5D7D04C4582778F9B0F713A906618632FB653EF -4FEA9BD993D11E0E51FF3A3DD50EFB462C4251A42D63863256FC819037BE597382C6BE60 -955D060340A268DCDA514793C845FF10EF0C72D6FF27BD1858B49D50516D48D6FD33AF71 -11CD37F5F7F0C4A4508BE16B80565557D025B529ABDAA2850E4EB6D8AA30ECF49B5D18CA -AB0BE944E0B95AA0BBE9F4CA91A56FBD41983A6703FA0FE415171CE8C11AF45004FAC49A -4346C206EBF58FFA74F22D21A1E069AC9DEBE6D36156C32E74A4ECD8BE2C0A6983D404C1 -07DE0A75C732AEA64C88389E15D474F8C0E7789B8707E2F46297012F4F51D07A10794D03 -195654BE0F7DF9A4F5F102C5A68CD37D129051620F807301FC8BD8252B4CEEE5EF78E803 -9D41B48CD3262419E9A4F93B678B9F471F4B221E7D165C1D2980CACA79F4E549D2ED61B5 -02E583516547A49E2804F1149855D77A0D86F3B1B429C56523FA773FA9452CD5B6340E64 -B04FDAE2E5B6B234D03E87E2FD39AFA134265000F7A9506F55505874D0B584C504DCD29E -CCCB8D71485AEC7BC34AB30453AE4E3B2720CBEB6A9C9FDD7FE7DD565902C6BF2118DA3E -95595C12A7744212827DF07AC5AA7B1E05D42FF38758A3C3105C5F0422030BB0102A9BEE -0E07E20AA089C118908BD7207E686EDC8FEC0580F7FDD106F202676424FE815EAB287182 -61FDE8A17F2662BDC02C0E109A020C57C8F37C4B606FA2AFB8C0993E2CD1A91AE5BBF801 -390AB8EB8841FEB2B066F565E497DECCC37DFDC2581DA9AE15E8C215DC41FC92AEB57757 -E92E18FBFE36E0E6AF6887671A9578C318C7FF50178B32CC9A046370946ABBE792708330 -D1C370012CFA2BF4A5DF75CF019ABD1882566333B0E637B9935426FB127699885121D83A -4DB8A43A648A459C83D623EFDF5A60F11ADD585EFF0579C91F8B5ACBE889D4993BA6FCBD -64318022C3310DB5CE4324954D78F06ACAA1FA4C8C4120DD41DC4EE2CCA72CA36FCC368C -A31323A17E4CFB07A0A02CA23F8518CE8ACE1548FD4B67F0A5C414C309DEE52E5327E09F -4B2A07EDAD8A309C54DBCFE3A59B9BFD3174BED78566F6642916B5B01CF4DDABF72BAB82 -60EB5945BFD987B96B80DF607C64747F5344A27DCBF4EB9797BA5D17B7635D0D936833F5 -0AD01CF4B9FFC273C05AD87745D79BA436590D9B50988311A06EAF7CE77B5492A542ED4D -129DEF268D2BB87D07DA19ABA6D4F78874A0A6960C9934670B9EDC47102EF929581A8698 -A9CD8F43E4F071577730D9D18AC416AB398124D9EBB91AB66A4CADBEDE5043EDF627CC88 -C68DED934ECCABBB9A7FC34DFB1B65ADD724BA67DAAEEBD04679816733D344635D997125 -7B2BA27D1F44A7D7E48F9C9A4A412030AF12FB89B15B07C3B18F9C6EB6AFED69D6A9951C -3C1563481B46E4AE5841D88BF8C64461CEE73A332AA07C89414B4380D0CFAD8D61C72E68 -6B34B0EA660EE0C8370A99398D9B0166F8A77FF24BE1AD496B0C0E8ED04734527A5A8C79 -64F2568C9B00E98F7165D0594080DFFF7CE5FF8C26097FAFEEE33307E282858726E675C2 -4B4C31AD2B5B1B855B73D553E77D3320E4D88BEFAB426B94EA33FC9AD8FA81B6636CD4BF -FC2D11BD1F52BC5BAA38C072AB771A9A107554A327EA10452F9C7624BC2DCD6DE2D43EB7 -0298DE357909FF66BE487285902388A024E120D587890FECE3A00376884947E1E6334BBD -79B4774980E8A110E7BB841F9289805FEED0DA0F4D4B8048F190DE68517EF34963FA1BC8 -F8C575012E01C280B647902BBC2B80365E9A66E28EC8698EAC50CFDF1C6D113827AFEB9A -45434209C921460BFF483BE373CAD65640FB3A8B7E5AC12CEAEDD5EE1B244FC42CCE85FE -4D34FB21BEF3EA9B959B6DB1624F05ACA4602052A78FF842BB1148ED529A460DCEFDAE01 -6A10B5B3C9D11ABD14C53020138A9624F0DFC3B1E445290EDCD7F2DBF4BE408EA8EC21D4 -4D9DB728B76DA63AF62EB7F89DC43144028D1098287566586F195B124B89799E3881AE23 -F89DD6610230B09D6B8BDE79BA206B87BCBC18DBE1BC155862D28CD742C38DF8CC906233 -09F933D073491984DA9D927635800B84A1C2350CD18D962DC9A2A235E2443F5EA72DA9F6 -45BE3240B03AB4D9D95C3B57CA05FE3A7011E12B182AAD81B426BB17D44D5C1EB10959DA -01563CA2260F6010ED7D37609ACF759EDF8C044860FBE3C89213394F03A309C04EE231EB -FD84191ECF14A020C7A4D7BF855213D927DBD921E2324BBABA6B7A06D69B4271C66F4FC7 -F15DD52ECEEB76C4C97A85CD59A38E1CDEE2F78354B0B71155227553FBBAE0EBF0D625EA -34B78125DABA3211CA9CF1D4AFA909080061588AF14CB97BC4DCC1E1A0BC04A40B107318 -1CAB643F064192A6074D3220EE050DE3A56D1558AC0F7DA0E2844EB48999EE9409F0F683 -92569D7E7DE78F070FA44C2E8ECDB09578598508EF3B97FA2B585A163EB540F2E8290244 -D60006EF558A5CCCB1D40CDED1CCEBD665A320CB82797F38DE80CF0DA15BB0E13B8CC180 -9D99437A5B25041EF68916C6E601B0432A2DB84C8DE1EBE4AD5A3EE34249E47CDA593424 -7C9E3F3251C59AEEB48BE773A6D775E6723F3B2AA55B2439CF841E1C729153B22550BD91 -F272DFD3EAA1336E94C8AEE4DEAA00C772BF05FFBE35BDE7AE2A0EAFC33A71DEC72B3179 -E4CE0DBFC083372451A7006B32357B94CD7975ADF21D5977D10444C80257874005F8A02D -317CA3C38DD0F156F191F88A8BCFE274976220F0D25BA30DC195F5AC0CA478FC1173A7CD -2A93B482916358E8B0ACEC25E51F975E210C895E1200FF2D29419EC300BB8284EACA5027 -69676CFA8099A110D1AA50B5A4523CBAF5FEEE90B605C5CADDFE233D235E008667D7C0C8 -B2BBEE796F1F78F4819A201131D4399FF2CC2D59B05F923780E775A9ECC284A68A2D76E3 -65E687530B96FC564DD173613D190EE8F1E6BAFC238FD9642D356E764860855820937E40 -44A41861BC40DCC84BD6F9969DEC343DC6F3F7C8FE9342793553B5C335CEF67084B9F1B7 -FDC790015B7F9D682EF547C986CBBC0606E0DE60E95AF386CF4A475902C58FC382C5A35A -2CAC908457D5B69C88E95BCCF40A9B12012DB3F548C3ED3A549BE0E5B0BD17B38022F2EF -2987ECC4A6EA46BBFAE4D6B330C3FA7DB68F0695F7A52C2E9BA1B97A6A2FB6ABA4B8EC07 -5E01D2C021D66FD6E47A4014E5AB39DAD64DA85D3171D7398BFF397E371C483283854453 -4E7815254A0612E9B79143E83555FFAB3438D5F56CC1B72BAD832D3F03F49675BFF38F9B -8F1A89D2E739F07B2FD36BFEE46B0F8E22EB6F23710D0BA81F3B421E9691306ED6D87F65 -4FA8C6ACAA3356D8AEF5BABD5F6E6231E64A772C550212A6EB17D9EFB987D124E63EB266 -72F2C1C00DF095C829BA7AE2EC7C7C26FEEEF5C7AF6DCB1C846F6B6DBF3F7AA0585F6396 -0A27CB026B55B06954B296E45841706AB1D655A5EE4B774A336B137EEBB2AF2F958123A3 -A9649E57BD61EAD0FD1B05C16C1AAD5AC103C0CB1BE0DA4BF4DF83A7F47814A64A11B90F -B0E449D75637E8C8366346E6839AE374FA3A2CCF4437F3F4C21B3649E8F25499556971F7 -210B267ABAF315E8B1D2120AD9D3110258BA296B3BA195931492AB8A28F1CCCB4AA607D4 -7DEE5BF92546FCACFF9D9243B8941D011F272431B2782CACBC99D9BEBC4CA43C90864DC8 -4C800605BDC071902BA524866FA1D98C709BF9200EA73C2FD8F41BEA226F37947CFE0B83 -1BD00F2237535653F63AAE9A6484A558FC74B7475EB0D895E62344F509D216A97B96B466 -24B8C4CDDE55B5E76D06AEBF9877562210AB2113912A2354E60C6986EB1077526250325B -B926BEACF55EB2D98858849EE63A44003D3FBDC186315D8AEF57F8F829EB61C4BAB6C9A6 -E3626F0F3D7E6BA066E31D3F322D060AB9990A619D26BF75C261C69F2B88A9C28C70007E -9B2C08AA5E8F73D00BC882F3680CC9A78E6D70DC8884A65D53E86B6A4030027F7D403CD5 -6106F3DAACACCBB4481C81FED3B7A711B04F016E18330367108EE6BD1A3121A9BD33EB35 -E824BFEE0D128D00208F3E1C860CC99AC8174444D75DF99CDEB40EB09C20355DCA68E13B -630DAFABCBB6BB51FA406C924F40FA40E3FD6DA0C673DF1A2F695E8EC2127D51B6F034EA -E96345AF0294778C6BDE553B2A9578927C484B51B4566B120F8A074C52318F06033716D2 -563658FCE1FC71C655D3319E3DAE16886B92DF451714283F5C1BC3FF960295B947D0D3ED -1A101F34565F24519FF5E7764E3C5F2304FC8F6F313CF6864E09FF079C93167E654A7FD2 -4F6550BB972F93C43FB9399A0E82D58A43B926F454F38447110891E0011904A776271E60 -FC7AD11E984AF84FB551AE9E7CB68466AF9AD82FAB71590A265A08A58C16046254ACB03E -98EFA92EF2EEC42B4733B1BD9FC767DFE45D4E74FE31B3EA3588746D5A6ED60F874E7C00 -88E2E423BF78909FCE19952A9BF46BAB57640CE2478015C7137D87D722254B3A70D848BB -177F0926A2E8DB72506A41C381B6C9D9F4B22700C5AF711F5EE5C7C1CA502483DEF489EA -0EE03CDD50292460C7352EA9B5B4A50FCA148F7FB3191432787A1D4EE5AA9080D95B810F -B13F5267F1486BF1A49740C61E0C6C885E3C5B9B28534CFE99F9C656CBC3500DFEA2C3C0 -68DF8B93243857CCB6D50EA01222C1CD2AC256063A27F29969BCCEB98B677F10FF3041A5 -D78B64EB9034C4D2B3EAB0BCBCC6C3A4E3F9F8EE0BC45A934C97F79E3ED5B9889285F535 -7B5AECE08D84E86C95B68CD40E4D747A33024028EB6D6CC22D05306803C5120BA4988696 -F91F4576E3BF631FE32273E3618F378FE44B56431230AD82B5F7FAD86941DFB3716D4598 -C9B3C3B92E0839F583D28577946992529A301525F1D784C6E8D21999972522D79AC7072E -DCE82D02F952750C4EF7BB486F202D22C5117C4AF3C61C182C177BD247A4F58A55764371 -235A5BC43A4BF5F2977EFB2B293246BB9A55B4E52C4CC35F4C5362395B69B56CB8E21F4F -230A12741F10EE5869AFF80FB230EDAE5BACC982A7B715287BE10A2C77CAB7DCB986463E -00C3CF475A746BAAF746FC1657BFA756A3EF1C5721A9E5129AF438C17CF2717AA26F3B55 -6E16EC7012EA595BE25CAC595AD380BDE9357F70CE740D44CED744EB001FA180E54CEA76 -A0F33436BEF0173CFBE3F450823F53702405E39AA9AE532ACB2D87F94B89385941573FE1 -B00E96F44433409EBC3B007A2BA87A026E9A99AB844F0826F837CEAF0ED515B75FE083EA -47AD5BCB8DCE6ADEB4DEBD9DDC83554336FB9B23FDBE3E9812E8D388DA8036B2EA0F0544 -5EE65BD22CEA0325423876C76D30F77443A1AD4B8640369327DCB70945C94E625CA480E5 -D18DB76FF293F7FB61730A67DEC184BFCB2CEC8A47476E40533B00EACA213C3A9162C02F -229EE91BAD96D2E7FC21930BA22596037E2BAA35AF874BDC4ABDC9DF92F2CA2CD38C5626 -4457D579CCA2C2D9A69E72B46BE5B19789934A526195CE74263C4E4EE29AA0F0897E1375 -F9914C3E39CC8E254031F58F1618565CAA96AFC2F8636856214A86A5BDC3B48F05FB5391 -797D5A8DFF2793D1C1346E54C7EE0E6170C82C5F826C58E46902D7AE72F4725410FC008A -D1DBFF2B0F6D269D5390F43663AF29E2138582F6B223C0C577428E2E320AD6E2D8EC8F9B -28F4358A71590309F5D75F86078B95A66DCDE939BB502BD0298E6690CC33832DAD2F7133 -EC7CBCF9EAE3134D91FDEB4BC8C98AE7C8020BF3B3D88D8F207880958F1DEFFD714A947C -1E2A6DBBBA6E150EBBB7576D612BAEEFBA83E85F20F4B5FD8CA126CE2E063A87005E4FC9 -4DF19C2EF01DBE2B45D5F255152BDB78BAA8506BA36190DD155AC40D4448F0DBB3A0C0AE -FBE24ADC1CC30F4E1412CBC6CD52DF405A4252F8557E8154730E483B8541E663E0BAE8C7 -816D95CA8B6D800446E4665EE726DBF0ED62395CBDE723ACFCF0EBA7D39697EF738A6F21 -CF591045F1CA5C3E68C2CD77143D7F694A7B9FE3348F70719B0F7D805E1BB83A1AC9F346 -1DA81E3167465C8ADDF6EB04F86193152EE00970D2066F79B191EE15E33606D83505C36F -9E8B05926BC156D236E865636E459EB06DC8A9AE6BF433511AAF8B2F37F0655488CD800D -BFC43897B1028A659F689618B15FBB801F303FE42402DA3F49CFDC8D03E5C28249400DC9 -44596A2BBF7F3BAD818203685C7C1B13C05CBB7E86EFB28B6C4D1C9D46DD08CA022E54C5 -4C6D84E0B15412F3BB3B7CFEA7A9A06BBCE4C69157ABBDD52FC5FACF0A23A53953C35191 -8379F3FF2F3BF089CF82158BD6E7013F5DC178EE34C55CB37A84C98C2F24A64B34978D95 -F82760C5382AEEC5761418A7D75704EF2EFA8EAD21B8EE44B87A8FFC59EAFE6B2CAA3D90 -CD2CD737421FEF85551E5E499847EF4B9D7D33F72A9B9E739CB294A16041EF1FAE98F726 -AA1460D1C782A2D3A717F925B4AE0E1A32FBA63A20692348F7BCA69DDF3FC0BF734930BE -518FC35FE0DE9F36E6C6AF15D770FB35B68AFC513969D9A0934131FB9A0A60B351E38659 -E3D6ED518CD1D9BFB40A16AC9E77CDEF94E5C3CF0FAE13076F4BCE2841C7EF7E0B364A1D -5B932335CE17861FEEE20D02237AA90A704EB6B74477BCA3B8BEBF8CE59E19E861832F0B -950FE683E1E5C05547F00BBD3478125768EBEADB91C6F3D2529FF871939CC7C10D0F07AF -58FCC9F8F9538870C3559DDF56BD94B5C1F239E44324C68F756B33989B482C45A7B78D76 -6E95E12F4E8853A430877E892A392C0228C567BBD42BE2E2FFA7F27578842D7B5D05B799 -C080B6E55B53D196FB2C4CFD7BF64115742FFC49465B2B62D80E877AA7E7D9D8811327C6 -6DB937B48FF75E410B5F639F02774678625F24CE25814E5718941D731B2F8F52A61CCEEF -66D7A63A4D74DA48992E4794B453734C9C3CB488DFBA825C094CD8B9729AD572DE4B4B7E -557644A0821BFDF2AEB7BF98C740C6F7BB79E0D80891BD9926DA4DAD346C785B381DF173 -23760CC55A8D050F73E8B8B751438037EFD9505DCFE058874FDE5AA5DEDF7B0B1978F714 -3F0981B964DB2F7A55B97C7ADF41DC95CA295C8DF2858BEFB21B94F5957715F982BCA5A8 -D6BD438C12C8E95ACC46E9720C7AF8A61A1D952F80E1D65769283FD18C2ADA03242F333C -527384FC8E5FC02B32B4802A8AFD6A0FBBD5678CAA927B5E970CAE60F72773BB4CE9E49A -0455728B49422E2AFCE32DE8528696E6ED42B350B80C39BE82CB53478FD8EA4B63DAE5AC -3ED27E83AFFCCC52E65675EED25001048297E293DADC529D37B5BFAD0C659292A7D89F81 -88A37651DED8312E33EB4F39EEBA2102712D108E8122F06AAC04528E3EC813EBE0D99EA5 -72E4EA566ABE4FF8FF53362FA3158FA52FC599728D97AA69A5C46FCBF2B0B75D2704F9E7 -CC7CDCCA951FE69E9C2B9B448D44E82D3DE480087E98D1A580354D4D0A8F893DFB7EE4D9 -30990BB3B886A2F0AE65B2F8C5FB109B5B7A69886E73E7883783FB030DA933B5853DDFDF -EC18E867FD17F24DF97CF72D95C7EC0897D20F2FAE74A9280DDAD0497CA6D099FA350C68 -1A46CCBD7B8E7AB3AD45658B8F8B3DAA18D6C5DF704A51DF6F2DB5F7FC218980B65BB446 -99569FF1D4081B16356114E4E72166A09ADF09827750DFB537E9F3CB07A29E2D4A435579 -8F9FCFA874A4772D04B7AF6306A75C68260ABCC1B2F59C447845735F8D9557A97635C2B5 -046B8AEC2815C5094D918D67638C10C7820BBD26EA458B076D5979E4DEE7DBD341097400 -2DED95CC963CA2D607FFA38BF2F6175E77ED9A8ECE8B81EDCD7FD6470E63E48A68C0BF40 -952AD9C1426B3FA70F59D03F317C1484FEEED313A9B21DD3410F3DAF2D664C8176FF63EE -2FF4D366A2E12AE43B34039BA38EF175253B582F457EE300E0F4AE056909C751F8E9F889 -EC08A1668980672230F7564C28C98BE3021A863086442F0D1B0169F98CA5460CFA959A93 -61E44F39FD8F5F1395C18B9DE0DABFDCB82717E34E836578901B33EC4CC2AF27E94609C6 -D78FDE2D2EE6D169036CAEE5530FC220D59A1BCE8DDDD67C2902E53E21493FF9DF4F06D6 -0787A3E6D31507E4A924BA17142C4421D2B87ADCC7A1D0861607A50C49E8359E0BCEEBDF -BF997E7988B54950D1B8104C504AF8B321D155FA250380D4753C739CC0C2866ACB76E1FB -D3A7CEB9C6DED0AEDCB16CB9C0FF78FC48A3B7B9CB117DDBB3F2EAFCA2A9462C3F125163 -6D130D50AC1C2E4381A5E89C22432DA5646E4D7191EB57F78AE5C8C63190C8A350D7A084 -54619FEADA6DEB239AC9CF577DE28BC967871FEECA21CBC24B7F5BC4656441B627A81771 -7B793E36D510ECD9835595B08C54504A35DCD31FB2354A2E3B9029FF9586BDDED0E8BBA6 -C0DBBEEF15BD4ABA2296F949104B44C7AF0FE063A14CC8498E52DA2497EBF940DE5F6AA3 -3788199C9ABC1A3EDE12C4CD6324EE6C6856BCF9C5B009C150A304BC37ED7581BEF3827B -ED0C87705C2EE399BBC1A2888BB0EB5BE6CE090C4EC75F44B77EC20C37D890E9225CA515 -0A3710734549550537F5E097610804FE488C0E67F063AE0B685D4AB5FF167D9462A87061 -3E240E17905E7A47119CEA30BB69011C3AAE24AF76EB189D7BCB06EE72CBB7C1225D366A -661A2DFF5F3E9E5C6AF1D81553146BE97DF02DCB92B690BE5C0D2C44E1A57FEC0BED0149 -9A6D08BCDC64AAC6568A1D3045616E470F23AEF55E642FDF155842FAFF49EFC7F6261F25 -662E6373E1A107326EE123240146DC3E8A7BE75E51FCB2931C8F42A6E76542B763192B1A -287CF88D28D0C897BECC7924801EC1D7B7B7E519DF69DFA0DADFDA635C9942F0AE4DA3AC -B6F1EFE8003E1192DE4EBB8C0656DC6BE46462C97C02B63B7A660B12B1E169416683BB75 -DD6AFD649F97018C8DBE0D4CA139D964A7FE98E7E86EC3F4E846C3DAE736F4C348D39E35 -C98D98B96E6A0436F5B5DD9ECA1DCCCA921879F11D42512810B55584A2F72607D20F801D -029534B9D3D7C2FA984005D00398FE7E549CE68EAA5B2B21D87EC383973C2D7A3A095293 -A510DF4F80074C4919883DF6091561EDD20B440E6FFDFAC0895B3D4EA594B7396B4B3AF3 -78559044AA7863D818DC89064CB7518D7448C749E66B56F9914E538EEFBAF56FE087CDDA -AA59C8A6146C282DF632571830B849A87E0A1089979BA0B38911386EC7834B8C3D212224 -D76CE946A6DE2B2C246A92CBB976736A586DAFE1B3D62DA86B7ED2C92D1B852FA2DA29E5 -7AE135B93A7110018E0968145A18CA917354614CB1937AD9EDE813A70B30CFB5AEBCA5ED -C158CF63704ACA8275356C4837B9CA53F4BFE2718FCD0F4502F90632E5F65FBB14C56351 -21B5A367A979E1515FB818FD72D9AE26CBDE09F79C244AE16E4AA13609878D0DC151915D -151AC0844AE2CD57426FC916E920ED93AD36F9412EEEDC7CBE6EDF7EE7DF16D52CE0AF4F -2E5470517F51B4D4DC734AE36A66D44BAB9531B8E2AA28A811F08F4283FAF1394E56FFC0 -9BC31790081146224C8A599F9209D59027843EC5C1DF4C9919B0513050868A107F9B48EA -8D68EDDC6947CBD4031CAEC69E35BA5F7F2CE967A9A645B064059A523A06E8BB5F33CBC2 -70D056A003D76AA7BA382CD149BE61990747C75F16D48EB550EB230CE7A87D8150AE1352 -C3A828660FEC741DF9A0F41677F8ACD0376724B7060B0DEA0478692B3E3EFBEC197768B0 -022B89CE385C383C478221B9128B577FEE85289F1AE5680F3F0BAA120916102059E3EB49 -74EE47955A35175C55EE172D41B79D47A1D69B679F08AE94B8CF805744C571B87A9B53DB -2C9F9573FE047343039413D96C6E757C9FEC200EDB3AFF4D330DABF5F2FD5A165C137BEA -4F975CB34D9B372E543A61C95408C284AF4ECB516028144A64CA94CD5B4282257E8820EF -1CE2CEFEF2B2254C7555950DBC6CE5E30176DBD5DB8DBCA2159961DCE778A703908A4E01 -BA33D7645C00261888C7A63D0893DB6EE0BC2165F002CE8B909264173D563EA04940844A -F99D5750540EA9AF7EE79B37173C4150F42CCD60053870250E45921EA215D6A318C232DF -9000542ED5479DCAB19B839D4F2BC2871F552FE440D7EAB59F1E46130D45E1322D1EB470 -AD5948C18BE73A0EC5028E37D6E7A0D2B0305683D244FC5E80207825FD8E587A74900042 -9C60722A87D9C0D96B32159A5E00120A9FB93A5F49014C86ADD51C4A1DE4D5120DC04763 -136663D080AE9A62F7136088200DC77777868075E545F8AFF504E55024DA59E61CC7D28F -0D2CF46A746EA11F9CC96E28A12F1C4E208D77BC61FC5F7C32CD6210AF8D5167D0781F33 -F55EB7C7BB8DCF35FEAEA7B268051C9BDE278D9AFDC8B1F832A96FEA08ADA9EEFD8B4D64 -525E223E0F8BE2D4492FF02DEFCE293DF9BC0B63FADFC0CF36D86408C198354D60810EC9 -A184885B1049D002D5250D46763042EF9466A3CC6D5D77F15DDED407743E5B0E66F07E2F -0D6B34DD74B03ABDD904746F47AC74EC694F2423AAD5AC1BA4D92CC812D14AD5BFBE7EED -E711C2FF2CA96229106E9B1EBCB7B247E9DF0D3497B50AFB597128670D3C37D33E8B3E81 -4CC5939FC944F0DA9F486517F19CF6DBBC50315F25BCDC9E2EC95BC5C32C3873FFBD02E1 -10C4EBDB28C5D812B259385DE0F27DCCEEF80D106CCF483FCCA045664F74BB6F3A93467B -F8CE0D96A004A1E0432B509E1E28CD71BEF3CC18FEB60DEC9C3C8B4C7DCDC14360C02604 -65A67941AF7445642F51288B5BBE76CBB54DCEBFE0FC2BB4F9DCEAD53743B355DBB7095C -4869B00D783D56AB252AD6242BAC1D7F71701B0BDCCA9788B29FEB31245E97BA0BBF6167 -570DE4DB44AB1823F301C2804D20BB08494685CEC27C481041C456C5D1024B7787385BA8 -F7799355810EA9BC21F6B14F7A4FC8F85276FFBEACADA152C746133E53A53F8788030D93 -5206C09FC2A130AAF5A6B28BF9F81A3AB72F910FFBBAAC14993777786D6F6B42FD005566 -B7D5C006BCC0DD10EC2D8EA90ED65F8EB52B488F5D5AD6AB2A46FF7C06B95523D79246CF -34576847ECC644C0A85F3D379DB1F97A246FE3B066D0A6F7B6BA63854EEAC4C82A92C3F4 -53A9A906DF74B5996B96D2A13A1F7EF9682D8F0669D4D241BA1012B13D69CE14263707E2 -22BBB0E36F19ADB165BEEAD76B323B55740716B85043EEF89D393EA418BFA7806FD23FAE -5D26CB811E5113DA77A37560F82AE3D2F4D8C4970AE092D0E56888D525D45563D0CB4DB3 -5317E01296570AB93CE8FBEE77BEB7E9DBDEE9F3208656C8B536F8E44F89203343DEF8D0 -C6CF20273522C4E2ED3AB104E4C98E0C773C991C89E16BAD8D6EF4D70EB69F9B9E7192D9 -36E057EEB0048168D2199D790379433974A70E9F418899D3822B0354596149DEF74FD653 -162778EC18B4AC9093ED9A6A3B3C76EEC9CDBF5A4A4ED23BF60E04E5D53A1CCE0360E178 -A682D70D86C5E5D8B4DB2BBCF7082558185084F8D8A22C96C7296DABE818F67FA9E5ECB6 -F5064065B7CFD19BADB214DAF76DC8EE0348E93849BCF1940962F297DB8181847B9FA9FA -6B443B870C7FFC99CAC69584C8CB64B01098EA4D3496EB66CB4A146766706945BE8AC9E5 -1F82AD6B2891A38D0065D37C2ABF340C05F8BEE47A35F3B01485CBD9B4C79D6DE4CE40C6 -E73806BA1CFEBA9C3A0816054A8A41B757375D6A0E013F96D8D168F0A18E44FCE3975699 -FAEE3089DA2C4C743E8F746C7CE589968319BF03874B6F577D2ADF4711B8BD42EB9A51C7 -256916C4258B3EE07BD2CF4431F1C835C2E1E86887E100703EAA07336E54673C3A3EB4F1 -B687442C6D4AEBF412398D1F1465B8FFDC4FEFD5ABD396EEA8FE981E585F3CA45798A874 -EC4D3D7D2BB31E4CD62898F6D6F27E87B2D2E8BB78BA524A54731D04E0A21C19C05C5F45 -357270669300949C580629390B2734F0F1A32C764E0BBCB8177DE0E5B8FE4E958E9651E8 -703C8AB58326FE0449A73AC645B2DE49E6FC099399003449124AEC31A8714834A8601652 -6198B6AEA7A2F0895EA9F9BBEB13311BB006F4F6452C8F23064057B7329D3B98C5C2ED39 -139FA2436C0B610542069B96D6A0027D4C3B79CC646C8E063C38C3EE4145236F955A60D7 -073D6B8DADBD102BE5EB88FEB9B889A0E7FDDE15B9F69F734EDC33F16BDCB9FB84481969 -6CA99D5D5BB5EA6B2C082EBAA52963C8454A0A1E475013829CBC977864B617A14DDDA328 -E086803BC06FEEBE32D8977F9A8376325B773199B29B1CB15CDFAE065B3A127D8D160E1C -472206B7E4497C9E91B5F487FAFF62724D86478741E6A2FF610256AB92AB688F2AB751DD -90D96090E98A2C94C59F0756709F828EDF55D4C7A56E329F3085A8F7CBC2765929BE87DF -11B087B08DA4D082594FB949640C24586FF1C8B505EDAF05C4BE22EF8574AADDC544C702 -C76D7A9096B206979CCF7AE4249552B38A2FA76F2A9E4EA55ECF7E7B4AC88F77B6FE203A -2D4780CAC541C94107DA1031658D2041ABBDA42FA36A744F55B1B79090B3FC71BA917778 -CCEA41B76A06564B753BA93BF518CDCC98192399E4960A870D13B48A5B18AAFBC7AC0527 -66F9727D135DB7FEB447986F1817A66EA426643E1D2A4127680EB0BE913BFBBF01BCC874 -92F6D772F4823ACB23F378CE68FCDD439A23947BF8AECFD88A8F8FF4E28526920B833CDA -DA3F234880E1CF5DCB0D1E333809B0BACE4D1A3CF36E122F5258E7B277125C9AC20AC18B -9323D1C8332E6CE51FF5C7CFD5201E85498BD05430993DD8E18A04C75200C6B883B0386A -8E81A4A6E3CC28E4D0744D8EAB410D60B93B82B64D387EE84A27DEF4115D554C338EB123 -40E9B6B62FAE4846FBE23DE6EFF018EA67317C8743F171AD6A008CC1190D6ACF47B5712E -607B1D6A6EBF3EC767F51A6D432CBE352E67FB4D976D852144289006679AAE4E5C582043 -3ED4A6F4DDB4F6056AF923B84B8436BDEBE43AA7FF0A84B71F469C7BF396E0EA95D31AE5 -23B41676AAAC68203F1214E08BDFA403EBDCFCBA37023A566A0BCF34D4237B6A86FAE988 -DDF9D5699021CFEFCF8BCC3862836220C39BCC82553FBA41585259B0494FA1FFD2C92C93 -C4380B885A55A0F4E829CE6EFFC72F6FE64B66E64A2E3B0E82043D164D0EFCBD3CE98D2B -8EC210F6570A60C92ED09E5B8BA6618BDA36F14BB1B1E6DCCEBE50E612A09660377A67D9 -3B19D79AC625693FAE271348044AD13EA26B4FE7D1520A814C2F7730537068C5C34984B5 -0B8BD7F836B957067E02A65B6D26456BE4334F180030082A26D89091E30D628BCA32307B -310C0078D3FCD2283D078740BDC955B4DE611BA1D09A04AE30EB30154C0573F459E75557 -A006418C7EA44ABAEF9382C182CC6AE260328551D722FF8D4B06D292E09215F79118A716 -77B0F6B4A7F15BAF61BBABDEFD83C92231DC7E4A491333DCE7B5D1FF92B6D79462D8B95C -E8300AE364B0D92F7C40797EBBC62F9847C796775385E343FDB02A0726FF6D5E118B8913 -F77E2DE8D7A93359530808B89BA7CE125C2DD1174D30F0EF295CFDC6E4B039283D23F235 -24D860B97851E7A59A8863959F75757E6F9F7BB8C5629675225CE1F9543F3EED0D931D2E -18A9206F709E5586CF19A965C5CDDE330517E19596DB1A817C3146433FB0220655949098 -0FF33A01F79C04CF7D46D80AEAE67F867DD572EFC12B469C9BE08D9ECCE54050A6331593 -4FBAFBD5E4F2348251582AA624E6743A0C8FA08FB3739A303D919A9796797642F6CD65D6 -7548C40C32912745452600D2093AD67A34D3219CB539CECB093009B13AA77CAE78AECB0D -A624DA455725B2707A8B27FB75411B96DD0F8F33A31CCA0D0DF08BB08679C6D2F06CF847 -23DDFCC89E54D68DBC2E8AF22D0E20F86317847D41BD78B463593DE423200FCEC1341B6B -A61B327CD89757825968B6D40BDCEB55BC00827EDF7994C12CFED6A4C16F5F3CE38747CC -8942C8CE454794209ADCE9A7D2608224AAAC684EE97DC956453071AAB23DAC8D28D1E2EA -13D28DAFF068BF11859F8E1B8E8C571EA30CCAD1333788647E250577D2E908F41ECA1B5C -1A2199B479F0D38731EFF6F8DDF3B86FD436D41F24306BE4D1771EF24B287EA32C5A60FC -BAD6655A20261020A3690E70DCAC494A6AF3214BAEED8C00CC86E861C4BA6F545F94194D -9FD1736A81A26ADB9BF05BBFED3157D6893014E87FCD8419D750AB2F51711D1D4FCCA860 -FFD22A121805E91AAE796708CF754C5030742FA9AE9CE22FD45089F532C769E906D2D74A -6C7DADF54ABB9F8CE74AA0E8B86F9CE77CA934DE33404BD07BE3CD88FF1D9C27DF034032 -554121F6214B95B17E1F8B2909C31B93E3BCD416DC76A4D150B7DC1A0D16B57A3E7207E5 -34BDF060F416E97B6C97AD7FC846F6A3CFDC92BAA822FCD90087A19C6C04BFB4BEEECF2C -E8B184E9D9A72005D2E2B306AB25E7708A36C3C6CE857244BAEEAED79DCC8420EE0DF1C7 -A3BAE477C4DC1EFD1CCDA761F230AC93BAD22F569758FAEA83B6FC12796C503856E171C2 -1B8DE2926E0000BD7BCB2087184865B43DA908765DB836C1397F86C4EF27C6B667D35B3E -ABE731CD32C0501DA20A26F086373E4CCA74922D3988B857A715B8C70F131A190A33D9D8 -C36E061A60E1B5C63C749AE965EBED843204279D515969A3A5A5C0616FBA3D7DCF19AA8F -B0B8FE4D5134EAD0CC503F0BBFA49E7C2110BDD4BE27DC7B67DD0F417AF8C33FEC671208 -9D5309074D1B15CD52FD2CF319D1A3B149D7A513AD9D7C0C1EF8CD2CD7031F082B27CFE3 -1CB2737CCA9492AEC194A92BB2E5FDF0A94A30836D1FDCB78D9AD2A3E4A289A7E58177B2 -9D92BA721571204A74441EDA8385B79E67E5AE5F52A2A181E8C22E3343A30AA03E2DF4AF -B65F91D82A7823D2A172196B613DB060917CB303C574522DFAD536167A501EC998004BBC -7DCFE97EE8AE4F169D604214B9746475C32B7E557223B20DE15E67DFBE2B4251DE61F732 -9BE3B01CA9D20CC06173FF97EF9C15C4109A1A6A321C4CFF59F448D7021A0A0E2ACBEB78 -C4C7417E652E46DB60BC50D79A8247146CCCD3D288F7DFDD1379154E6E67C3245B8D4F78 -394936ACA8A3BDD330219F916595035D95CF1AC043B3205981126CDB837EC4A69FD88C20 -EB20E8204E3C5388A84F25AC5E96F58BBD258326C4961CC39627359AC1BBD203C878FA14 -6466C407F206184AF3D5666E7A3D6A01A866523FB85A86CBC08C62ABA290248E9E23647E -4A3D39C6C1A4DB8EBFE9BE7D70B228A3D426D6F5F0B73EE30A462983D166782B02AC2B3D -CBF181470A396FC272782D83A2F6978586975FF35C955A2A15DDF14A0A152B91344856DE -24E10D9BCA853424AA1ECA78A8598A300F620C5D5DCAFC26E087A118219F6F17B1A468A8 -B3C2CA6E1113F428BFA8776F863D89B432CCD125F7E37002067D775FADA0365E6314B022 -E782134FCD614431D014018CE7E6A66092EE5113F3E94ABD5CC5EBB42B11DAA52D18C34C -3A8A973F1BB6AFA1C81BC36EED9595E5AC3ACBD580D6D499273CC5A04FF2FF51CBF886D2 -4A80DC14D0C7C69B04E77E3C0D9DF24D295128632562A1BACE9CB3D69332EB08490CBB94 -37A4CBEDA79BC03409C7EFC8B8C38072D37F9C2EEA32C59644EB148EA83C21534D28211B -E074DB78285632BE3DEBDE8524490B9CE18FD89374171B546D349828B5C2E9A497539CCE -B501FCD13C47F4C2C57E7B625963E7159A57A3C18FF6DE06B357E7D125574D6BC2A3B891 -A918E00AF3BBDF845E6E3BB21FFDC4F724085C73B147EC7C72AAFE2C7087133CF8759CE3 -5365425F272C61CF5F96B1490DEDE8E9FE77E6F7FAD03A79DF2E2A90E1A12263EE5E67B4 -4B1A7C1737E4B178FEE720652505F6C5AD062FBEAF7C8134E984B8FEEA448340FEE7E3B8 -54436EE0CF964B7F854AB52C1A7FC0CB455EA3B879034C34361FC56935B400E93022A073 -44F0552946915B6DF0464C8F7DA5EF0C6CC85A877BEAB9FFC4854252FC2D01C275E634B5 -2F4A439AD072ED4917A6132CEA7669CC1D91CFA66EBC689CCA482E9D5DAC4F2D4A138041 -82792ED95C8305E0BCD5B0D70C6E89F7F292FFF59D405B86A00765E0E2A42C18004366A4 -C9AA307E15395495BD16D691EB48649FC2E377B388B6F5A8D519D6CC18B4F2176FA9481A -BF4A0674FD8627F5A544C3954A4F51C234DD631301465BCFF18734190C48531D3C22A368 -3A8887D4C665D442C58CF05192C957A5B8D5246E925963FB22A4476E74122D5C5A45A64A -DDD5280D5BCE3DD52BA0C2C5BB01E25C6107BB785D48C5E37EC652343D5DF64124E0544E -58785F88A7677C2995B938923A3D31BFEBE629A0C0B10E89DC24AD5C5BB67CE96706620D -44122A38FE39966D83C60B29DCEACE2D5B7C62B8DD63A8C4933EC9C2DB8F0E1EA95C4325 -E6A392A6FA28BC9D8A4614B57D6454ACBE1D4855126AF4F741EA672C5DC8785B9510F1E7 -CD009ABC0DA119E418B9D1732893A71295FFB947382B621A35430765814A4D87BC9225F7 -C30315EE1C82AA20C6694A2BBAB918D6218A862B9606E868B7CE46ADD21F18FC192F3E53 -680F2300AF3404BDA02406D991FCBD977F993BE179ECE640101FF69DD7130AE252104759 -BE35F677641AA99B77998EC68F2C33A8BEB421CDD80A32C85187445EB30F882B11DAA52D -15208664CED636B5A8630DAC33A8F1A8ABF26A1E28B1E9C5A8BF20B535534D337780DF72 -2D36FB033EFAC9F460A030DBA78B9DA909984C36A8D3A206501585E2E7CFAEE68CFFA72F -3C55906EF2D704D8815FC8DA8CAD942581B20FE0532732DD02C2E7809FDD9EAE6CDE2B79 -F81DFFEDBF5B25B0F81E884877AD96AC10D4CDE1212BDF99DB3BE6B407AC12D6FF84909E -B43A9E47C76B6D10F728AC30B0AC9902AB6FC8F894FF1B8EC121C32DAB55C6A781D5AD57 -45F94D85EF8BCC8F2672EDA77E61499065D9C1C6CB105E0DA67E2562663B52D97CE325FD -4C0C6A01D33FB1D3DBE738088EB49F61BA3A7E70F567109226E247AFF09D9B0A2103C79B -33467BA06B94DB8BAC62F45935DBCBF027F1C7C36DD12E895077A646392EC61266C98961 -FAE84D5338D421424846807E904E1B276CACA31010E0B3E5F5A05E98B82A5576C060F452 -6CE73581B41C6BFB71867D47293EB5E120E0878CBD4F670B69EE75C203CACDA0B87CD4D8 -6A7FE930BE7BB0D0E004FC34C2A51B5304FE437BAE9F2A2615DD834E6D680A1EED495A87 -5362C820E355D56B2B5D2C70EF2756A992BABD7C94555961A2C39C5AFF95AE8B88DB2B33 -2D0F4551212BD258BD2D6C53A290657A3475E173AF1CC8A893337932D9B35FF9CD005B2E -7854D0997F23CB9D359D7462EC0827DAA520FAAB6B0A396695DFCA5758BFA64DDF4203ED -FE4F89457895CE06250121FD57536E08E898DC20F084890D65772A9E242F5A07A0CA75C9 -C3551E79784A8A3256455B6C88CDB8652ECB2A457D00B90E2C0DBAEEED508EE964DF1329 -B34B20E37D58D92B6AA15B5D5F56702C9EB9755025FC8FC393C430CCFA34180ED1BCF887 -05C6E3EFEE8A9D5C99EC0F48CBCC34F37FE10FDCC68B021E14A1D131FCF8D5C2F8FBF465 -8A60A554D418D590E03A268503D12C542393342599828553AD4589E8B0E6DFB2EC663AA3 -B6A37FB206C1B732C18A052A0F309DCA19DAE82D110FD3337A863206216B00317508BA1C -1859349EEEE49B9D25C897D29C4F28C3757D350B3000612D4C32AB5E072DC92700132514 -30C91CDE6C1035138C683763736103E836DB99ADC686EDE265182E8B02063D76441E6122 -F10EB88DC27F1273BEBC4219A5E6934C51E2A9FD36C7CAA59FC5A5D2049C0781FB48B30B -750640992D5CE69D1602543B81712E8514041B4991A115956C268DE747B0F136F8819023 -8D14DDE8DDEBB7E147057EFAB2D0F0002CCD0C6D997248A1AA973D284D6A04A3E009EEF4 -3F9E859CFB4833C7E485DF4786089D9061F6F4C1EC74BD179D01636788A88597B7F9742E -17C41DBEA3E371FC867274D265589AF7BEACF9748E7E21B73318BB6728F455EF9BB67165 -6C39614711B33B96FF3F74EAFFCE174F0CFD3704637E5CD8AAAA0127AC58C82CA7B20971 -670582631831E7E5EDB9A27C26C67165C891679515E0514E6D6CB7ADD9CAE98B9E578DA4 -7B521CE6E8A0AD1DE58A024F954A424B707C462C83F5B459D000E5195F45FC4DD186DDDE -4E305D1A2743BE9C41B337785B9D57EBEC790987B6E1D03EC686CD01C3E2E14D63E07AC8 -FBDF1D5D1B38A2BC1BFBAE604908BEA0990033F9F4FBBB8CAA310EA2C217EB5FDB8E0B08 -98F64639043595E8D09010D98F959A7BF315716FE1E05109992F33231C10B7296E284A87 -219767CAB7BC5DD096DC7E164E114FCB6CB16F078275B08936A7A036D17B96863A068423 -D4B72E67EA43483968214F6243E538AEFDD7B076B0B6F7CE98A914D2A2332751DA48BCC8 -0A950FD81DACC79DD6E3A2EC69B724FCB10CAAA58272FA64D625557153DC7C1683858F9C -00C98EC395D7A364E65B33A0A8FF31C7FC19CE7DFB5D77E2B5196C924039F2B4D4859C11 -F3E9D42760F5DDB4A3BC9B78C0CFD18F9B75F4756DDFE2D7C3C8C4A60E6ABD17A234CC78 -10A6AC5778570C86C63B27926FA00D01A204CB6E7EDDFA36476E7278B67789B17EAB6F9B -384465DC8EA130CFB75204A20E63D0A77F4F2148BF88AF8D86A7CC39FEFCEAFEB7CAF7B0 -65D7CFC437E55773A2F24A1F7156C4488FEE00627ECE1B4CD8F8536B91B477331073BEAC -A38423E177E3BD2F6E5E31673EEF7C4510D430BE12AEABD40D3E7116C4C91F47CF12E4DD -6500656EA37E109AB7F5982BEEBDE4C4E1AB125EB84B560F82716B4D672D13CB3D424596 -8B201C3B628AE15A0E35EDAE952720D3D7DC3C373E1589C1B94E758BA485AD155FB984F0 -7EE774778F52A84919E48959C071F7ADA4D5D64A81E8D5D792F9E8DE6C491EF9ED29EF53 -3CE191646D7EA108500A935EC3EC9B4092EDC5920FD07A5549EDA2F643175B7CC27F7AC1 -098BD65DEA60D6780634EAD4FA2117E74458703F9722C9BFAC8863D2BBF338EF586B4E34 -2583F1EE4907414A1FF2DD25BBD2F5F3B10EE054A6783DE20C414E7366BBB3068D0E3CCD -A8AC3FE053EE1B89F32EA80EAE51D9FE242D06752BECDEF0F9FCC48DD72BF764378C8628 -98B308C826837EEE3C1F745325F1D989D33650C5A11AB9F5C47C20993159CA359ABB6E14 -ABED7BD14F7AB1B604EA8179D2254BB6D2F9F08904B91C645844368329765045BC4B0EDD -D8A5256C878D64941DCF0EED82A61004E584A8BA9CF9ADF76F5CB0B2F26FA4A4E6499C45 -92ECBFBD4736242A8C64D6E692524B3E663CD47D0341637139F2029358BF07AB385466AC -BFBDA0A68E684D4132E529F4CA6E3017AB2EA78F4281C290E2EB2A948281C7C466AE758C -19FB86A7C335C50BC32E68FC5973E533DC14720A90E5AE57F8E8D87B0567F291C797A00A -B00F1488437F05B149E4CE5B182C5CF82C3B15097C269913088C9A493C976319BFB2C669 -553240D1025AB656ED019592AA7AA98DF352A6F0CD453FB20FDA9BC5E53B003528C1701A -94F06022EB7DC590D290D564DD37357DD75AFCA9704642DDA1E23E47FE3EAC9E6B5D22B8 -AA0912C8176CB668997D9B9946314647ECBAE379CC2E8A836F697E614CD975560278F0AE -74EA9A7C10F94564170B11426EB79670083D2F68E3336898E5D670AA4785929A2ECB553D -356F8AFD7B0F95E8AFE1947C638684800A8720AB299EF7538D6D56FB1B679FA5987BAC22 -A06F3716B089EA008B1DC55E3CD09A39F0A903B8EB764E5AA9C1AC0B5231C440F68D4E01 -C36BAFC2FF18F34087A5B90744D85B8DB03B3F8F3578E1605487328A11ED9C7E7AB8DB6B -580D7329026F14F24304B195893CC1D091D960730D2C45751109DE55DE39047015AA14B5 -C497C41867A5DA02E7091FB40E952E8ADDCB0117562A04E71739AE2F9F2CF315D510DD0A -063AEE64F428F29AF03B9436652EE54D68BB45FF0E3A373E5CDDC9AD707A989AEC860A32 -2AB8C2CBE68F36F2523B1145ADF788BDBE0F577AD7F5B082ADA4E4F798199883011BDDE0 -18783C3E8246D2829325798FD75CED42DE6FA551BAB1A8E0637BE3D487AF286EC8B42278 -14FF0E5BD8B32A0C524FF0A0C22C8735BF7145D82F6721E7774D2EAB4C28BCE0634A10CD -571490C14979ADB3126983F20925E30D7DE2AC03C146432D8B15DEFEF9504467604D9F02 -32F7E56163F09E9BE071FE10FC3CDB00F40004AF8B01239CE23B5F69E37B35D5DAFA76B7 -8576B031E3386C6099407C8042816A4EF9CE790110CF24C114EFDB9C8529A43C41168F10 -A17C2ACD6C4E299A9DE70657E70B16CEDF35EB41392648F09A02E1E4717400DE1A346671 -37A7CD6A6EBC5F48A19FF169A279F815BEAE49B489923AB6243E4C8AF35B4CA1EFBD8EA2 -D21211D869E0D3DA441860B6BC465EA8497507B8323CBC9B41AE6C774EFAA7224385FDA0 -CA5104978442A4279CA25C29401BBA1367CEF35A2BE9D24CADBD7BD9695BE9AF03BD8DA6 -A62111A9B59A24A4ACF6334807CABD977D251213079A7265437C822AE4893BF048B19907 -E997F038CBDD1FD0B412AA2817453698EF05EEF47AB03E9FA77751C57210969591876316 -C83D5052163EDC28DBACB472D2873919B63E9271310702DB9521E8C18020470A4DC60EC7 -A1007BC82BCCFABFA1F575011A9067817930AE0321659ABFCFB4CFD6EA7AA86AEC98D64A -1854B666D075107ADC85FCDC67D89C379741264E6554B7F60E19A5292D356E64538777EC -830B8F0931D34A61F9CFF3C37E187D99D5A2E7E876D1E8996F73FDCD7E614101F97B8BEC -A0744AC91DB473C0103B6820134BA545183483C05E1EF90B59B78305350080D2204D751C -C8AE8DD9462DD62F0FBCE507F6EF39AAD77024E89975AD12BF8F86130D9B76AC7BC4D4BA -BEB06B76BA3D77DAF45E769C732882DF011DD3E00845CC703EEDB8EDCAF7A6EF4FAB06ED -AAE69FA3A9436774577899367B202442BD6CD24377AAAB605114823C26D249CB0E130CF9 -60D8313DC983131AF766483BA063D7ABC0BC24EC06DA0720D4884F9421B9946AC15C30A2 -DFD1375F5CD56D83C8B94CA84D3467574641768C02ED50024DA171F856880506E3AA5840 -1E65B0B73B80BE8CAAC83A1012D1F244F4B99BB4BFF9F001FDA8F06946883B1F0657C3F0 -22900DC7E6EBF936A8D55CD5D0D66291E24240F8B997361BB943B5A9D36900ECE284CD7F -66047938301E2632D00CEC224B1811F43475B3EBD58006DE58DA2F91EBCE1833CC23C395 -C071663B9A91B8FF22C98D840700E3256087FE0A616FF9C2323FBE8CA67CEE432A2D2AC4 -D00407877B33CB35B83591CABBF8700623D58B8C745C6FD0CDB21A2C7B26BD8495AC72EC -A551C5B077D0EE92F5A67FBB4D438114D161566167535A3B8BD74EB10382D997C418428E -F88388B24D9D78C103572341D2BAF842DF6522087E28058CCC1A8A7858EAA41D1F588C55 -282E7AD9708396959DAD7EEA79291F5FA856A15E0DBA1758E9788685F3FE87AD15E29379 -8CA04AD209B10DE234315BC07132D32C82ED96B649EF7BD65B80A45FB3A48C5C3A994628 -118633137D02298916DA8E3EC7598B8FF27058EF911807A26F2189169D7D53A305F89659 -B6AD13AB05ED759A14FC3FA59F36902ABFDE6D02CA63BE37DE57EA0FB0ADE69626B8AFF2 -C4CE000A5AD361A7311FB0503F6C6EAF4E12E90DD26C2FF14CF944F1C7D370D1035DDDE5 -DDACF493116C4B10BEF55FD88CEBC22252BF641FE8E871D2A051F774A5D3D9921D1BA16B -26765180C16A4800F59B9A6B990340D78EF95CE32DC7F14F34A67FFA19474C8EA4641284 -DBA859874D070F5B345083E1AC095CA5348E0358FE7B10F3DB25027CA0C6F63D034974E4 -64ADDEF24654F73B0473208664323C568A2EE651373FB821BA60F3ED0844FB75754B1D3F -D47D3097CECD9D8AA2E3C12A286F3AE09EE3F27E136DCD543BC7BDD8F4E1831FB190FBCB -8B5EB2BB4C91830CDC404EF0F46DA4A9F41345181D0F74F39F36F5D1E2FB935D595E6331 -80AB43D32F82C5F339DEB75288209C1F7E006326239FAD725314A95ED40D51CC657E52C0 -CEC73AC090702C85B9F171C89B2C787F1E7B4EDAA41CFAA83E47CE0BDD74E9AD13E71539 -A19872ADC0B12C705E9B4B271016B208974D97623777A64FD6F4DC176B98B07F9BA07D8B -949DDE4A4236D3F19F360265D8E745845F2E6D74C1982803330033B524B6692E58EEB2E8 -D1A3EC8575839D85FD65EFBAB49938B9BFFCC0A23D8549BEFFC4FFD9B5644B205E17EFFB -A6D24813F3F490722DCC5401EC9BB107ABD77D11FDD60D882E20F1993F9F471BDE3DF47B -13D8BDC905A1EC61E9325D4F6CB62477FCF08BA409B7B1BADDDBD072A8FB38E26AC452FD -B77D07A223CCE2EF62F7F7365B8C9697413D77A188491448143F300B09DAC3F77EC6E287 -C372410597198B2E7AF074597B6AA4E86AEBB31E56BA401D0E6E94C40A4F6EEC7703C3EE -06EF6FF5DDFDFC2B7443D67C04D7311BCF21761DCEA797936EBA6098C91A973EAB0A9D6A -E81C1893C7CE1A8D2181DB792D20C29F3E6C5310DA2F4A25DECE6246ADE8B78C0593ED7C -62D5D6C89B6EA4AEA664A79DED2FC50F958F8B1C7B92942B4E58323F2BABCA0B77B79992 -4738A89BE91ACC5306B0B6E45D672069AEB3485A0B52E931993E600B2E65F969D17585B9 -23D1E5C75F44E2866DDAF942C6ED937C4B7BF2409F1BF6397FD27BB5DC7DD077F0F988AF -0677615675590C950D0F9A39EADB0FD85644D3996C41A5B45393BF9FD3EAA4435F9A99CC -5A35051000E4FB703F801E8B71115A0EA3BE19D5AACCF5B0833AA87FA7CD506C3131B6E0 -5B3B92A493B57268CA478EAB09E71B1DC304A329DC6E7453F4B3721CD13C2B670C19A764 -9CCB29BACB087E768F9A817E893A4A0A7EC4EE391DF074C947B2978A844D944A10E2229E -0BBD69B27AA210D58954353D1266F57823ECED7EAD0AB583F4F27CEDF3F92D1FCCF34BBD -ABD82B2BE6BF7F958EAB3F5921D8CEC898D7076524B12D68DB720BB81305F195EF87BA96 -264878A18F98FCB5136177EF743037D4F7141A15744FBA348614DEEAA97A3510FF277A18 -8081B35AB29A53ABCFF2AF1DA946971AA55A72022A6DD32A7F55C05EEC925CE21704A5F9 -C35D5CE2130C32A48EBB7C30EFC34419355761BCD0732AD4B351BD046C32805BB089A3EF -B013E4F54374E8AFEC10ECFFEE05982915D22E25A2158F5BEED6A95EC6005490FF895CA5 -DB459A2DB44108AC0A9602723619CC2E013155ABD1286C9CC50397CC7AD975A042833A03 -3C2F010A0208D2B5F7FCAC1F4661332E91F43507BC6C55396FFBA9E2965CCA72EA47E3D6 -A0EE5BA53A8DC8579A85383B394A043B26E15EBCE158D95F14C714793513A6E11C0B4FD9 -A02704707112AAB327416114A7E25F6487E6749A8BE860330104E85A2791DE3C98B6D6DA -8D9F251995C972404D1A0D4F044E828F03848565B821BA154D836BF8BCDE9B4F3968E32A -D031AEC5216746F5BB0C24B6EA06EC50E0AFB4BEB48CCE75B016708682FBC063DA14314E -37152516354E42C8A6AEABEC056F7D9B85CE992D20061F25C87125A9DEED6DBDEF357EA8 -68E970CC703B5C8E67F94C2084FED1C6FE0F9BC6D26D132D7A8AB5EAC1B2801ADA11C806 -1D005081A47B901204BFF62BBEC6E119C24E047088B44278CC47816306864CC85A242CC8 -0D2A4A10BACAA701E62980CBB93B59190E7ED184E280B0A20F8CA4749C6375EE133A0A79 -5215D020563EE1AF19A3C573BCF56533C2BE07D4669C21E22FD33530D408714E42371322 -E72A367B66EE7CF614BF7F4647E6FC1B9F9E18867CB630B159D965F6B4CE54BFAC489F10 -FD115E894741C99B40E2810CB37E6F9529CF01989C96E6242D67BDFAF52888F1AEBF1870 -AACAEEFED464733028168BA7FA51311F251B9EB544BB6BB6F5FA90A20BCA883E3804916A -C83A39F9381FEA3D8ADEEE8A62634D02F3C7FCD8F01268976A3B90C59BFB9AB1F7293C14 -48E00102EF69931EE40BC3FACCAC7014FD78DD06EB156C860DDFCD7963038197189A681A -AFD7B886C6E7E26C87D4293AE6B1B4E7884FEDEACC9A2B049119147417F3AEB87B33A413 -C4FBBE3D0E5FB7D61B114A85A9C6F4A95D123234A394615192765DD73865CE47E4E0402B -42D3A1410AA055B18FE654FEC978F28FDB9865B09227A98940613EB39D7B8E4CF55CBCE6 -C13A5ED3DE5F617B495CE502392AC8DCE6A7B8CC7AE9B37943DEF4E6D4015D3936DBE823 -79E1210BC38B20BECCAEEABA24BA09357AD20C0289D2DC03E4CBB007B8B49AC2F1A47CD0 -5037FA11C1E1F36ED2F1DED20FF9D5042D9F9300B5C79C1803A9CFD65D80BEFF3AFFE22D -A6A1A48AE94C7F647195C920B4FA1E025B960BF661D592FE4FEE71702A7093BCD4AC1510 -7CA7CD0BFF3E766CD241DD6059DB2EE8AC74EFDFE8EAAF57B8AF7AA57B41EDF431549CA5 -DEA22928192F8D1D14F3087C9653F3C8FADB30FB994C72FEFAF5AFA5EFFCEC3725285D25 -19B356ECF7F22D1C6101DBF3F476575476166E599DA264073283C19A8ACCEF9C0EE2C69D -D9F0FEE3E57CF25CF842D0D3CBA7204B63FF0C4FB0D364BFF2D43D04FAEA7BEAE5300B14 -319DEC628BE834B7F995DDB697963AC750576C154BA3B31C102BAB9BB93272D6799437AC -9CDD83275AA5A15164757D9D06F95CC444B756237352134AACD5BDA0C41FC0FD98DF9C74 -96D32139692846A141BEDA8E79E7279F1ACB7491ECBABD9FDD1AE69C61B22DCFDC81E440 -B2965F0D82C291D07806957E6D017B8EA7AF37F05F5331BBFEA70A3AB8B078C4F87F4D64 -CCB62D889852BAE9C0FED70BAEB159343A9F3E1F2BBFDE54D5E9353B39B65C16E2412234 -D4E7E1C96D282E1C8D1B38D9B9293FFCDB5EFD759D583C9EE63A407F08A6B212AAD91FA9 -FA501D1C725EA8B08AF2880F1BF0EB6CBF885B70953517189B8536EC2C7960C7E6D5CDE5 -22282682107CF85CB025FBFF2E88FDC5ED4EA44DF630359EDF17BCC33BAB47C302F193E6 -5EEE260DE65D388E935B2471A70A40B5DAAC06911ACD2E5BC9D2853A501EBFB39711151D -643E9E4F78CE0FE4678ACA19C3F7B45E4DE13696E35FDB7EB7AB60853A6CB942DB425AD5 -CCC11AD042773482E0DBEA11FB1D3810AD5DD26B175339603E4E8F32A14BF7E994ACD717 -AE314DC77EAB6061863F7DFE05D95FEAF8436FA218FC3F59EF8FCA198BE6CCAEB3D4F3CB -BAF8F585FE5997C4619EF19E53DC30BD017A67E318612FF82EA2553D060B7D406904327E -779B4980085565B8FD0D7B497FB4350AA989820067B13355329BFAD8D9281F0703A9049B -75DB584D5FC19F3015BC11EBFFC3BDE393117DEEAF11994DF5B62B5CAB0B16AE64DB714B -E1ACE83640FEC6AFB4D5A66D7DF0AE5DBF347EF96B535E8ED1839CB030703846EA3D2E78 -6721D7A3409C8C23E7B0A609525D8A675C88E069E4E39C4E06EC3CBF5D65F4FF176DCDF4 -2DE2AD6EFCF7D2EBFA8E3FFB2353676C39B167AF4BAE04624856DD334890E8446134DF7A -2435D76D4D76090E7B6914873A08688FAD94CD3CF36C10F983A211BC0A8B0276265CFB28 -A976E83092D7B210B997F392AB4B31AC6DD977276E3EA61B4095F5804ABA0E21D8681A5D -E660B5C095054FEB45E9CDEE557675F66C4380A89FCF51E51347BA633FF52CE6F3FD9596 -5B329DE8A88AEC6F101338F1E0ADFD99212B29B725A6C4997117FF445DE895963F2787B9 -0A892C0A22B2D244834CF54A73082597044AC27F5253BBD4B01C42A69B8DFE25299DF085 -8C545801C56453C0E3659CA5A6F4FA3622968F77EBD8E551C8B5FB354B8192F3978E4DE7 -52544D029EEC168734C623C3DBECF5B362328EEAB289EAC40B85EC5A36FA3F73CA1C9A61 -771E4B2DE1633636F3BFCECC3D70741DEDA306255AE27D4FDBB89B811BBFDEEF8867E490 -C1A731C51EBED996DF36340D570FE89004AE7FEB5F686E1129100685EE41086A245154C8 -1D80DC435DE1253923B72DE0C6B2EE3DDDDFE5C0CDE38F683E7CE4813425EB35F9AAD55D -3CD3E62314510DF6C2FC0EE94CC188DA028C82FD9BE6C8597B271FD0ECA5FA6AA0704A0E -9C1EA47EE0DAA990E98E4BCE43EC3ADDCDA75ABFFF6E6FB98AB71271A73C3DFDFAE883F3 -B37A0D2193BD185786280B4DC961470011902D56F511759FAA40308DCE49EA5DE8C073F5 -AB3A29630B93ED1D1EC77A97CB5B157F65B583A96D2D50FD6EE078CD6D7A7CC4A31DFE09 -23A866725740D3E39ABA8305BBE4D4196EFF98A37788B9E71EA6E120DF0E6B9F14BE583A -EF3F2058C22BAE7DC3B63BC150EA62ED03BC238C27E65DAFB0992DFE8C8F5879B75753E7 -375E76ED56BEDD1C983B9548818E6C2BB71E38BF3F771B65F84706D75FD761A14ADAAD2F -4BC97ACCC1191441BF0AF940FDF539F961C670AC4C8129C1DF1E479207F50D1E08478503 -409C4E9D165946571AC1CA1D7EF9D31546CA99C1AF6F7611E605A08EE2E49162EFE39E33 -726D6ECF05520DE13F634AAB828595C898678BD119D7F6BE976AE504AF22FCFAB6F930A0 -29E176F442504F3ABAAEF24723311428384D691A98DF4689C6930D8860FEF6E355163282 -700594922D73799A67D834F1551D7BE208615F590781651CEC7AB705EB278B3470D7371B -A90AC7F0FC6EA11A906030EADF328B63E21A135A4BE6C6C1670C9F795097749D994277D5 -3866BED00493512C771C973CFED9D7125A095FCC4ED15B97E3CF56398981A8ED0D26266E -5516FBE18D099AB62B457C6D8A1CACDBD04A3F64D4D95A6F65B7DB021DB83C43DFC24A27 -E772D8A805FDE4F4645178693D5CD29B7ED26821B4DD1AAB2D256693A99F612500A903C3 -65889A1266CEF14E112C91F2E2DF5B27A3D979E957C5F70C9AB7F64B88F2466ECA5DD0F4 -465D920F5E78A955878C261079CECD27783086379EC6BDA8CBAD8726167520DCEC08D65D -4A9BB2729462365F7E3B97E6432EC01F8833870F1877FAE22E893400A346BF8D8729727E -E7694035DDCEEF10B596B3CE9754E69560A1D8F61AE59FD3CFBD0D1CB94A14AA155C2CE5 -03D238912CA0DA82E700EED99544762C22B8CB36E4EE2C73738CF1721ADDF2091411F98F -2F7EB86C46E4DB9CF84EE208F6049F73B788BFE5B38328DB074752C8BF9B51327A7E40BE -F48A409C0B2377236D94327A0A1E36BF296A670F5E75AA2F4C0AC6815D20B635F02B6929 -D72C60CAAFBBA4DC377B5DD92E904EBC2BC2ABCBE404197C803F7878F33FAA8C66EA0062 -CBB1E24BE46D23AF9762C2050F85CF03084FDC271BC0910266FB693A4C5EE4057C2319D4 -3921EC66E5408A0D28DB2C094C92CE16A2A9802A3D075B12D15C0F4F4B603EA70D69D94C -102436EB6A835D4E9C0937298843750472396D20FD66A039871D21588EDF04E607E03A0F -E4671CF071D2A24DE7AF33D9C1E3124607854CCC014BB6980C4ACE3B73F1544846CBA010 -A86E003A464014699ADFC587294C8F64F80F1311F4E0B8CC1624B7CBABB7EDAC646C7351 -D67CDD61B352D8E21DFA5D802D5CBA52A364B019FA24579BA36A99414E3B018B8632031A -365F4A0E9E5CFEE1C936E546C11AC93A2B7EF433C2010FEB3B2F315D806F6D1F42FCDA3D -144DE40934AD30A14F3AA66539FD901C6A7A9173DD4B2EB6F0F546C43DB1BE141B1E3442 -E0E0DDDBFD1E6C582102C5D3CA9A856A7082530B3C84DAD4FE67C718D7AE874C0B59171E -2CB2F1BD37A1C4DBB3E767E0E844E6A189A828384D042D055A118DE26D9C5787CB81B102 -F8DDFE285F0D24E0CA87658F2DD9B553B1D52A37B0E0A1E18AAFE6EE4D0CA2E3CBBE5907 -16FB32D9030A6C60523FFCBEA0D682CFD92341BF5C533EB7084EB42EF42A0B6E7D172B14 -805780F54FDBEB03AFD73D2219C74CBC569573B5DA65CDF3CD11D8CD1E3E60DC1AFAF5C7 -417DC5C8BCCDF6E129DE171607901C35ED11B0299BF2104C08158EA843AE803B63CAB426 -842C3B4D93954728352468A44B6A02115782156AB7DE5FA01B7A2C7C3C69BD02999A4F89 -3600E0E79F60EBF221A40269A40904EC3DDE24A4FCCF92DCA20AF2614B11D85F2EF90015 -9C878BE4D889D1471E17AEBFDF34C29ABFBC8B1FE07BA33A5C6B51B3DA5887AF6C6EB0FA -A7F7AC8EE55FA82C66210012FF0EF781815EB18D1530008AD7EB0705E854B3FA44AA79C8 -EB7A91BC40EFD85DBB3AA61209C03D1C8D70A57AB608FC5EDA04465E8C6545DCF52C867D -6F2F5175EDF68957BA609B1A5E6F9FB15F628EA7F0D74186E278D45F89F981660029CDA0 -B1CAAEF12FDEF8C4686171A9FD08BB0226DB70C564766AF171C6D25A08C6669F71CE6749 -43F553CCBBDA80CD3C55F283F3068BC8070B96EA52D2853565E00DDD209166FD46C17B85 -604F4F4FBFAC1E7B3FBE13DFF9C2354E625FC87FB3EDE892C48BBF9D11A3FCDF65A29E76 -FCEBA941644FF4485A4E14E5749CAE0CA96819C9B637CFAE5B6CEB8BC390444763570362 -D8B397C3783EE5DFFD08EA0F09DDC3F1A29452B3287443D67C04D6ED1E61B2DB7921A52C -7D25073B58CBA2699AB8578FC49CA9D550D482F1BC7CD283BB8B02390DDEFDE7CFB447B3 -FE99D6FB4A225DF571790CFA6FF35BA51440BE6740510D7BF8CD55FE16E6F394FABBBFE7 -2D2070BF9CAFFD58FCA0A70BA2F898511477A950293A2197A3E8A7E3FE7AEFCA9DC6704C -0ACAF82C39784D0D800F52E775150D976F1BC9B9D91EA99E44FC9CC9EBC08DED6F939CB9 -86CE37724553657133AB4903D0950B235130395EFFC27F76466ACE37A323358C6F935EFB -E8109BDDCE9EA7B22F92DA7A5F5AC992B4FA798C0F670C0467A63FE7571F707053A11071 -F6BD8D93C1B32F1359A827222080AFF5940135A1DA02DFC6AE1113A93E5FC5BDE02F9739 -0FE65F8680B0999EF41AB024E35A88876DF86E413AAFBDDFAD693C0BCD4654FD8F5B9A51 -BEF91593357F8F16B7C59CF6DB3E5B6B5597B8F8EE953FDAB759EF5F42B8D7E0282CBCFD -DD13062501C683FD109D972DBAB823909E117A55B08E20776A79BA61CE6D84AD8995BE0D -4D2AD126F6C195AF54998FFB9131E1F3DFC61F6AAD217D0DC339BF8DCE17D074EF5537E4 -7EC63E4B707D0048543D939DCE6852DAF6DC1FCF95D689441B998C8A5EEFA7DFEB894B4A -90216B335464CA50BEAB87DBC6B3E23AEFD21DBA17B004D9BCD94357EDA82F2E388054DC -593050F7226E133A937F83462C4A91079B8E96029FA17A4162384ECF11F95D53F3984022 -B02C4C82A702F75C0C3F91FF94571981380466C8BCAB42C2D3A33C282E7E6F5A73EA38FC -7E296FCF8B1E4C24DB0E2F7F076F659EAED92DA4C9700B6746ECD85995746D648B9FCEB8 -FCF7DE89F299DF6A6D7DD11FAD78270D2F45D75FB0BE0FED1C1290B733212C1D1BFA80B5 -D17CAFD3F3FF5E504B3EA44727AF6F3F37DCED87DB486BAEFC2D7DD7DA55635F671895F0 -EE51D1102B1B491542C9F3CC8F1D1F14CAE5700DC1566B7B44ECDA0150ACB072820C480F -F92F348C108CE1F70BBB830CB9BC69A3F3E4E52D191BCC2BCE475734B38238725E3F3A01 -84AB62B13458F221C2C505587407B5623B23FE444ED5BEB0F37CA4265FEAEFA74CB365D7 -401CD4C247AF0DE67280316545EA659C2401A8D8F8279A8BEAB4FA83F9AFBFBA32794C7C -A7268F6BD3CEBC42895E3317C1E8ACC0D82735559AC7EA0378524E879BA243CD6F938C6A -6BA39385EE7944805C6E3D0CEC912D1D711D90459D032D0F29DDED3320E437A8809727F0 -E42B52CDF7B49A350D8DF3ACC7FA81AED6E290DC3D40BA6A7001ECE8222BFBF2E7D21AF5 -B5DDDE2E531A5042892CAF60BA4BADD60AD61E811BCD9D7608E00CEB90989E48DC676155 -EF3D790B8A4FC96A351DC301FEA7B959A8CB44F228B852CBCE8F9450E4D288E48C3A5D6C -616B9BE51F38E9ABE16CAE86549316ED8B58E9B0D81E7994BD83A314601CFEBB5413C580 -399D87BF9ADE8D90BB6CC68CC36972159CB55335D74EAAB882A1C3724A2707037E5098C2 -2A6655650DFBB2F87BAA1B3EFF8AC76397A226B95492C64E648FFCC08F8A552E333F1E65 -660AEEAFA3B0296CFC6B300D3C6FBDA01CEE297241588DB27E449C03F0386EDB5D4DACD1 -59BFE6C5915988099909AEFD10008CF1BE8EE8E9F1DCD980DCF0394503177FF49827A3B9 -D9FADC16F0890A6D330146809CB5F3823DB1F9FE042B95146D6880EEFD113174FE00681A -697ED8BCC6E6B61188903CB3CF5F6248EE181772F5F873B671812B8FA93C1089BBFEC5EF -0696EE1715FB37348E75AE88A096C1141D19E7AACC7A1DFB282D180E8A08A8C92610D2D4 -E3ABDEAB7DB34FA630A8F5151DF12269454146FF715DA88798240C01F82BCD3BCD81C558 -E6CA13767923803162A8EADC641182B71A205CBF91D93ABD4D194E327234F4FA56F4C496 -40BCDFCCB269A49F449929DE799A99D15460CB9C131CA83204DD513D68F10A07FDC0DCC4 -6B93F8D87EFDE4590E3FE360779B5082401493763FA73519E8CBCA4F815AD8A95BD10135 -3A1F379DBF7ABDACC2E5FD6CBD2AFE90044D86BCEE408AE8A32C89C224EB483256854C72 -E68653701EA2AB54C09F98A365FF042C4018A0DDACE380B54FE568F3C72FF16E73A594C0 -E9F3A228171F6EF548EEB0A2F52A1EF48CD81AE008B8251196854A03D4474EF064C3B9A8 -C92427F5C3297BFED28C85C235272303BBA92E37257868DA3D4CC651A8E8B007AB388337 -29587176479D1F6A95417EDC03D9AA5B6FC390DC64753B279206DF1037A26F38A56D8A5E -97DA5E3F416F12FA14484C939EBB24CCF60CE0CB682821439DBA8DD842E6AEF330609AD0 -756ED23585F99CA1BF6A9D1520682D939B38408BF49DE661E632FFE11A7B9286AF457698 -1F26E731E8576D259BE89AFD3E96A0872F1992FFC3D5687C5324822D09FE555153E1B03C -7C1FBDCF72E8B369BC26A0995C6B5F5C3F0B6505AF28033E46CCD32D396F1FCF2BBC314A -CAF1BB2CDCE7B5E89015E304E1ED36853C9B8C4550894C208398A4596EABD6A675EA1716 -2AD277A409A2809727CB0F7D02F74910093346FE37D14EE063F6D3B6EF9C682988ADFAD4 -75D07035999A7247440FC2DA98D5EF04D718281C8F36719ECF7701D2AEF8B845B983A1D8 -46AD41CE818E1427A23A2E5F842A4BE05A6E867653B6D4530E40B96288C1FB0C49F47CA0 -ED4CE1456C3582C385155F309A5EF60819E3E2EAAB741278811A9DFFBAB54762ABC5F045 -1841D0984BE8960BB21E8642071E442D5EB7491F2261C855151628787A4C699EDA1F05DD -C578A9CB506FE5308A90B3752D067DCE9E715F12F662C5303CB064B3F5FB46358CB4F803 -21D29935FC49B937C066A1AC82913863D01C1FA85156CD0869652350602D766CB27BE412 -1E50493C0AFAB232057614AF48CBD74C4685360FD02900F8780AA8F0827F2F7E0B0B0306 -80A4CF3969036081462D92FE2DDE06DB413B4E76550706B43AE982AE2467353B8059A32D -B35DC0D388D6264C573182970C2D0526A6F57AFB21DFC59D22F8D791A214F50D716428A4 -BD37D25A5958BFAE8DABA9E2438270B90440AC7DCD9D4D8A3AAE7E6F0D54FD15D1C8C1D2 -3E04E9BDA3CD2D97C1DE1E6499DD2B2C9D1B789D600EC6B2B9E24739D65D9C8114606645 -D8F2ED5178E3647DC8CE3827E53FFBDFD5948F7302AD1D70987FAF02E5FD03A1B9CCC6AF -C658B742C88DC2547B3A4EC4CC5414220EAE69E23F7BEC39DC476D24331422D0FF109416 -CDD40545F6802040ECE231B7840CD13B8611D88A25CD60BA268CEFFA145592ECF8CEC07D -A9846135D35E035CB55F46FD5B9AB7D60CCDE973A3A51AC2F0314471629CB80CE30E6ADD -71B6819EAE128437C1AA243E869CE668C8BCA434D5A1156A41581D27F3B52DD26BD4089C -A25EF40DF171EE2109A17BCBC93B05EAC8418F4E415B6AE72CD4211DAA97780F11A4FD11 -A96409AA6BF06A69E6ABF9D31FB157C698F9CD86DEDAB707BA74814C9C96BADB58EEAA87 -3B4D4BE0C4A6FEC42B9AA8A70F57DE8399EB5D574B132BCB2D3FBE7ABCB621BBC3E483E3 -378CEDBD2FC9B758AE746BE44EB4973581E0F402C1738FB987E7C7B32FA9E3DD3E822F7B -7B79A5D67E0E7C455ACBB780BC94AFB886122FEDE728272B619765C841DEEB915C501C9D -5E162E25835F660E33C017C88A2BC8D1E93D32CE0C43A83C17937B7E886810F774215EEC -57A17AFA1F89AAD6751ADE08A4EE4A6DE1208F3A35D927850042155EF6F44BBA6BABA143 -BD726F652D7F8EFB9EF14D281186F9A8BAE057F048D7914429B7BD0D95DECE36C48C6F17 -599FDC8F31FA2A0444C683962895C68AFF8B343B9CE4703A2761AC84B1B31946A7C8373E -A369BF33219296783C5A3465179E1BAFE1BF8443801C972CF6D28BADDA13F78986F6DA38 -8CE4453D5E7AC0CB518D5C889688F3E54C3C00BAFF896961357BE6B4B487064A9660E353 -E8CD453B5B828AC0F166B50E0C1CAD4CE97469403B22EB2C3FCA6A734706EF4CF7F9331B -53E13D0A5653473636154D94CCD625F8858B69ABC25762AE4FA1763BCEB2989CCCDD275E -ED8E95DC14500574276083F59BCA0A2BE8BB1A9A5510C63FB48939BB2ADE959B0342E759 -F556A6BEA0D78099719C9D4FB5D8741598522D483B77155C9030D252E28C2AD364C84364 -39A58ED8E27CCB1469CAAB4CD8B7293BFE89A7BB6B72C4EA5D7C29EBD5B2A9DD66BAE6F1 -9FA45E886E5A79B5FC7A65438695659213E0F4C7A6590911CA0C976668C7C2697C4F0A54 -4E3240D23DE40D53274415F5D6CA333CEE4E6E04EF7C42E84DC0B8F583F83185E1E1CA10 -D210AE0816DBFED7AA382EE1CE6EE1ED7B3F3AEB25DA4B1F3555F39BA2DA5B87B9F78B57 -9B65915E2440B09090E4E8FB0C342933AD8DC8BA3DE1340F00A037CBC4D1E775D3555532 -F828FBAD77499AD45D007BDE4AD065F462D727AAA69E314BFC1055C5FE9637676246DB67 -A6BBB7A78AAF4DD18611871835C218A45DD0852434ACCDEEC60AA4DC48D752FE4303AB75 -654E270D27E951410DC5354E85590305BD4B0631C90E369D992ACE973879CB962EC25EF8 -D01C2F4BC4155F409AA95E65B89D4D1AF4989B6BC3681E913CC4CD798AACE97678D4EB0F -131D6C2378314EFF41C585571F3901B0D7BBA1E30CD7ED9E4C706446D55B9E269FF75547 -AF498C716FC0A951DCEBC8BFCF05DB2375B79CC1EDC162ABA073F01C06C0D64E4D17A692 -98482F4B4C1747A08B78073D590F5291936AC3016D5C2CF84DD6D93CA7FBF9FC7C9BCD98 -4EC0E07F03D6E632100BC328068B2C9C8BAABBA4E0CBEEE49D37025FD0CD005FE50DE670 -F7BF621CBA9C4723F3D7A6D1BA5AECCEA901403C03B66F6F92D403E4D89C238D75946080 -404B79D35F8D5E0DCDFB0E22AEE8B6BC7D994D05B7AED76A40A22DF9339DE4CD937D54D1 -E09B6660992B6FBC6B36791D5AA53093E29C78BF59E0D137B06FEE0A553939725EC59380 -82954AEB8EE503154E8B56F4B45B6357402D78D1282BFFD0D38D8940F0B3AA1D48419ADC -33E11C96A48FF09E3A6CCBF7C88A0750868FD61D0BAA581E6A010BE41462FF3F71DE3B9D -6951D2771373AAB7360AB1A7EF6C04113553AA399FD21B02E1C90FD6FF8DB09B6F485CD2 -EEECFB5CE1C4E0F3675CD792BF28D726C065D5B8BEB92681072CBF17EFBA31BADD5AD401 -C3171B406ED57D757E59AE1C61AB425A580C179771334CDBB633428DDA41FFA7E6BA6668 -568930B3AAB9B51EA7E63845A2D50CDD60F8F60C3FAA5549626895644C1BC9DDAC415BF7 -96137F82FD0FBAA9F66269000CE1421BE1F617564FAC0CDD70AB2B2DDF5C804540182B4B -EA2608F4C00A220D73EA038B76AAE89BDB8B6496D3F8CFC7FA60701303795C1BA8EED486 -48BC6DBBE06A28E84D4151F85C790E5C6C7862B7B5E1ADAC6EF0C300B1AAE19F092A0D2A -160208C31B9D36A334511C10339995BBCB3C06D5A7E0658B6E7988FA3704C6E109EB3E60 -687983DEA045BCF7596F869A5FCF88A68982DA5FD4E26F72E758C60917094E7A0BB9E32C -B16880994E573A73F4CEE17243CFCBB4FD85F64A249B74454654E360DF55D6BBFE5DCBE9 -AEDFF628B1F054645AFF8DCB417683CAA103C4FB59E9FCDEC985F0CB8FE454B245C42F81 -BB62E1128B7581F1634D63FA0DB839B631A5C46A6AA19A0586FF8E1F36639B416C2E348C -2BC4A28C9A4BAA5274EAF37037C0E0B1F74715F5DC6040AA6BDF49175744A7B214F90355 -2CF60765D50B7A92B7CF05BE188C4934EC815F2F3C274D5DE6945E5A25631DD732EC10A5 -D1D5911919442FB0BA3B411A655B8E9B2937D2EE2B317A9F8656898B2BBA3C93BF7FF001 -FEEEB4701A01F6493C6AE310789AAAB18E543F822AE6389A95F8E07F6948D90DF226DC22 -3FF6584CF81705161648F245BF7A95ED126F084190D003824AF91827912987CC74BBD073 -5898D710810A4057B652E46548031A2473758D5157BE9F657D6AD6E598FD6EA797F66E6B -AADF37C84C671A8938BD6ABB7B9B3B793EC1B8A70C1284D8C31B180E68BFCA71428EE2FD -D10185264F9AE8049B64DC56132A74B609867D3B9D4815D1BBC83A6CDDE66504F2917544 -5FEB2E0203BE174203BF266862F83828A462BF880AB22EDB59CB180A8E0CC4259E4DEF1E -1F3114AF8C03DC00C7B1F39027EBCC62D308E1A99E9C0B4AF746DB1BFC872B10C8D1275A -93128F35E8883DBAE47AE1EEEC72ED408ADB618C32C9D780AFC63F1F4D3CA1784A0E483D -401BA2C3E2B8B9A13307028DC563727C72F97C2A7373F9B8B664782C69999D827E4EA508 -585A47401D5274B658CC683401DB1B0977A4214BF0E747116F3A2C06F75395A4A4A5D8D2 -68E17F8AE00E264098436DC1054456A72D426FF4DD84EF7AE9F4C49434CF6C9218E7B91C -EBA8EA88CBF22F4F2DBCA527FCD11EA79E4E5719E8FDBFF5ED895F5E640353DFD38F6D11 -BA785ADD90035A3D7BA68620F26CBEBAACC14E13C904F0FD147D0D6326D94B42748B7D72 -94BF4F97386309EBC593B8BB4AF0D09C2EC2C666CF0BC151CE7F7F763FEBF83F521CF115 -AE13A8C069F3188140C2E1208BCCF8D05A3A79FBBE8E58232A7438DE1EE565B56146C9AE -4DC0CA21A5F17B05229FE0373C3291266A413C382CFB63365ECD9F80DC6CFF7C37CDDB9A -98786B3130B61DDE400B3383D300974B9CA0BE9326C2843267B805D9C2BDB088156A7641 -704B203D0485852AB3017B851D63BB4876A3CA32AB30B87A3A9789D10DD76168B2FC0BE7 -2DC6037A9ED4315DFDAC2691ACBB975B777FA7460A851217B7328BA52876260F0E9A43E2 -962A80174051139EAAE4773184190EB46E72554267C0FD1B9388271B7DED405931F65479 -FCC4596027F11BEA64C684BCCA6896CBE3BA2CB2F71C1AA16B55F63D27CC239ADEF62E8F -090863B0659D8E41B45B65F91BA24BCCB6FF5F37A03320282156468CFE46F95612300B5D -1D811C58AE9DDD905174565900634F0E20AA6D7A15E43872300C876087B005CEFCDFBBD3 -10D23C04EA817DE15F350C4F90207637DDCD73BE0834A1651709EC3EBC1F7A73457ADED7 -68D88A2653796D132233C25030EC8E8159D128E2260D60F18097E68B95A56E3C590D4F0C -E778F72FB0A5E182264651B3B93BB5115BF14FB1D71AD9C9EF953344C4E7B04B16000DF7 -0D8500FB657C4D368B669D92638E0FB331EC3AFDC59E75730FACB442DFC31FD087174379 -B491511BC6727E4C31C2FF756C409508979DC47972A9C0369BB61A450BC888B21213DFCE -0FB400AAFE8B250112CFBDEE410B03F344E1C6E3A5743304D23BB7897D6DD6A052346AE1 -66C20F309083C0CC33B1B7D4909D8218AACB35134DF67F72752F697C4A6C568ABF2A6BA0 -6138D0DC6FF73066A5E9E559E0A25A0E4BAA0F0544D680C812E16F70CC0F3521491ED1F9 -747958D476519258AF9141DB94B1599F78D80AC9FB2AF393CC98B307DD3DBC5BE037C41A -CA0450771CD31D126F3577A82E0D32E1E114753962A635DFB27FA9BE95240B38D4B20E64 -651847E20DB85F80D062E80D1377EE0D6A751B5C5E5F89E6A9F09DA05C3BA03ADA1878EC -6EAA9FB0E3D4A8E707B0EF507256D60F76E25B61421A4DC14CAF733B03F43951CB3A4880 -7664484002BCC03695237E902217ED414DBC57A89802EBF93D4DF4ED83E5CCF8A79BA8C8 -92ACD02A4D1BC0BECB65C3D2CBFFB5B11CC143D37EE56A55338854EA43506FD200B7F350 -EC0DD9A283D0C46C5D3E728F920875DE6D3EAC17B025CFD20823D2C435C120D20F80F948 -6A37B71B68462D9C38AC003E66871047A6DDA56FD5CE319C209DDDE831FAC80D8C6BF498 -DC6B58592451BE41740BEA4766E0D71E540EF881A9110CA16E9ADF2ABD9FF296279AB2F5 -CFCFCF8020D42B01F4CEA91440C7634A4B901E5B2377D6F37174C692ADEF3337C616119C -AB1735338F2E3AE72B22DEF9735318CF8B69F23E110D8439365C67CABA3D2C16FC96FCD7 -5076AA46F4F5B0DCE6E2D5250E2026609A76C41410B8CF45DC8BCB815E45C07F0C248BAA -FE71A474EB9CAC749EDE8FED1AC13AEEB5549AC306B1ECF05DAE05E5A339ACCD9FC8E52A -4EDD4E2E5660CB8640D7DF392BF2CA1B0864C01472B4ED4A7649719276F3709FDF5B890B -6150DBEE2EF12390B63FAF9C65AE46AF648DA2CAA1AFEFA6982E07C63F810D044BB122DD -2AA67ED2E98BC3B7505BFAD72E05E228FEB9FFB56068FBBBA1E8193EF539DF257A1D3019 -3B2E42386E6017DEC0593454C76E13DAEC50FCB81BA6ECC997225B79DF89783784083F87 -BFB92457456F60D9424C93CEDD40D4D462359E7060282A5A54E3F8F54C86CF6740A8AE60 -C66DEF9B52513D70B64FB40671EB762780F36180F14724069D029D1B43DDB672A5A6A9C8 -9BBBB54CE48D4D25E61A670344B4D8DDC7E57ADADE6CA7A1BB5134276528D0450E5DA9C1 -B8DDE79D25D3DDF220204561E67855D168FD7ADD01F497AFD5D3E89DD83E069486F55B59 -B91823689873ABA14D5CEAC606FA8393F1B34582F871B6C4131B9C483A4BBED1CD69BA47 -37D050F57ADF9C806CECCDA795101376838E893016CC92DFEAD0699E6BE626FFFAC028E5 -462A1E7CA9AC3FD199B4C4FF894A3E695E18646BA33B900365CE6B810C7D53DFCBD7F8D0 -D6DF20F3B09ABD2C7E862A5C8280E55612343FB741297A6BB95FD9423C4E0602A8F8156E -365AB54540AD5449FEB3E4D13C94794F17A0BD06D9E26DC3833C87FAA477041D1394E0C5 -993507E130C4F60019FC0B4B74652B2BEF4A9603FDDB3A534001448A8F691C0A97267826 -1CDBCDF47FB4B0A7830B434F180625B451173BA129726834181EAEC346CDDF68F32A57D1 -5ECD44FEB77C2054908C6F6CD73DF94E4FEB47EAB786106F25CEC7020AC7BCE0C45F7935 -46E02937D310ADA5C46379838E266B25127413F0AAE1AC370E3C753C6A7539C8AE525CE8 -9BA7C49158D4205E10C054DF541B7472A0A6040E68897ED029F42E013E0B8EA547A7612B -157718C7ED485CFE6CF0500C88A0CA1C96A2320535EAAFEFA930325B59E551C8D57BBF90 -2A5A7785E69CA885CB7456ED7D063C93161B7F0AB5C4A33B19CD8F9260114B75BBA018E5 -CFD6EA1CA19DA6A157C632769EEA695B634311B4168E776F9B81AE354455AB0E9BB355BF -1AD45D85173062B1B2E66F2820512ECE3A912A5383AD544FD4B0269E30EE1D120EA034FE -5257DD2B857C4812CFCFF94EA3B8AD00E18C2AA887CD8E2801740C69E148DCEFB34B4897 -84D875555B9362A35304998FBA3FBFA98D6902DC326F0F407751DD3ED02C77F9B22D768D -B8C3BE360CED4964E0D413D9B288E403DC8E6D89EB0B68B4BD3959B151B45FA8BD1967B3 -70D20BC10CBBF7F626F1B4C3F125833567B9E88DA21EF2CA6C209DEC8EA977752467090C -0467D01B5B0EC2ABAD8596A3A342B120A7E3103B009E8BA2B95378DB329B917C95587A82 -EF5F72890BAAA37264BB4555F5C69D10A4E64A462ECA8B4A1BB166D88036BA071BC33DCE -3E79FC9F144BC2E446B720155812C06F10752D1391963AE98C4CB8B035C3C8E2F7CCC529 -ED8AC3A052DEFD0302D1F4D5A1BDA6B042C1D90CF84123DCE6A7C29B3AC8FEA16F07A210 -3B2C7098ACFE7FD92682FEDC1132EA886581B798496D59B5AA47CE3BF3A9C7CAC6345386 -F60ADD73B0D52642F4E87461B1C2792155D2123D0D7BA43904891ECB1573D871B973FD0B -52D76A445B55F960BCD3AC44BF762B7AE12DB4FBBB0409C102445C759E7738C4D3FE2BAF -B97DAEB3517F5FA545180AE55DD7D4A0BB03EECADD21902226EE99A7156689824D02FBFF -41FF30B9D94D14348BEAF7D3710725E9A8054DFFA2794D7D5A90482E9A49600885043C5B -E0E220ADE6CE0FA63C5826CADE8A8363440C47E6E7590CC8F5D445121E8F8B947D8DC4E5 -DB5301E89AEA62B903ABE3AADD4E93A49A83B0BEB040F7F2C320301042CC9D31CCCFFD70 -32DB766066FC83EE7109C6D8DA79610D5E1E94848556E4DE9FCF55DDF8BE524361A4D673 -6F09CB8AFF3347C41B9397538ECF26274DCE7A27E76301007A492E0C6BECDCA0B1C9D1E5 -345AA204F29F361FBAC0211BCB444F8D9B9637791F5D3B869A5117CCD73EC5124F1ECF23 -705209F4CA831C5AE5BE9EEEB390A8666BE40363642DABBE28D1E06182A95ED0F7D1177E -D3294B4C29D8D1FAAA210543C3850FBCBAC813C21AF5D62621623DA41A27F9DA0ED6B0C3 -A2AB61A913094FA2574C52FA1195521962C8D6B8DB2A10139A9C09AFAC133A8BBACF0A86 -01F38217602E70DB3651DBB083C791E7317694AD1F50FAE278155390264C32975838DE33 -CFB0ECA1B0BD993C2A02E1DC2F46293018DA3AE825AB81621894620054724C3A8D95ED48 -1E899F972E6537B21FFB8A4C55319D15A03ABE885C333BE19ADBC450D58C5DA2B76DA6E6 -2487A71FFD2A851F0551F17A00D165FFC44F204565FD24B0D11C2C21238F5D6F64277FDB -4D0704DD6271C69F4A5CE05258832BFBB7D303C00EBF68DEF694D77215084C74BD2D89C7 -8FCFA635F694723DC79E99D87F03ABD7A06BC1BD7643092790AE2D15D63D2C98288AD284 -7F48081116C31D98680BF2C03E4C2FE4DA45851E4FCB6FEEA80294ED5709A796716B134A -8EEE8ADE6C3709541E3D234F952B4B2ACD1422756B8765AAB9C32338736207BFD12DC05C -4D7496F1AC0797D5A3047F9449A8C5237C75EFFEB8E157B262A833BFFA03A26CA8AA1188 -84426DA94B43BD21B1028EB2A6A30F41179DA886DCBE99AAB28A1B329BFB743ABA0A2F4B -B4C400F1F3BD3C9A0109F63EE563AFBDC1591BF3CFDC863429A79F6E0A21A749A934EC7A -08541245B9F3CA401EADE0438C18B9FA2A78B618F38C611F6C053D2F6A0726CD20687DD3 -B09863DC0DBAF040D15DE51397DDEF2712F688D291B71DB3F59A7D87E2F44FFED1144981 -A11BB9824B1F4FB6C9A1CB11867A187796E5076C811A9E085EB5C202E0CDE461CA541CAC -D3FCDB4031FC78D7410C4D1DE558A5B697F03F9EED11F731678677448420B876AF142242 -574C740985FD2B6038AFCF1A81C4D89D00C73A09C93AFE68E5158B06B1E4A5122A371687 -93C5744583791291A8B8C2CCADC8C1BD233285F91C87566E36545ECBF3A8D5F9B3721292 -8BF2218F2242E3F19F91120CDF7D7B118392A4F3742911D47C4B6B2A61A7F79378DC8DB5 -9DB041A761DB0EFF44C948341C174E5C6660DD5D3E5517EEE0DD88A655F3F9524168CDB8 -AA2A506EED7498CD8A320E2FA42D10B1F16F8FAB5B5E85DEA6DA3005ADE58DB47E35C71A -C9527AEB0DB1B59D7DBD35A5E5C3643E17139FE1BAF662C7E88031D01A9BEAF71A18DC76 -F8AA4EE94C2575C438BCEDE9118D5124135A071E3DC0B103DB08D7277EB7E9BBCEE953F9 -77E01A009A031D4A204B87C0F0BB722508B76E4F4ECE45295A2FE89A1DCD981EBB4F9877 -246527356F2E8DDD3A67C8A39047F4DBD69B37112BDADAB6342FB6C522FA37CE74FD74B4 -D37D919B612C91586A2F1EC2E1AD95A5DA5F6FC0E260362765A262386FD8B9C27CE5FA84 -EF0B7CA9A77B1C41DDB5CB9450AB1366C00176A7D47DA6E4BDB2C1C548426B69987EEAE9 -66F4A937FA6597B2A1F2A690C3B467C57DC1A6E271B4B4FB7A60EFE602B5A2CDEA496F54 -073DF69EE58BD31963B17870B41EF97E852E286E1EF07D48FD2CEE44F51FBE8FAFE8B171 -82DF3D6343C85AAC1F58494274574A6231652AA194027CDDC257B942A7FA1E9002E9D75E -80EF552962CC5DD48735A14C8B81020C167319755636653041031E89BD815A299BEE48C1 -626BB77614622D88D310B0E19CB4A9E57C174BC369BF13C727FB452170D9E830ACCA78FC -F7F0148CA9BC1EAD7CA3BE325B60C676B3C5AAFF6FCA80FBB8737C7BDF51549439E06B38 -79D71DB53A757EC2C2D66FFE2CDD0C166E2981980AA2166112BDD1B14C19916A14403BBC -7E0FA36A3818F6B4D4711BADDA0B113F6EEE39916EC8952E6A7858BC65BB175488A6BB74 -6E78C5D7C565EB59ED211C5DDA7443653F6467C403F9725AE83953468488A6EA8237CA9D -538328329A8B23D3C96727A7BE68B59048E394D2BD3E9B5B97E6C88DB0D3B2CA42C1E845 -9B375667990B8B28CAE32BB63B8973E40533D1E5FCB26B2F680F985DF33F37AE6F32B9B4 -CDA270B0B060C8E511A0220EF06F0BE429D2B977A3782A086676AE58C244D74E364533D7 -467DDB36A7B93F27A9B729BB3F0087C01E6E38ABB26A2CCBD35F2AFA01C1A085535F4427 -521B968EF7DC76BA612329090FBCB6C99F73A61BF1B3D0975F2C7457666994C94C5E6FCD -4D4CCF29DA3E355CC64034655471885713804F44081F1F4C426670A0390BA6D2C25977A4 -91720310D0421B3D5FEB3C88BBD35B2D4132497904A74C3535A15B924023C464CD70D227 -F28490233A568AFE309F6908C0F369189803ABA18497C20B5E47D5D969DA3EFE03059316 -C0CC37688CC42783823A1618AA7C0AB924CF1D4B961CDA7DC6FAAD0E8F742D33ABC15730 -CF0E246173CD0A8F21466C9A4A9F86EE6ED508BCFA0E4AB5AB079F1EBA14D78E4B562F81 -4A1F870260F35D55D415CD2C10EDC209F23BD8A0A0ED6FB8EE11C30EBC2250559B02221F -7861C08C18BA12E748D7181EA7314E355E27EBBE1B3C00C69C549D4442998259D9966E9A -6C89F9D8796A0DA2745CE68C3D15368621F9AEDD74264565EFF245EC7D5E235D524D19A0 -6D1512B3A823AFE1944DEEE38E6C365D8EF2917C382A537FD94DEB1F7A959A69A3990033 -F48466A241B4B39E8AB9643677BF42BFA3080B8B389DC2BD74DD9CF7D2D466CAB7CC7EBD -33FDFC9CBBC0B2A0D3176B3D5D9C78B121705E9AC8DB4B76711A8D299D6EC76386C78241 -FBE1887604B50BDAA81187B0987D0B7A2108A32BAB0406AB8977F4EB25957E88F93D0CDC -E9121D49CD3FAB7EF4B4627A731C43E7198EBF05E662A2A81F46E0C55510B6D47A5363BF -63A34E483316B4FAB3BCBD0F190F554E8133E1F31745424E0B29C031D84F24A1250CC3DC -28384EEA40BDC069C457BD958A8D2ADDDE965903B436FE8BABA1D722F82B6BC781980B54 -86FC63E2F918716776F756BB91752A0F591F518CD941AD6453AC1D5ADB8016E17F0367EF -973A4F6DF74BDC2691457DB95EA4C5729031B8397663BD0C4388B8E514B279F0F003947F -9DEEA6E76F6C3D3BC3F64987B5AF5F7D520BC76119DD36265453DF598CFA741E9A404704 -4C2AE3E1E7472CC11BAA4D5A32304447DCE4A766DD19A50542BF90C3F1F93BA6669BCF83 -808634A13FD2AE46048C42A90A8D0768E3BEE2B902E564CF27FAE1AE71E5862A8554967B -1BC8FD84EDD3410EADF57CB3E4617B65B26A2B90CD6D47E7796217B51BA60D29D81F424A -4590B5A8FAB9B7404CD142CA01B5ECDACF659A4B4997BF1D1B6F9847D3BF5102CEB53754 -1410448BF07E8E49786A718F56FEE3966C4852147B9193233C8008A2D2DFB70448078B95 -81FA5F9CFBBABBBC5D7E6BED86C9E69E71FB53AC96FA096AA8E6E46B67BD96A58A18AC48 -854D5C6466329B0A9C7C910A0ADFEC02A784B3553FC43E4C2EA8E1382AB1D9C103CD1260 -E3709CD18400AF2936AF02BC37FC32054A73CBF36B98521FBCF62D4F25FC7E0F3989B25C -084FC5B84F16F1812B52D7AB115F0A80DA3D846A3DE4A83C512778B469CB887EDEA0FC37 -9581C927228B510F441071FC705C98024CC64E9BD21CD7DF90BAE4D271DCEB183FCBAE68 -DC78E977A8D23206CD3D7E3AEC0E8607E24A431C6E24F649370C897A65FECE2BD91C7D82 -F7A1CFA96AF95891FB8A2806CBBD2AF6DE7205E8E7269DD0E8703758F93D0BFE29CD178A -62BE495A0F7574EDF1679AC65A72C43131B63AA8507A225C447CB2D71E0974A1405E5CF2 -E13C7FE15F3FE046377500E9C4A1D0C2825E49B8AFFA5B54785B39D27D181B0AD38E0E1D -35C03186235676EB44E268F6308B17B45B2AA604CBBD05E33497F4788E969E01EC50A3E0 -F8A6CDD1CD8950505828E16F2B85AED36EAFC45D9466045D43AD9B3B3B2B92D5AE0A383C -4C0D8C27BBA70E4A6E7F4D134E4D684B9AD5BC57F19810F88F618F49C66DB98D76F950C5 -25AEDFFFF5641D0DA2532994BFA810022AEB15505DFEB561227DAF7FFC9B2E1578108ABD -66424877BAEC36FA8FCFCD8E23ABD236399F4AB2FCD5CB2DC84B80ECB9C6EEEE7271999D -37272C0F8D1A306814BA2D302F7A3D8C08EF5375B38450E852820875DD008B55CD50230F -9F1C513684B5A7E0BC1C992804AA638CBEDAB8D673556F9ABCAEA81059B0EDC0193FB823 -92E4D7B739E8B0053F84B7891434CDDF773E15DFD66122A300E0A561CBADBC15058310BC -C9E44582D513D63E90832C521CA6F7E6C70D3A9F461BC33908F1773575043419B5310F74 -1FC502C5E52D7CE3421D0BA35BFEFB54E477106DFA69677F822FEE85CFEAA54EDF1E641E -D5E73F733F3021A0CA6F5CD5EA5ED8C09B1F3B1CA953E92A4117839A678572DEADA59C50 -BF67C6367BB03CE4FBFEB71F652918939FF2B61C6A89E2278D42FB30BEAF2CE7E6ED6D59 -CC0B941DBB15F4BC70AF627817277ED59A95A3FA22FE35AAB686FF442237C1B4A9FDF6EF -62E4F90266EEDC96AF7F7D538DF26632B6189C2C74F62106734308EAF30D9A6E25A8FC26 -12180B467359D44B592BC4679DBE01856CE65D2E0FAC04DED5207CAF770198827720A708 -E0667AD7A3EE70879A25C40D468E307E01C4EA8B0FB67A854674010A90CC42CD6821F717 -19055EAB05AF9C9856C6FB31850960CDFF7CBA473C4098A45A1E15C533182D146B64D9D1 -BCC4EBE36F926B2D4BCA8737364CA448CEE8A27610425E06420404B99D7C2FF4E02A90F8 -583262933685471C74FC236671D814DE1F3016BBBEB1780E4DE6489CD71F5DC6DC2BCAD8 -D742B695074F28EB6A91DA6977D8BFEE0A7012DF751455F36459FDD63FE1D1317858A2A0 -EBCC845331CB6BC509661F464ABB2B3341D1AF150993D73D547DBE8E13A249B4CE85D9D8 -3F35B2B7AA450CE28CD22F826F69F7B1F7AC8D802D97FB20536ABDF8CD275E67C22674B3 -1C6B69C7C8410B93FA3FD167764F2DE0DB966B9BAE9168554D718E00A5017263D49F1CA3 -443F1C126EA11DE16A4D19BFC9BB8AC52A5471D755EBD49B535760254143E163B22940A8 -0F2AC318C264DCCEF794B02CE91CFFD152416C37AF6F7F1D151F4143FB808D10D635E811 -CBFEB3EF3C291F8CA480769FA0D3D80E1ABB4199DE5EDDFCF720D95B1F7E57B80D529A22 -49AE1E2DDCDD4CFB478E88CA5EDC7C4A97B7BF8D1DB4CF194227B699D1A5884FA7163E87 -7117F2A46897135F0202B6AD25EA7BE2AAFC933D1E3761F0DA9432A72BF4FA0755CF555B -7DC892A63879333E1D5C4614215138BD11967D5746163ADF35C13D81DDC09045989E9AFB -668CD3E34572836F7ED5981CE6ED895DBD5B7BB1AC7BD9A4A197FF9C400050A97F8684A5 -E9732512D1BA6C9F4EB27773CED4ED9E63DDE7DE003BA708798235CF66D0C7517AEDDBAB -F667F6AFC423511BC344A8CF07EB7C697072B9CDB4958C40685DD2C6317B20ED0CE5DF6C -204B8029D48783B1AE8EF5FABFFAFBB42BE9D26B4840C04FCF826CF6168DC1533BBD3452 -7D2AE02FF4237675F45ECF4C1994D45E0A15E6D03A3E399BF9B0821AACB73329636833A8 -B4937F8DF6DC557D20FB4C1A33D7E7A2411BF35BB0888ECBBAFC4F1DDDFDF71BCC627304 -C4F92B71BFF5D96A822DC9C71687C1FD37299C4BB76B7F2343741882ED86E05FDFD97CC8 -76EEEE402AC25F9B5945C48629A605632DB0E7D210CAE8C887718F10FF689AF3BC23E960 -A1872ADD99BDCB14CB388B4BED0C9730947ED47775DC9A2B028778ADD281B8A7107C7348 -FF35B6403BFBDBC3AEE99D2DF222D796BE4EEE6071ECA471DB5740647D136B49D2FA83EC -7C12E402BCBE75C7BE2CB2C058D041A3A390D60165866D1B84A5A21AD65E5B7313071ED0 -CF488AD4CB6D7BC4CE06B620262D4C3952BC443E10EEEF07FE3A1CC72F2921AFA14CE11A -40655EF499B2FEBAB39B530BB27682D3618705104D6A781ED1463EF6217F8DA8DB308E47 -2654FB4A1F5CB5A147B50FE10357E109DCFF49AC818F53621619B37A9FC57A5DAB97F829 -82D2A91D92888851F9C58DB754808668EA721894C859EBB4E09123B8E21AF0D4ED31092B -1E866C80FA135E73CB59677CD3E74925A82A6E8AB6A1E28E1735E2BBA3B79CC8D1D6531E -A41214CB887AA60C94B642AC36F9720A420E64F321A474FBB57576C2B0155450B51EB175 -D39DA3945AD41ACDB958DE15C25913F7C3D7C0AE3A6CB987835B26DEE2F92FB85E7B872F -1035CC7E7332A9418126BD493C892033FEB7A254B47623F8645C52D240C70F1FEDA77C1F -87A90806E9AAEF356EAC0758714EC5018B1B481B79B416A2D6DC92D7B22AE75894517C16 -C3DD09C667BBCBDD6C3D36AB00B636323B2B6116125F6319FB4C16A57764E8B879086C2D -F146DF03073509C72932A516FD7BF9F9B1936B643201F590D1D551C2C5D48BDC93785B5E -67F1E6EC0A5D14D59A190CF6894060C1953D2DB3C79F48844F7A0B0F0FDC3AEA8A53E33D -577B67E9213ABFB350929FEB36A97DE7658B441CBAB1F0E26B3FC5612202817A5C2F423A -AE4430703E9FEA99B861C4A8CC09F79AC6E6F53DCCEB0EE7847CBF73ECF35D4F5530082D -1AF3AC71BC3918496CE6AABC23D61A98D11BC6D7B40885FB6FF6AC67ECF47C6733390DCF -A88F9B9326B5D130874910D3E479ADA40777274C02847ACEF3AEE8E0DA0434C9B35859C0 -3D23BFCB376446EA2DE09F42AC3713F0673D7DE567E8A0A1B15A1DC88FC081530804B744 -2B0681289D586D9757631803ABE18DEAE727DBE5DC052A0A1F0E70480DA458FA96A010B9 -57E4D1CB0085713817AFEA72535EC98D71B4B9ECEBE04C51974D94F874B0E3E74D149C96 -BEB4CBDC17D81564C3C84A14F5130A08AC7B71F1A2B81CFF6682062EC4DC6D8E1BDC312E -ED6ACE315A2A28C772216C052947E079071314DD07BB321F1EC8322F00CE57D3B0E53E6A -7A2B9002F1ED47621CC255EAB1F3152D5CF2456764014A5DE60DD0CEBED98B584457377B -F67065F706978C6AA2914A68A942DF2B2742622007655BA8780AEF5086CE17B67B8B3AA7 -E432EAE81226FF8CEC95D0498BCC0FE737DEE690FEC30B80F8DD74F05B9B88794A54611B -C12F61CF8BBDD49F33C5690E1F03DE89937040BA0775FAEC6ED05026ECC6DC4D0A0EB441 -66ABCC55B3194DFC9213025725A8EA81A3290031FC365D3741922FA26E1499B93C2B59A4 -BC226A3F86FF1551DAB5F9F850ACD311DF36EE86E5B3EAA4579972223DAAF9E475F9BDA8 -4D95A89DBE06611D73BF0717D1FE0258086C1B97103CB62D8DCEA974B41388C00F176979 -E8EFBCF4FFE9144820AF24BCC47EE0597276455F92BD1FA21FE19E1D98E6E8D6BDD6AFAB -E61C7B650C109A61E1A3C6E92A6F2BD8C872A32DB437E2EFA5A19641608CF2D5E109952F -8B2D9C0F0B96322665B1698490E37E860900EC392CD42DD9AA6DE6F0E5A5EE7BCD34A538 -95D129885A10D9446993F5CFB6978DBA5B9BAB29773756B9867E4A2561AEA643414BA7E6 -00DA0932D0252E094EEFE73E2AB163397C2266CEC81ED1CB7724335E1FDE7CD753646810 -F94A631F2DCCED349080D4E9BA7E9585E3F52F77114012C081C806A447BA8AE735E406BC -532B46F55134817DC0B30496C6F5367A4DDB55FE033A236404D643C4C3DDF9D8DAC0F165 -C2B8BDA4194795FF0146830C21CC1E991300548E7A0A0B032BFBD828A960FCE987A5ACB5 -E2224DCCE6CEA1F7C6BE69248B6044ED317F1F3C028142B52DD60DDEA986214D93685E9A -F3A2D9F7899A614FB41BAE93640B9BD10CC3981505415BD61325AE4E2EDF73E7AFDBDA1A -D4DD09F759787DA42A474F1B6C134AA6FEE8CB1B5BE1E9AC6AA2D1E60F7FE74EB2FAE2A6 -BD8874F746D14A51F860741F5DCB208C461F8118A4741573CE37DFC57E8B6EEB1D369758 -7956D6255ABB0E047F04D5AF7E59DF62EE011BCB403ABE71C63490F9E3F28096149F866B -480EC82AB9BCF835EDB42F72B33526DC06CA515920C92FF73CA0C1A1F1F61FE8F373C486 -5DF775DAF6C7BE60F2DD4232B73801BE6BC491FA63205730E4974A531F1E75E74A9ACD2E -D4A9A9A45FEEA8414614B535372F94E55BF70152086AD2738807B85E0ABB2F5AF149C8C9 -9A9F38A6CF85E31358F8846145F428A89DA1C26DAFCFACAE7992CAC52BE50FBE0EE43CBB -2228490A00E9716E513C434DFDFC38263D773404743713BB490DE92A2C4F3E2E67032D40 -B31649A0672EB3E41079316EF1020DEE6DC23B95B093FBB87A0A88733645423F72CFCA9B -4B499F178EE31E5C8B8D432D5872CDC09713CF21DAAC84AFC235E8AF0F8DD6D6CE213937 -7314BABC357F9DDE5B3F2EF4843827A6F0D1DE9C8D0DB30E14F9C94FBA3A7726D6479706 -162D0071B70C19CF32BC2FD0113504C82EEC7669A66331267B4EB18C5F1902B6B2C78C3A -86E5AA1D2BEBB6AD05539A612C230DA216C24B40029A8CD96B8FF0FF000E816B6A7C4F70 -90E217124A1D6A78604D5A340C278BA9B16CD4B5518E0376B3C518E1493AFA9FDF83C36F -6F28785DEA18DD992EA6C2909ED188A31E933A0F5B521ED9C46E7A70BAD32D05AFDC381C -9EA3D56E2E8C48276A82F9EC08440D6468D0DE0577EA8D5171B678F3AC9F3BE2D5DC899A -4D945959C9990F334EEB92F34B88F256FFA564C591D5B18F79BCF9817E827BE4BA219423 -252095B90DB4347B2D54F2BE6D31B87B525D103680700F13CC1C0F72B0DCCFDC01F2E924 -B5E1442F21025659C39289B7B4AF03169F584C49D38EAC00B1910B823745054F00B322CD -174BE2AB28915D81A829B6C87486ED7EA4D44D6EDB6BD69C25112E0387FE9826C0F3F2BA -D1C6BE26E603730DF1C4CB227936404E138136082AD61492923E173484955187CE3DE172 -0FCDFE244D85D3C5716B7A4338A8130748567E0044D3D9DAD19A9785272819ADC5CC9876 -B764CA881499268F67D6FE0ED4C73D463BA920F27CC02D187573082A1793D228D2011E2F -59A15D7349B2EE7C9E7BE1AC231DCBE9DC98A2796F5FD4A5853B8BAF6F266520CEA0C42B -0AA848B977E9FBB93F77CC2F6224A339242BA2D7CC565373E3636DC0CFAD06B7C5C8FF10 -392C03A29675102DAA1E7BD4D45A2BCB6F6C73F8C3A6DA9D520F858EE0E4028FF39A7C8E -AD10A54E91112AD1A6BB7DFF7D3421533DE306FD859D5F750268EF950F4CBA3623B38703 -1FE153AB39B304EC57FC95710ADFFCAC53508224A7DFFF79AB8A24E4DF0846926EA4CDD5 -665E4F1734764B53C911EE8AB436EA08ABF1FC7BDFDD754D22C6CDD1D6EF1786C10688E2 -E2830A80A5AA37C08D1545C24EEA559618C927E4E5A1D6F83CE3CC7B100D4E04561B1BA3 -08A400644C6B49F4D5AA8EC1B5D769D16B28E1FB6DB45B118FD348D2A6F241766EC0BA04 -DD24F51F3F288D954D2C7E3B402361D6343C5A26F78D2C220E83D33662BB0CD33D84209F -7AED4D30489645AE647D045AB0BD56E20943BBC8642B2DCDDC09F955EFCD74F04337A15B -9DC924D48D1AF6AE222B76563139CC37966D32937FC5BA436843EB57761B9F052B0BE1F7 -132E40D0F0C783CC80B728B75FB600127673C0FFC2838A8B52AA3C957E978000314DC091 -9D1DE4DCF84280D7939ACCAAA46ED513080442D497C7CBB2EF36C43CB3BD66844691DB7B -2F1ACF8D9695E03F747E3C0CDC2105871F13D27C3FA07E30A27F5414960DC3A51AC1B569 -F30811EC03218F259BA3E4668F83F6670968C7DFB3E7CFF0D12CE126E4C27DE03595C823 -528C95F4B1C92AE796CD890EBE3DA9746B92A835817B6EAA2FCD276A77436225C44E89B3 -6A0066BB7AA1E94C3203AB45A6E2DAA5DEA3B0F0E068A251CBBF98D376CF76ECBEBCF3E2 -1F375D73BC558151341B01B27E16ABCD30F60FF9A91AF52808606625051C54ECFDD28E8C -90E211E0174A616C68BFC718DDF2656FA27BE3DF485F050BB57F96B7D1F6531CB2B73B46 -D21629F201D40C5A37B572428805651E2EC179424D8F5251A84384783A83D2C89B6833D6 -D0697FFEEEBFEA9C8CA21A627F50A1168EDE8C5E085B5930192973DD939E36F10AD90B9F -C02C0B116F922ABDB2A94213E4D9AB7903770FE69017FA7B28894A5CC4C66930FA7FE05D -35D664AFD098B8A76C9F2EF0A11E36B6D7362B62205AC9282D8082C15E1BA41E8A711DA1 -CFD28A83BEB3ACA3F7095FCE5880F18EE93F9EE03C706AF5547B198B4A08B9731A61141C -9A953B2A5A3DFEDA3545EAC5D7D8D556E72118187899AD1D13D51B44F1E422F4809BF42D -FF01E2F05B9BF68849A398CFC799771C1AFC256B7D333549A0A71FB7A8813D5028BB8F2F -397C1A68F22F3F1B9C2B7C2D4F4EB721E73D6E63BA651C802CE8E57F5CAE8C1F6C4AAEF7 -BFE00547D8344D7741BAE7BA30F21197146C8B31523C1C651420D130A2DBC055FD437CD4 -D92E7DD74D6F1A1027CC95CC028F44F2C5B95E72CD31F200B0A3584946E55B9A6A20163A -3EC73566552D848290C8EE0C821F08DC9F1AD94C9E94E8C5B865BEBE2047092AFCF291BC -EE941AF3156D6C8AE07E63B81F27937759F91A6C8795051BFC02164475850E295E6F40E8 -4DEC3874F6762DCDE08F738816A14E5D5423590D87B85F7E0E88EA234561903039FBC1F7 -70ED97405878F62A7AA078601FF5277CAAE4722171DF7954AF82DB007C56E59A7A59F133 -071E193E18D2D24EFBA31F3E598B9FDE11C0416579BA3AF70C8F7F0D069C3BF3FDCA150D -ECD1E82A3D7E1C11F13D37F27CA578A761A9E5EE2B425EAEB8298120429D457998BCD81E -81531F1F23CC05417FD802E9C1B7FA92F129CDB8F498C78F9B936FBDB2EBEE402AC25BF3 -CED327EACFFAFB1619E023F018E22F30FAB458228AFFC545AB15D66D4A0B08716E484F4C -FF688C67B70B3878ED20939A1EDFDF9D62FF19EBD66C9FEA31F18B6221208CF315DF5108 -CE58848845FE2386F9F916108102A8EEA1E6A4806535410FAC7AD182F6F317E0A864DA31 -35FB3C0802E830A039535E66BB3ADCEC299454B7966FEAA81861965F79C0578D5D48F3FE -5FBAD2239BBF5F107E5FF42EE8EF094D8586E8810522BAA1E231B4FBDD6CF6C62D3B36AA -8477D9273E95D66CF67F5061EB4E3EC2048518063703DFB7EFF5C2F5A3968FAA705225FE -9E088D592EEB980C54777F46BB385CD979BBFC34F3870583C13643D449A49D275E38FB4E -A31E0C69CC3CD31BD790FD0960EEE331BC1C7D47AEE5ECD11D6EF0FDAFFD1FA2C0F33C85 -31357F04EFCD25B6CA2E0800E7CC8B467D4EC22FCE69FA0F1245253B8B3E842C10276456 -ED5D4BA9B19B07B8AE60115D4F423228878C7E6461523A102F03E2C997C826B0E01A8C74 -737BBFCC420E2A864B051B219EB2F65AF711C8034EE858E8E41E93E80D519D7D5B78FDD0 -E4BC44CB9657C8DD9C37EB9ADC2E33E42B02DA3E069B9B20D7A727DE8070E17FB032C9C3 -4F5623EBABB58EE9097C85E0A2D93279EB7F6CCFB82CC798F06208D106AE7E811BB77F43 -E4F96EBDB0E29E9CC6CFFA79A00837A14A424A9E97B16F52CE9C0068C43523E286038ED8 -D91087DD7764B1DCC9FB73CB72A1AAFC3A09D353C64A8E3480D2C3E9D1F583E2437BC1C0 -529AE01639F1CB00AF09CFD84C38037DA70512DCB7242EA3BDADF8429ADEB743E5509292 -37BA921D7AEBE87A100E99B0D806D0AA4B3BA6740FBDAB5D1E0FE3716EE4957BDA0258F2 -70B527DFB9E2FE35FB0A6AB0FFB583B9529FB51BF336852ED0D4135E6408AD228714EA74 -D76CA630E0AE366233CD90CD586C9D8031173646A78B88F1F88B409110801D522DDE383E -93675E5993EC6C007C5ACF1AA8D0F10A85A144E189273AC6E135E986EBC2A85074D3C290 -1AD3BA21B44827EC7A55EFD8A429FDA1DAD0929E86FA7692CC46E7B312B441806598F2FD -6090A17540D1140AE17D9A96678347EFDF0B510A8BD31A07F26FDE43A5E012D76BB72FD8 -8A70CFE950A471C724288EA13FCF2A5A7A3D54B2D30BAAACDC818C588BDE628B30011DC2 -5CCFC66F6C7C5F780280D8E4C421A0C30749C2B33EB4AB3882CF161E116498C4204455C5 -B70C59800A0530493F63B843B3BCAAC5F025163431DF3FF39FF9330084D41A696DB77343 -7C3DBD4E794431B80E72838210F2BFDEA75DDE26997A6F28065DEAF13EB71B0B098C8209 -3121ECFE486A0CC366FD76927D530C3448FA16790C4A96F66274D5E7A71427AF984C5004 -620F3011223C4556D8D996A9415812F1868EC9744B1101FFD7876B0F0765CCA2E7BFCEFE -6AE75779A6AC7876D5435153A48C4B931D23F7AF10A71532249DD0BB4F52514EB90B98BA -7EFCB01C47BE21CF5C2C82827AECAB3666D9DB46D415C31870CC7934BA73C5736117F639 -45883151F82A1728E5E591DACEFFC0AEE8E0234EE158F45F8CE995953F2D52D0DB5D23F6 -E02079E115F3844925501E263EA3EA7C364DDB44BA125796D630202D46DE831E5FCA2BF2 -8709E4C2A8139444CB401254A0149E4DCBC69AE1438FDC782A6DD7D08134A27C1C32033D -B1707A8CB8F458B3FAC6643712117752FCBC008F2EEEA842035EDD4E50DFF848E20201AB -074E662074C5F57290E7FE6EC37D5C1C11EE8DCAD4BB3CFEF95193F16A3AC6CBE11EC609 -111C0C056856B5CBC8C5F59CE7FB37CD8F3B53FE0EE6DCAAF3C933B849FD60852EEADBEA -C506630B94EB9814AD4A9D31D2F355A3A176685CED59E6F2A6F61458311635006CCA9833 -BE5552DEA87A360F2FE23679A8C5E05A5A8C395FA909C7BC287C6587D2BA7C4C22DC3396 -0BCD0B32BA37DC1C1F59E730B8F1ED109E215993B16FA35C7859B8F8F299449CE26091CC -5E9A4893D1D1AC688865BEBC3805855B245A9E90F715B904B9761E3EFC7676E9DB688EAE -D6C5470282E8F065A2CF7CBE00FA66260F1AE895921852BBE6CCC06732EF7290620A1371 -3C98977827D534617AA33769F4A89CE899D29A6048516B0B9E764C4B7A668470CC188EBF -54D31E95714E4F85F3EEDD46DF34786702A088B30A31D55BBF6EC09153F5A170E28FC2C9 -F39EC3EC34BE68B1B13F39C7138B176B064210B8751043F03C35601891F31570D77B94FD -05420F77B5BBF0F15B62C06CD8E026D7402D53D5455D608D9A903482DF22066AA82B0927 -918EFC606CEA50534BBC94269A487505D937C2A0FA09DA28BA69A0B90EA305CA02332254 -5AABC58727B5169F010548A30B750484B8A6F33BFD0026BED604C56CE9CD713A05FD9816 -C1A8CF1FFE9A458AD7A3A0B0F4FD0E506608C58669AB9809DAE774920917406CA8E68F9B -E4C6B9D36C0A31494625FDF84661D20DB004C8E6C1CE34646992D7A2780AA7BD04B7C15D -8A696817A5D5F4A00D9C25E6695C383C273877B1F75544713AA173E9892ECFF80CF54382 -02A2513C677A4AF1C3BFF5B282C807A77F222ACF5AC497A36DF8BA7C537391827360220B -40F2AF6FCD3D3A9EB8847899F3FEEBCE598050D7CE593565F3CDDA813453B62983C0D90B -71BFE793AA1B2F0CE07F43C8D4DD8BF656EEF5C6C3CF0FE90C9891344FE3F4644ED8E98F -6C1E8C00726BC7B8D2AA8AD0681339EBD2B1BE983E36988BB22257DC27CE5E183AABA617 -D9AF549235E8EC30B37B85BC3F371764AED219FACE0CFEACF611FEFAB312466E6C02B341 -904ADF69B17706D8AB2EA734D8895813DF940ADD72547D373DCF82D1C484D7544B06AD93 -3C4D95655ACBF08429DC60D26DD8690BB9B865D0846FC0D32117612B8A8DA0D6955B38E6 -7B7EB2405F7177097ADD4CF54475866A52BB7FB9DBF8055D96586EC8C634DF0768B27E29 -92CA552A1E4B920C56DBF6E6C03A74745A0AF944DCE92093C8BAAED7B40F2185D776081F -5B3049BDF295D0C4EEC9E3CC12F9B19922A76724879D842C1851C16A9447296DDD5096FF -804D0DEA8530DC5D0AFAFFEEEC6B3057F16FADE808E85040E4275FA41A9B7770048508AC -6AAC18540E2D903789AEA54DE0AFD72E582F596734D44EE33A9A719620F0B17FF028CCC9 -A1DDC29D41D9714C27CCC48A06A49551D8F5754D8AAE52D92D31269C9696924D52A44EC3 -D483A0849738125FEE094ACDC8C09574D7FB5FDAAE0F44497115EF7C152453BF1B6EAD42 -44B784EB072BBBAAF2962F61879D74D8850B1C544ED2AD2483EC46F99CA7E5A281C38C40 -A5BFAB0500A37CADA0FA0DCD05838A4180C0DD8AABAE616FDA7CD77572EBAB61656158D2 -C27C2DA43871390F39B4D3E193CF95C19D2D2B8072857284405C68F5AE101A49F786502B -8040587DC7E2AD00DF02504FB119202E0FDFDE2DE00D4AFB2B67C8DAC5838050CF1C2D19 -C2D2F17FDA9BB90DA4F6DA74DCED5972E2F8221EA6A0AAE477190CF01D645D452F0E477D -436DFB6EFF88407904DD172E6CA5E132CBEDE212BEE43C446CEBBCC250D13467915BFAAC -24AE63D231CB519A0007AECCD201482201282B6C7BB3C4C45392D32D5E6F0A673FB8C27B -D70813CBB4285D3755BE80CA5EFF3B8CC0738C090F535004A14D6EEA4B56CDB2E70DD71F -98DB9A8041A2F80882BC5EA1AC8661C20632CA27198917A619646193B4A3EDD8CFA675EF -5F83AF3D18735EB811698BA7EB58563F0C706A2DC7D372369CE227DE737713C18948DC20 -5D9E574513D54ACF922CC559100D90AA3439E5B3D02E0ED2EA9005F75BF378CEFE680D93 -CDEA6ECCC4B3F43CA57B128FFD4ACF5020CA5258B2A03AB259EEE34B80590D44F58F3D18 -7190011DDC9B6FE1F5D9D8F1090EE4BDB4FB56272C579E33C7A3ED0AB39D96C1AA74E197 -7F30423B3E2AC868292F70B3DC9D2A1FEEE89FF3BBBB195E409C5F473BCDFE107769B6EF -E8371487FD8408D67313A1E0A6E2E448A0321C0FC931AFEABC4F648E4185DAC8DFA30D9A -87C0380046D38FBDBCA63BD498FF6F96FB141AC9D0CCF2D58971BDA0703CB600FEC9C22C -781DD3CF1D0604930CA0D8D9C35C247643892A82095F9F12196EBF4638132CC259278A69 -6BE54B1BA1B56DB1EE0F1C8FE42989AF69E38473B2A4317356A415E1FCCAB2463C80B5F9 -185D0B49D4188DE1B620BA6D108F3D3732BF34FAB723C1373FE6440296A18732444F56D2 -2E4666EB01FD9E25BB52F399EF53375C9280D7F6C3E774A8FE3EAA78EED6A94F85089E6C -FDDAAE0774DD926D148BFDA4563FDFFE56AEE78D03B9BADC66DF13351F3538D6220D5D3B -814D6F55C97A4509358DA25B47CB33923506BFE54ABC45FFCE8B35EC6EC9B5EF3AD16EBF -9FC871736AE364350BCE0C88152854A653BAC1ACA37600276DFBF99E9BB4B19E90A6F234 -A11071922039565046DB5A6912908CB86AD30FD7FE3660C06F05554A0C970AE20BB57E92 -448EBC532764FCCD1FD1F8B7E10FD0EA90E043C3064B246CF3E2299BCD5FCBB0B8BA8C1F -7A78688A0AE89D73DA9E7D94B20A3566F0870462FC72C6D7390CB82761F428AE82DDBB9B -DDEB99B653807E6257A2DB61EA8F4FB2C1D133EB3D8D6DDAD980E5DC555C4183B6F1C380 -B932C33ED0AF6426372558F6E01186A41CB25FB6CEA786229ACB9E61A133E138685C485F -505EEA8B5BCB465E5A697E2D6AFFDF040CCC78B8A7DD2F76EFCD0ECB1DB60B7F6996A75A -A0059F9458D34FB95925FFF126E616B6FF585B566CB41926564D8BD98D8353DF5725E722 -86E1B9D1DF3644A4C45E3318ED821CE90B2D0495E97C5033C8733756CD10C763C2BC5CD8 -0EE9043A531A0DE7DCE115224D0E272AD0CA70D3E206B070728E093BA13F03E8D419E50F -F85B3DAED2E7A581948541410B2469172006F0C24854049C0180D0DF6686E314757D9D4A -7F6D641D499DF6550A60ABA333DB90F4615BACB3C808FF6F58272CC252236B29FC67FFCA -5ED9063DF8100D915C5B8F10D7B1AD3E848E797F82E9B76786A4524AC083B09D91396DB9 -05F133D6E300AA5FFB1E1D161D00B4CBB09DFEB87CDA9527A23FD4591E2DF7E920A3F4F4 -26A7D3AB614E8D45DB0399550E166F01C4C4F660430642F813212E24C7CB24CBA11EBAA7 -B9F63BB00955F125A92658AFAC7044896843138F90299686F549A427A542B2588230C21A -09938ED97A7A6382FC70174F303673CE2AE93D8103F5E633298E1DA2C36908F6F6039FD8 -37747FDE7F714A66CD8871AEF65B8A68529FD63F87AF84F3AD411F820AE9BCB84A7EA4F4 -3838492DC675D80FD615CFC9D6EA741C6B91AB432C0CBFE06FFCC562D71C6440176F39F5 -3D810FD4D3810E22089724E8A7F53D295681C2E07334D656EA4D3F7AD037D3B9C760042F -86A0E2240343EFCAC8E2578DB30BECDF093CFBD0056110EF5834A1E683CD7D624B04AC43 -A663469E0D3AAEF64944EF7C43F8FBA221DC846E86A8866AC53384FD35D10FCF34EB7404 -BB38289451048BBBE520F6018C3F3B8F6FF3FDE4C5F33D89E44DBAF04AC4FC17A4196676 -F16B8A2F02FAC4B8933CE617FDF903113354619906A8637566B3E61FA8C849261A625CBD -87BA5F1EC6479E7B9423BA14D9CA0C68E11BEAF1D1E948DE44257986388E75DB6FD9AE41 -13C36EA637EBD0812F272EB8381437855C7B0F262728CC886BCB624437F8CA30F107427C -7D1103CB94B19CB2129FD2B388D62CAD6078EB7528810DC458907A14EA0CA0B0C28DABCD -988174387FC28FF98B7C9BCCEFA0407D138828621AF7815C13EC04F7FCAF82ACD3E8E773 -B886BBBE2C4F2818E39A2D7F964A29B9E977F53C7107EB586D628F85798E70489189808E -159E28A8D81FF9D642F3FA4FFDC2059947719184D1E83FD5EEAC7FEFD5DE2DFA8D808AAE -91FE63E94AAFAE17FEDDE11C1EE21085438581DE1F5EABB4FD2A2C3CE0010492612F5797 -163F19DCA534DDF49FB45D0381664FE5CDEF1CD0C319B6748AC4B8996DED871EECB3E223 -8E924F30CE315DEC278EB94C6206951B2D4E735463650B5020CA8CBC756618AE1D8781D7 -B22ADE2D20CF71A9ED08111EAAF4E3DB1F081CE992ED1F7BFFF2B883EFD95F51CE612CE5 -6588D7A8F342EFB74A989AAA55ABCE83A773333315FAF1AEF25CDC4F19FD2293A51AD64D -A070635BE2763AEC91BE2DC9F233D8968860E76352E6DA9F7E5EAF068E19CF1DDB22EB76 -FBE149738F247F4369273B6A901705B7DB396F662986D91803DE93D89B8312826CAF94A7 -80EB2EF254FD8F19710452E7EA41399D50177F4A8CD017EA2446C1295B6C1598BCF35060 -4288FB0A9C7CBE9D94E6517CECA11528D286CFBF0D621DA7D93C7D1029FE0C70F20ADA26 -E05A67C4E301A086770130934D6ADD3419070C6E2F0173AE4DA51F478DE9BBE3687D09A3 -A48D7FFCA601801BA38BB9D87F091DD410BD354C24C74E2E049407B8A3A98F90FFA8327A -6260CEEC0D9CFCB9BD04C3C08FEA15D0884A9017E239335985C85E17697F874DD3EDC192 -AB8542A11C8B5F50A2B737F27E9A4078D72ED0656D5AFD0EB04F76565CA2777930DC4B0E -62715FE6D2A8A78D8C0187FFF43BF6C434DBB5DB369F4045558E5F4F047554D4641D02DE -A9A78C9B3B64D32D3415CA488D399273879BB9BA3EB375F630F273DAB8EDC0B015A3728E -B55013B32BE513A0AC4769876686C9816035C2D199E955DF7A99CC07B680229F2E9C4302 -D5F7F4DD4B9C3BD69982E0DD8699EDC973E55A259376CBABBED36F28024A9EA504154EEF -B9F2C5649E7338C52CD19690D7BC56CD06D5882366EE32FE4B56D7703237F3D38A4D5C07 -F4B851534F597A1723BD364620757118169DFEA997B90D243990C23B6583EAA176021C29 -923483CC99E04537F611D02C44E99A05FA78A0EF13F05F695F38E3E631750BC0427F162D -96057F1A50A392131DD979868B617C037D26CB9A92F478C57E822C3E946B1A30388A3813 -39C0A4215EE9314A42BED741A0345B13D16F462E60E493EB57A775B3A01EBE558F8423B3 -047BCA02DCD80CD35A3AD41ACB26D75C92B1DEFF4CE5E8A8332AA185DF670FA87410E36C -D27F4064090E39970DE94F2A9476DFAA41225BB65C0103F5F2F277F932CB3B1F273464F3 -1C6E88064995D7C6DDA4C597ED8C8AA2174DD99D8769F818CBD824E04EB3458DD29A78B4 -1BACA60903E1BC1AC6527351EE55A550CF7BB448C3926E5AB461E374AAEBF86885B8D912 -23108CA0D5D57C333DFE6EAF41FB5C7071B83EDA33362E2090A76DF9832BB5DF1E3AAFFE -135801E3634415E1E8A561360B599DDC5F84F3DC12E3A4DA3E325A67DB748F6768D42289 -0520E9FCA4928178B888C4BB626D82D9B52DD2A8558BE9A3013B4492CD8F11CD4B8CA79D -771D9A9127EB7D3F8AC0E09CF86F94AE011B568EC3A12B6C8B930084C0982FF9400E5308 -23E79DE9CE44B754947CF6EB96BB9C9FA45869AEFC46A19F957B677E93E25D7CCECA4389 -35D70BC5C89EA5E2D1BC207365D7950B8227E70D4CBF3613A1ED87A7CF85485DAB70AC0F -3CD67859B72D6384000CA9B3831D32CC774B27AC9A2C21A4CAFD3493A2BFC37464066BA3 -4A4BB4BAFA36019452F8A580C4F27BB5D81BDFD8902B510FE95DDB23CC43AAF71E464CB1 -AA6120E3CC15775000BFD24AD031F000F787696A6A6FE9F2EB409B259E706BC64E2BB7A3 -286718CFDD3D1D2F3BBE7218949E69815A570AA59CE6545BC1A2036381515AD097A81D2F -51AC22395AECC7D208F77CA9ECF5F2C121A7854AEF87CD2170A1F9F7FE9657F2C5C77344 -F7F07A90FC698A63382D7E59D7EBC856553BC2C821A6664E3BFFF963C3671EB7CD32C9F5 -AAD7CF79F066B847C533DE4298824AF0DB3C96B780358DAD0F71CAA85AA876EE8C056864 -FC9F11FBAD9D966AC00667AE21F9DA3555D55D81283142FF4071541CEF9C87882323BC72 -454D5261D13BC65EC5113899474CFD4C05D13D8FCB5F3A49A4967B8C46817DA1E71F7EDF -3FC7375ADA580A715D37FB8D56B2A9EE3296D302AC10A9C5AF7DB8E92C39EFBDCF74D102 -C9939DB7F7C2293A9BF92E3A81C2A17B1C2048150935B977B85EB6AFBFA266ADF1D7CDE5 -8EEADD8B2D7D2EE4D9FF56CDD2CB1CBDBE229B03353D7370F9149ACBF086403B96B6E859 -952A34C0B58B4891E029FC505417DA6175CC8786CD4326548C65941E17587AAEF46006AA -01599C4D9C3D66BC8F7776B38822AABEC1D52E1B29702C498D6583AA9BC40F656DD6F74D -0528F562A31E90F620B7E96FAEA15F1F2F0B68FDDDB00D9FFCDB10635AA54C47AEB4FF60 -EB3E40FC4F82A0F73B8440023753309E443CA66CBB5C02CF7D77DDC5917078EDCF50BDEF -1341027323183AD881EEB8CE2CE4B983C611508E8911F098ED89DBF2ABBA49F1E7DDBE0D -6BFC1EE74A839F7CCCCF4A12339519C2EFDA56941A74044CF1B0222361ADF02CADA96F2B -94AF954304B3CB7635C2E7E6BABDAAD0CADF6127F63A07BE097E6C7FF598272D39D3EC65 -4EC2E9B795C1E6A65C50AC1D540130B16DB5D763B9923DAD3CC2D8DBA1D3D2158C01EF3D -0F41E368C49FE8AB6DE7774CEB1134B1FED9E8911F9C2F29B8A65D2F030B966444B96EA3 -48E804BB6343A01E2A5A4B3A39EDAC4EC5A8F9F8BCB4377B0A10820E5B5FCD84A1343A02 -CADC1D5EC78CEDA3EEBC08E795D41C30390EDDB0D6228C706CF39C2989618E1A2C86FE80 -32E093F244E65BBD5AE8EEB19AFA5EC0717D5A0365890E707DC35B2B56187314BC1EE8AA -F3CF2A8E90B5A04CC30BEA3E50101256E48D0DDAE0E8DE05D62DC3AF06655AE331010C67 -EF2377D07B7075866B905644D7003205A1D9380B56386E291962F5A8CC209C4D540CE82A -02B4E654BD66EDEF1DA488CF02B1F37ACA1566F5FF3E4A25E9DC0FBE6F1CCBF4315DB6EB -F3027B8751BA5BE3E68C3B428012CDD1F23ED25C9F09B53321698639D37C581873723846 -06606C0B4E522B57B592A205EA908633A20BBFE46689A9C749FCB2C1BA5D4B3EC7DBF4FA -C810240BD7D2CBF721EA3F824497D9B105348C6DF4E964AADFF293FB406A4678D7E1CD5D -24E189EAEA1CF128CAC24C3764922AC24104808451776ADDF427A8E1DE5227B82546F1CC -8FD56C60EA96726924AD39459785E481A86C59E43F2964C332FAF11BEB87EA9F7CB71920 -1E31DB06A94C12CFCFC4CB0E5925B81BD827842A8FF3021BCB63E9CE7BF8984006062267 -DB5F53DCFF1F1C08E053020257982E81CD41F6D55D6DC148CE7E1588146E2E7A721E0C63 -4451BA6D6B0BA5E1434EA112CBC5BC508BAC211A55498D30FEE9DA4BB5D39E19767CE082 -CE5E2737B404708070E8E6F325D8E9A705398C4D2704CD50AB6567411B18D49F2D55D690 -CBB1B4D50EF9893F8071E8423DEC6A6738A92E527446549C87D4BE374C6BAB141331BE47 -B0A1415937AF7A047BF16B2AEFAFEDF28D15B66C241E346884870E8F3ADCAE8A1403CC77 -1EBDBA2F12EC4BC01547238E69EEE4B08FBFAFC2E81CDE882C9D7558501B0BC04175CA89 -D1EA401ACD6AFC5AAC4128539AA1F3ABFA352F69A1322A7E505F68774598F26EF248F658 -D0EB1ED0278DC608903AE7D8DB3A2FFBB486057720D8F7B6039C2BD00FBD67B73E183EC0 -D539325173FE5D5F6443A6D98B967ADFF599124199825EC044717674D4EA3D0CB23058DF -D156708E37DA80BC192F0D51ACD25D144411F856E36B135403F818297025F27FBF7EEEED -1D964BD4F0BEA178AC1780B1FAC7D64C2BED556696F164B97CA0C400F8ECA0E508884249 -8F32B23F9AC97B52EC55580C0C7DF9EAA9B8DAAF266DC0A02C2F3AF10D756AFF097A7610 -9C299FDFFBAC8A6C3652285901A145DE49C093F4AC2BE72327C35E6F0756F18C9D219D28 -24230C2F226FB0E9E47291136B363658230009DD11F2A8F23BC2F90E7EBFB384E1BD8E75 -42295AE84096E3BCB7F7E7ECFB394FA8B2C9B4746455DB755A59613D085C34D07BCF89C7 -2EABB16DDBA4C2C09B48A5D21D75CD9529E4684F29479264C9DF6FF211B72559F0BE453C -C83C1FB4EAE42A8DBC18B2F0DA7DF4CEB2EA36129B469CB59D74C5A6897676B3855E9E28 -5F0BCD467538175CD6485237686CF42A046B714941BFC56FD1ABCDFD292B5368AE331149 -B401F69DD62B294FF941B1CCDDEC0DCD5507889C8310A6FB7D7F3A9F0713AF8E52A5077D -10ECCD6B5E24B260052A25E09C477D1F4A4710EF521C44F5765EF8DAEE3B7BA4E286D764 -59802F38D8E97D9A557963FCF5CE32A7DD5BF847703BC9314102928DA945BC4301440841 -94AB6BEB1EAF29A147BD1155D2A5E68517E4C347098D4D49AA10A359132C633B02E3AB33 -4BA68714EB41277EE78BDB1418DFC5A584F6541F3EC0EFC75E66263F61CF2DDDC5DE5648 -B14B8A275CAE0728A9B60FD75210FFB3EE02535815F68572A9C29DE316C7A6C991DA22B8 -08CD58C392DAA11A2390AD45CB6161063043C464DFEC11E8B068A0CF516E38BF736AA9FA -A03AE4EBC45C03A4064A4CF07B171499954D8F93A7598F3D51E953F91C7A70F35C88A384 -97839CB7F9CFCF788932B261AB359F8834660BB0CB5C69A4178BC3A6A98D6DB0C7C346F5 -E44ECE30B1C3E5EB4D203CED8B5DFB17F8211D672013A41F5760D90D593B7079D6F231D3 -03E9C3BFFFDF1E98B8F156BF47EF60F082FB02AB362582361B5274444E6C615A8ADAFA43 -71CBD86CAB86AA91D096EA244AF3C69C4A2F9D62A0F5BDB7649DEF309347F364469383E1 -4B72A52AB0B0DC030D8E785C81724959CD02E1BBDF43E6B92DCC1AB433576ED1F7B7157A -483C99F4662ECEE5116AFC2B28263AEAE6FC04C656B02E15D619275C7D79894320559E18 -B75EDEBFA7230375F5EB1A66DC3AFF798C6B67D05D8B49F28AEBB509364AFFA36EF12063 -8D958796CDB5409D5D3D8270B4E602A530EA46300695868F972A1E3764FD44BABAB416DB -AD0E3799FE67EA3A134F9841C79F89AF7FCF182A484627FC0A70A8528346E3C27F655232 -10ED76FDD4626CE3EC9F34F506F9A7F68C50B9434024B7C40A3D1ACE1E616694E442625B -FB49252EB156B12AACB84BB3985FBB8431A9BC0D1F071F7947ABC095FEB24EBDC9381FD4 -ED98028BE53D441AFA5534C9D27A3D21CCC2EA3B6A652E08CAD80B56751ECB06F18CC9B7 -CEC29919314FB5283AFE5A1951D3669B446F094550DAAD91C36CE3E5D30238C65D2E1D67 -5648C147047FDCF267AACDBBA50B1F9C7959C5F12DBB94B64FD02741211F297176F5F849 -412EDC12029643AE2AF2CAE8552C69A90BA2AB2DED3FC3D5D5E8987CB9B538FF90B693D4 -B842EF7D8AF1055F53FF8442AB5854E94BD016AD3F29CCE91F6D222C7E0D3EF3DE72AD41 -C2E179FC20B4E0E694E50082E944C77CA4D878BA6F19410FF616569C59E94AEC542AB9CE -BDBC0C9726DB1D56FE5B66463699266E4802B8572C7D2E45DAF827DC6FF7543A45A8B7FB -908AFA10A67EDA2CC08F677503D0D30D74BA3379234897DBAA955011163C4E0138858535 -1FFDBEB8804F00B6799ACE948E698EBBA5C391BA1D2FC74F20C448FC0BB8766BB3858B46 -2E06F751F2762A5B8DBC4D2B7B96FCB3EACB4757528964DC348C274F757178EB41BBDDE2 -E075E7F340C899F2253DA8D35B2C544792077D7CD7678698C2D8A3E36D440640FF920E74 -7036EE2E46227F170C5F311BA5D89C0EEEAE6BD2CD006C5D18BEEFD521894E5DD7E865A1 -B894E8D3E24AFC5A89D18773A7028DACEC61BDF9CFEA5FD37826AC0A7B51C7CFE3813A36 -8D62036C6B5CE16E56601864092F2997816C600AAF2DF34CB4832981CA5737A5EEE14F2C -08302588D473353CC126C39CB3F6829CF84358384005A577A7F8E9BEBBE001DCD4BE0538 -6490A8E7BBAB5DBB98B5548E478614B9CB730CFAA373114384BA850D00FC9B4DCFCB6B8C -A57D4288E62BDF5D36BBC888C6CF5F501BA8B6D8C5D69D5699D80AD979974F42420D114D -9BD3F2ED149514EF44BBB2746A00E3C633FFA966AD76B0AED0568E44B94C1F820869D86E -91A78A7C5DB8F454D313637FCD271D92FC20C9F578B21A969EC9B1C015D8FA455AB419B2 -B743CF348AE9BBF466F8FBD617E29374DD71A846A75441CC79C4B1030266EC8E46801E38 -CB9FAC30D2804203AE5CA81D0FAD237EC8D8EA6C544F8BA10B91C2D3A402E940D3092E16 -9D44A95F8292E2DA06C709302F69729A5C5042A009D319FC7049C50DA4653337A6BE5A22 -B325F1C64CAF8682D3D4904654D636DDA229F6F41FE01DFE8CCA48B171FAF8C099A92C28 -D3691CE8EAC30941176151B67198121ACCF7A6EF4FAB0843C385003036DA94117B66FFAA -0A6A8C007404A9C0781D60652E48D530A656B7E005C5053A8CB7483D1EECC4A85D907859 -982A74B1731BE0B8F4B1E91E4481A68057F9AEFD9438343C1229B0E676842A85641CF32E -364CE9EDBB8D4603CAF04A5B2111760E1E77370474393F89179413D5B9184938BB00DC79 -FA7602A1A591EAD89E9D7DE655378E10E301B4005D6B5BF682DF253B0D8A34004DE431B7 -C82C1741D9952B20F7312F6B44806226115791D0E38C6A5E855B2197DE0317858F25C62F -2177D7E6237CD2CCB630FBB13107B25EC2A75EEA8AFE6AE0642AF1F23D171E99AEECB731 -5034D2410795B40495BE25FC6EE051D78792D65BEF57BE88C0DD7A7C6221D0B7ABD88762 -9AB940664A7F4B6261069B5DBC95BDBFB9DEFC25D4DD38B184CEDFB2653553894B7EB379 -4CE19DAD9160266B97A32BFF96C0A1B7B6EC126F34DD8B242AE0FCCFB7DA22EA249A14C3 -E6208F2FF090AB21CE1EBA11D66D654B30CD73CA6B2258F67706792E63E52B1F9829313A -C0D6FDB303995546B77974C0B07F906944B68B50CBDD7DDA5DBEC4740FC6333D1E62984F -A9C13C623620B27680BCDEBEE51E3B5841643383374E04BC65E4CBFA38C91ABA62D7AF44 -C721491F6C78A9088DDE50BBFA9CDDA44E567D776559D3E11030CAEE6E5E7D07289CB58C -852AB6E55F52A6F5730A099C982DD11296E4E33CCF20BF6EBF16C1EF76785F13A1AF9EF1 -A52FF02C06A959B6839550F4FC30D277AD524E215E05B63A9C7B74E2FCACAEF3DE606002 -349C3FD26BA26FFDD6737BEC9C5DAB55F0A63AECC534DBDC2174490980A9AE98B00F6BE5 -2334C6090BDD9AA329F6A66F551B3E41A0DE3EC021C7916F521DB7CF1D5A6B7B9D72851D -285358554917F453CC15A1D73FD528AD12230892C6774001C56840F60EC5439F6F54F741 -96E6D3D74010F14A30DF85B16D23A7194634CDD9E4D2D74FA1ECB3DB09DE7D7FA438468E -D1AAA438A463FC988C4460B1C55FAAB585AA17837CE6597B162601010A04725655079C2B -627139B1A2AD607FC365CA845CE554AC4881BF87DA677B2B240AF10286A947D624EFC074 -1D7EDBF557FC7BF5409AFEEF4535C7A02D9F195B1A20D54C25BB918EC1DE3492D8301448 -81CC8EBA460A299805212312643D95AC08F93ADE8DA467C4286ABC575D17265D7B268809 -C055D44FBBC1672E34B73EC73F114FACCEF8817B3EACC68C88D07249769D0AFA2B797863 -B6ADDE44995C903A35A619EEDDB8F1D76E736C26EC4E8BBEB51B05DBDFD840C0DB53C766 -625664B8506BB1A66DE8A04041ED2F68663BD15E3B932234F37CFF8128E4B2AC1C191297 -D4202B56DE39AEC4006ABE003B7594062C26F206C124E1AD656B8598F190A335A0351034 -388C225B0B542D11E3CC96C0B72789349BBCD9C445C19265D32440F6248F2315A9024BBA -0CB6B71BD71DA2B06B57FB0483262A653161E6ACFB5E916C22B6DAE5847740A36A40A505 -668EFD5FB438F9F1779C02A19D2C14D6F1DB6B120C060D2ED8BDEE9733497FC9134A82E7 -42970EDA3F136E0740CCAA97EF05658BC1BC0F5855303168E2BCBBA37305459215393674 -3D51B4670061818712549FB6CC007C1F13B8C74A8AEB05B30D37E6587148A94CB7C1F27F -1B4B37D298DA91CAA996A180DB262FEE001AE974B819D288A619A8ECC8E442D4A2EE0D93 -B89A0FFB9A03EA573BB8D40676E9C67EAADAC5C0A807D7422AB90881515D4DE087893B8D -A0329DDA3C42689CAE4F29C791EF79B2965F6DBA3C25AB0CE23ACFCCBFAF41ED546B4A05 -0203147147ED047719FAE976A2B71A81A0EDC3DF0A3E03B4CB8208BD7AA6CD91151B1A31 -5AC3C27534D9D73F285CBC0F3D7E0C2CCE2DA1502BD04AE6789ABF17DC7CC9214C67F2E8 -5DE2A1A71AE65A91D7F139756A1A9F912D759CA02A433F0C44E12E8739C4C2BF217B8FF9 -55FB47DCC70B1790B3E906B9AEC41467E5E0E9CA0317BFD62F2A493EA5DF4103A385B56B -45290A56E816C06EBAEC8D38509777CEBB11CE12509834FB28FA7A19FAADE81BDBF0E427 -46EAD35477D51E467EFAFAC373E3E72012AC7AD85901AB832B8197A5EF7ACC5A9D6362DF -89CB52589A3CE810CBA525DC46E2C00680EB66CB4E20CC4872B5F6F9BE3636117140C3CA -545CC3926EE9005FFF15AB7848A95ACAB42E3B565AE93DC7A1CB80B2854EEE6F14422013 -D50C7BDD75E97822BA7C7D65FD383BDD5BE7DC9942888CB7C39CF56F17ECB0676B73D3A0 -2A37319899D89426DA1B299009379DB2C217DC43FC08F4A43E13BF8522A2275EBA64628A -78B877E2EFF40FBF2B5C628981B0E66643757F5F8412A5B48AF6CE0D230D57100D2F3446 -CA7C8EBF6F3EACC15C3115BA9BD61CF3D6309C18BECDE16EB18F6D008C5C5CA0FA426B52 -5CC0F33A5743D4FAC4830C4B7ADD35ED3BD7F7B072847D2D430DDF667A6FBE49A371BF0E -BBAD32173AB5928B86FE1F4E74116041E0F6E4F1041BFE588A17C7ECFF96EBCC224EF0E0 -8E3D8566BC221C1991BEE248920A4BF4E424FFD1BD34D1CA66F53DBD6A1AA33B33CE4EC3 -ECE8DF81BC73A54DC350A3939F07521808FD40C566B03124BC7300D28035F2162B76F6B7 -F7A26EFE392EBC35BD718DD1697BC9FA8214A1E137E28308F7C37854FCFC6BD031A851F5 -E54751C2C409A314A0AF104BC8D561A5A8E7C6B0BF4F1EDF9B42F577A9B9AA91D690DA70 -6BFD54903E6A1591588A845EAF9B49A8C5BF35B06AE495F4A8CA94D64163B2BC03482DA0 -BBA8B30CC65711C8B45AB4EBAF027958D578B94DCA70863767A0627B0751AD63EB628BED -CBD2C89DFC2A3BAAE500389F9D25F1EE6FAF3BD85B018296528A0B6049688B2CF7BB1941 -386D49D254EAA716D29051B9A5295E937F700C7D46872B6D593869A88576DAC22A2F8B3A -5076656122DD5178AA5FF49A84BBBE20DEE581FAAE017BDA5B7D4886BD8E90755D766EA4 -B2E825F73B8DCAFC4AA1A8263A179EC15E6E7EA656B1BBA6E19756324876082C9CBF9094 -CD62531D1BC54FFD2F9F9DEB6282DE12B66D570EE73905B0287CF19E628533EA058D5FCE -AB66B6DFADC6AF54995ACB056B8BF3AF89EB021073FA98A4B6803DF89CEAEA3874B09625 -67D46C4D830F0CCA68C7F24B20B94FF73A0D270D2247193214DE5E85775E15F5ABF0C88F -59931730842A814185AE10BCC62DC83846FE3031B140D6E0E05F4E5B6053F71781B10D05 -81904D48290FB4A157670B791271F7B1B32BDA4A71776B196767EA25D5A935CBE1626C6E -5B3D8E64F74F03DFC72FB5C63BF586540071EE17C883AE11F2D154EE9AC0B2F7F71D4D08 -CC170A9D5206AF1585BCC8AABC2C2C714DF83AD1FB773CBECCCC388E0D3769CDF84DE17A -83618678EF40D4171BAF7236BB081887A042DB575528027CDAC918086C6D8FF005639565 -F6676782F78AAA4EAD4ED8162A35E447C2D60A07E6222415B516C8FE60B9C0FD24E78996 -C1316D99AC6BF81AE6A7E53BDB0DF9AD231123474DC9A0105CBB4D98EC4ABB4F9BB4D3DF -9BEFC99537B06378E91C875FCE12910CA65C33C47F1D8A864D17D5C5B288D5BF6393C576 -ECB62660756C8746C2125A8434A5DEEF7480CBC48C21595A28BC9931AD897C754A87CC3F -608999E7FE39CE1F60C099357246117C8A074BC1E405EA7FAD3277CA45F5053C2EE050C4 -B93A1F85B90084A12D625DABAF2291ED36699134DB6BBF4AEAD7CFE27379AA6AA93B31A9 -AAAD3F8F998BA94D3CED13C1730326F08928C6A648CD010845C7CAB2B935ED2450239B20 -63D25104A1E9F4DC48BD8BDA6FEC274BE5807DD2355F6CDD587263837ABF3C8CF8466D3D -9C38D0302F1CE94C967BEF58E6B867C9FE138A7DAA9E7C791865A3E8BA65A254C7032E38 -FFAEAAAD4EE632983D975F167172AFD8FF70A1CF6C90C24B9C1C3E1CF51046BCA8C2F0C3 -D56B931C70848521756E221AECB2F0015B3476FB304B28C4B7966A3F693AC9E1C5D69C55 -8DE014A05981CC5E1AE6083A91594F0BF812B1348B5401E4170AC65CA29A7182073F0E18 -8BDFDA17EF3933750DE211D30CED8B11A1107DE4F12336FEEF5AFB522B2060BB745526FB -D06E42C1D4C7F529706078FF598EE48C9521793F53F770636FF6CE984FBBDA645DB8E631 -E041B10E43E836B1F8C58C4F2D4A7BDD4165FCD7B19243AC560E80A6FE7A3EB4FFDA465D -9ADF12EF99FD68D90139A58A53583CD9A0A574B8E0A604E84FCBDCCF67B8A2DE8D411996 -12EB00DBBB8448B80098B458B143C6D1CCEFA354EDD81B01BD6EE4A0ACF2AC0338BFE143 -06DF27EC691542D79715D36E06DE6D7C2D3C9C0A7DF0094CFF0B50FB21D67138DCB7D447 -B45EAC890C4C6E08852F9C00D6DFB9C60A24061A3014844C84BCCDB993E0B8206E5DCD85 -A97D0F1AA82F5AAC40B5D490BC1C60F05B33BFE6F6C07138A4BD1ED177C2FFD13278F53B -1B20218F1685385A604934223F259646450DEFF801D97C1D38E8621C612A4E49B9CC2279 -7DC683D7AFAFE54FFED9563E880B86C25982D6733EA3B8558461207C91F024640FEB1D2D -5A7F80D16FC694DDC1A59B7E30D1924ABA53497F37345B31D2429F6804AC66E9FCCCF4EB -9EE2BF2836E5B55F29D445762ADBF6BAA501E198FC7FDFA66F3474B116E9A77319AFB981 -7C2F4BE21CDCA0FCB65F07DCDB906AE92CC40B4A8E967D91A00E9110BC5E3289AEC2643C -02F77C6313DB7BCA506CB8BB3F3A434904BBBB46D7C724766DB3BB73422B659F7D5AD5FE -6DAD7B204230C92AEB30AE4E510478F620BE0E4D6AB477971A22A5C6AA66835513B1E2A2 -278BE747880EA3E1EFAD48ED0B7B5C320B833587A22D5C944F5ACA917C4C49FCA58CCF19 -BD800F5DD3246DFB9A772AEE6DB700127D07167F2D69CABC855BA8850571850D913A0606 -3DAB1EDBB6AEA9724368DABE65C57341467A58E819ACD98BCCCCC971E30F0488694579C6 -C4991EDEFF6DDD79693EA8BAD8AC9495D8884E5B09D163C7A0D343C031CB29F879CC5064 -B65AD297089E7AEC41026B5E055DC47A7C529ED28F3D27A191239D4E3EA911C84084B411 -13D7029A39E6C6A2E931727711F1F06B807841406515B7711A6B96E6AEF79E271C6E7D42 -7146AC3915D35E9C2D4C9E7C5689F7B0371BAADD037840BD034F4C411AB29B36D4314729 -E97666CCED8F1A5AFF6FA352AF6AD9D9343DA8E3F97A8C756B48675750D128A3862C19D9 -086B597EE751BB0D87A3B7A56866CB6AFD2CF8B1B322C9B2493D40BD5B89C4AD69F347D7 -26C22E0E39ECE377C995A611B54C0B2EE3B6CB16673F50779C212AF1AFB93DFB2C931A09 -39A1379C379E3F7327A687B5C4D8D909D3CCC5C3195935D8A09D5E5BFF12E61EFF4FC6E5 -F99A1460C5D1FBA82C84136BCD64D96AD968D6EC728DF4A85573E021734AC6C2100B6F67 -F4E648F5E284618A1868E773D9CC819AE8BB433FD388E971F211301B3ED077CC37FA4B58 -0B50F8BD2309D8E81936C050E3F0C8C7D81A80DA508533BF5FCAA977C17A572DD92CF1A6 -B7172AB4C66890E9F4FEC661AD629FA0FD23E9427C481408A637F9E649DDDC31668366C3 -692B524D9B4DA99938076EAB2343FEEA1560550B8E8CD18D3CB23BDB1AF30F60EFF18936 -46B26A09E5411F6C456917CFC6BF3F74B2079D0AA56935E672464F6444F2E17DB330F94D -FA7CFF92DB6C800B2311AB86A21658D431EA7C811E020538CA2335B9DFF550C077E83B29 -544FC63F5407B1C9CBC3E6E6259742EC85BAA006D2715D686619A94AC7EAE394915CA656 -B8DE89A462A85CA179C276B4F90C399167DF0D928518DA2A45B3125CD16AEFD65C85801F -BDA3D139B3B349AA86037B579B8FA94C713DBF1DB2A904652E89AA8281DD58D4CFE3434D -6C86F0BF7921486C9AE78F322DD841CB43AD7EEAFB5735DBF68D03DFD6640DEFBE22B305 -B33DE7C444D16D31C3EFBDC78547D77962EA985B734970BD6C4B729C7364348B1CC321A9 -46D096A078A45797F63B1734E968CA55B8E905160740F68676AD286C9F44E1A94D17F911 -0EF21F8EFCE27A76D1D7869FD19C5A9AC889675172335D312E8E1DF59ED55F8FC13D0E6D -9601039BAB9AEF7A4F3BA688E288A089B326E0B582384B9BD80A0BAFA1130E2034F95D21 -49DEA8E5F576EFE035C5E58CE82CCC0B3A95980097B2D4A80BE162C8E3760C3532697651 -2626F6C64864810E304D98D77F13BD535DD5BFCDAEFFFCEDC1CED370DB2EEF6D90E1F0F8 -D4C3FAEE71AD31B0F4798ACD68E1A5FD00A327846DE3AD55B0F493E534AE6E30D2DA7EDF -3F68459CA7192321B98C8DB02D3399F72A0216F822FB8D0B5B650B38586BF22197F78D31 -55B67843202DDEFF5B04D4230DB2FC50443C21C8C28E7AE0E399767E03BEE4590C4D47F9 -27210114B296F1E8263213544DA56D46BB179ADBA6DC415D6A46679A4A7494AE4B2F0812 -9C5D06F92D2D500F336304FE3454F07A2083D6B6BD5D5AB3D6F917F555C7F7124AAC6F38 -4262A051D865369A95DD8EB9DFE43DCBCE770D3C8BB6630AC2F8DAFCE58C5C4060BAC1B2 -EEBAE9E56AED8725DEBA7CE23DF18E1A52A5B87F39EF416565DA17A5BB6566A8129CFD77 -D3DA3E3583E6F59EAA14F7788C06D3492FC84F7C6BDA74C9FA885EBB7125E87760A1E848 -E9CAA638A813D6EBE8EA2A3E9ABA7DC8C392A066331D9EACDE6C6819AE12A85B096CBFE5 -29BA283C2CB73FC34472C5289914EF347AC8119139A3E6F0CFFB5772D5AB65B276C171EE -D565CF9B1E629AF962BBB00CD86FED8DCA3DA0BDE9ACB286C516114BDC1AE1AC41DD8453 -795253786205499EF2E971F3DFC51C72AC5225EF4E0D9DEA403F24002591D9F55276CC38 -0DCCFBEB33F7733A1DACEBF1AF33D55029C44364284F6CDC12ED12BBE809666607771634 -90828A6F10683FAC8C3C4DDF38A0CFD1D1FEDAFB7100FD9C02AC8796C7B3B2793D11C107 -DF10D22D9C294A3AD3897431EE593AB265D97450A6B2DC4917ADBF04B04F32F5802EE354 -4D3A95CDDE623A423213D0063B79F8F40EECC82F3C5985CD12B0A46F5AB9DD5175A9F3DA -06E40950ECD37DE39B5EA6205D9427EF43D5B0D090A62B669E437D0C31B6A03850EA8BCE -5D2D48C25EDA80913821DEE94881348DF1726A7D61ACD9520267B5C668F46B1660E87E27 -658B7D3C2F1C06ED70D97AB144D22A4CFF4A54D73F703A5AAFCB5AE2C7C5B33CAE3F0BD3 -29600C9BF8BAA060ACD3C4D5A72851A2A18AF29212B1E070EEFC452048CF312134436B5C -E91FBD2E526CF0A35F42C1D8092DA30270EFF9577ED231B303B472670B458C6B53B1C766 -09159D861584F0901E7C8DED964E9ADB0B424092B4B50C490BC8DF607EB9345C7AA94CEA -F430F8DD439472CBEBE11C26F9D7C7C5F8F04F6D3D97043E282CC848A1BFC73C095841C0 -ED64E7449BF4CD53A64F0B932C45B0770D6D18CCA6147E9F992A93275AC93D1B3B0F02B1 -9F117034AEA1F3F0F77D482A3DD8D5B2F69122E5B08C067D39A1C25D042D1EF4F47377AB -CE1C38418BD39E7400F10247FA13291E34BA3CE681CDBD28F3F14EEC90A21C76806DA1CB -25AB9B96031D1A472C1146004C4DF21E61E07087A8DB5C33DCEA85EBDE4587FB2FBCDC2C -5C6B92E61C72B067EB5F07233162AFD24FE6A2A9D0BD11F401610D5C5F91E46D36B2401D -A81BA2716D4AEDA19136E58A14F5A367942B70DED7DB1E0703609FB97F8C72C062934495 -DE54A6C45EE6C8B5F368F2817ACD4A10F14A846C1FF578084779649C4BD01D9CBA1E88E0 -1DB953307EE9BF10E6C17B020FCEEF709840DF73B4CE45D4C2583CF4B357C33DE67C8CFE -8FFE367E89759117EF10E08899F466D342E75083CAD4795950C026505BA8CDE648FEC333 -BC5842ABEDC3CFCD3B27E707D6EAC3D54FE7B9C964E28AE0FFC96A06802C5A8327FC2CBD -DBA565FE970FFE18008C9DAD42EA99FF7BCD0656362AFF37432A182C59988B0BF458C370 -725CF7D7F864747CDEFA9688FF6D2CDCB49052F349F9BAC9F8261B5FF65BCD2E531BA32F -7FD7D3F0E3042811B345E8676907FE71D4FA94437A3A42872285F010D909D468462942BA -696325E79D943D0E44992A20EA118ACF9CA5F1B20E52719854476111D6479B3842A9CEF7 -749437F57055B19C5FD6993F5737E8555B19161FEF7F3560C6FC498EE8148B6327EC40EF -7CABBF6B7A99D14A789F6F5431BA4714CDA494E29542EDDBB4A250ACAFB9802B6A3D8FE2 -1CAB7FA79D9682C1B1752DD2E671ED5E4574BFF967156A503753B65075653471F29E06BF -7342AB3284E9EAC6F14232F32C3B0266416738EB5A138DC33DB2FA3A74E649532B4BA7A9 -AD51E0278FE837ED68A9A5E40AA236314885AEC0DE2BB1811BCC18F0A75CBEF875D886AD -55A873B8D3FC81BA69DA0C68778CFC5F02C17A851EBACDCFC9A0682D514144CF47382163 -6B1A61CCD572575E6A81671DDAF8C442E4268041F8E03398A9EE0F63B352839BFC4D4720 -0F86CB77549091DAE5FEE2CEFB21F4B987496FB8F993E3CC18EA9CF06442403830E06738 -20BBF3E4690163AECDCF693BEACC77B5591FCE1D2DC11621BE67F9C439F7864BCF981F3B -8A9CC1F21424AB86102448FE45A42993737F7C09275C627CD601906B75CC9370AD491B59 -2777DD8683ACC7CC961D6CABAB46A2AA65D8FDA3E66DC5C75ECECD209FFBBB76263E036B -8F62EAD1B802D3662A23A28079CB47ABA48799F3DB0D7E46710675B2C434513E997D189E -0A9661186D9D623D5B47BB377E4B0CE197D80E9AEE04E55059C6292C52E00D0AD892FE67 -600AFA285DC92263DC1F15EEBCA803647789D4D420FFB53C0CE4A669B4B963D5F2FA6FFC -3B28AABD6D97AA2F92EA3FF8EDE7AB264CEB19062030F43D8438DA703B68D2615928E4F7 -9687B03BAD9F3447ADD3090BBE186FFD3E42CBA236104DD1D9A8E9357CAD999E889D313B -262A4232C5926869139EF1165172932601BA4CB406177E25E6150605DB931A70870F5BA5 -1DAB4D15D500B261F9D708174568422C714F30B696095757C66F7D2E6A5CFD146D90F21F -27F62393B532583B49558C8C6124F2F428794133E093D4FE09805FB2F18BED35D12CA321 -B79B0369E46FE3191F47B07D234866AD7EA52C50F4C0562597AD1F7D186060BE2339C324 -F154C2EDF64C7A40E8419E7542B8CA143E172E3C62471AC1F42342051B3FEA08368A31D2 -56A7D51FAE801A420FA30E5D479283A21B50AF52C6BB4196433D933FAEBE36EC577C59A9 -BF52F260443A622B637FD4F6BFD330F8DAE7E4374E16B8E98BE92E3404CA22763671CE0D -276981334084462B06763958C81E7D85C76223546F3ADA094E5597AC68967D96CD9E76B5 -0518144684C71739C488751FFFD3B9859E23DFAEBC15A0AAD8417416CD5B47656E8BA799 -BB2ADFA07B90E634895108D5F97BAB5B560F0608C1239F49967B34941B908AA695840FE8 -4519FA60763EF706ABAF2E0C7D407E5DF05807FCDACB17685226D6B5070522D4A6AAC8B8 -77891A1390386A074745E5F4875F625E9BBED05B54D04EB6A6D8352E7E4E47FB7EF432C0 -808D0C139EF7EF5220838D1CFA3A839B10B772D8F2A197E8FCD7EDFAB65B7234A7E1C0CE -D75C3120A58706A26004C2218744B095AF45009AD3036AEE08068311B20974C4A95C8CCD -4EC20B2B8B8EC4F2D6F9281968EB51ED0E377E3BEA2481810C3B0B289AE6A3EF50339AC3 -B7F06050B7705C260D942DFE3B104C13728A2140F9E137AE5E476FA67245FC92F1DFD28A -81CDE2EDB4978F971F668664658A674999A62287F74C8BCDF0C306C20FCE35EB1BB7318F -9D7BC39F215535A9796A7AE7D117A273DD5F1B0F5FC5F87863A817993C96CC2CC0FE3504 -44698065A0654D045BE4FAA60A218D260FB013868B18AD6DF01B793D298F0CE041671E71 -81893BB81310462FD1906C5F8137FF46937B206588D2715297D008E6AFB90DB28E3D64DE -73EFC4A6DDE7466A3D1BB402FC04AA80DF2BC39AFD30207230828FABCECFBED8E11598AD -CA43FE742EA8D1BA8CEBE4449495398E5DE432B8218E02A5340C854455069082EC8AA449 -63A13C0069F468BFC1D3D75D4458383E04268297EFAED1D02B91AE933DECE8DC3337DC99 -D7AD1DC4B999A3AD5E8953C7820BBE425470B21BB61ED6007F236467503327FF73979677 -918B34DBEBC181DB99526586BB6E9889DD810A0CA022C62FCA58F2D4D738A74BA24E2FA8 -29B80401DCB36889A4CA08B77377DEB0C4172DAE920E318DCE78DA14ABDB77EECFA5A1A2 -6FF51D6569AF1218C4256D4B4D206ABBFB1D2C7AC2102815EABF306CDE0615FBA775B5E3 -446A2095C406CC1BFC1BF4A53E65FFF0ED565B45AD332505AFE0F91C8569897834C06194 -6C745ED6618A60065F6E3B3B49A61BF3265F3BB1FCF8A25F4880DC771ABCE6BD03B48C77 -83BDC1CE678E423ADEFE9AB04D40097D8DB062DA0A248D1C81AC57FBCE032B232C6FD553 -8AC5AE7983412BC80D23EB71E4DC3B946FBFC4B98C4250BF8D57CC55D929B55C354A3F9D -1C5329F36B06CC099C2201E7FA501F75CC7D5579FFAF9F9C63C6DFEDE80B5387117EDB49 -9D3F1C72D650FC120FDFC8E42479469DBCD81AB244C316963CD6EA1C34DA43400C5A2B7F -E9F0B71EC4EA67255AAF6A2F49982441962CA30DCCDE6F7894520FD2B811619713D91DED -5D1FBCBB42B1368E7F8F4B8438C515B4661879D353096F880AE278905424DBE523DB7B41 -A5867878E478B85960607BD1C129E85249CA520BDAA479CFFCDA162E46DDE5EF6BED9684 -31F3289735FA2891C13C0C341159905F43BFA6412B6ACF04C2A11B87AD4B41A35385AB66 -68CF890B1E9A43598F03AE5A833A932E5C5A70E498C405CC56BD0BF1074EF1431980F575 -67D7C62291703308B41C4B94A99DB6F6F1F924E791025D5E2F56F3A0B60903FC0CC0B2DA -8CC5785C6FB239ABB091B7718A9BA16D5A33083289E8347CB56172FF037F6FE1A9F7EF4D -5D68E23A9A3B9F63C2045AE2B1758489AFBABE23DC1FB610B37DC573D2C0AAF544ACC904 -B69C7775244B1ADB77B51727FC66D02637CF2E9C596A05AB6BEB23295A093AA90DC3C3E8 -F17CEBB44AD7A8BFA8898D6BDA4F84DCA2A30FB5F0D151D8F6666690BC71002F31AF05EF -E033513CE82E8639B45CD235F24CDB7C7C3576149CE989FECDE2F51FC835CA9A023D889B -F6DAA3DB5A8AC49DEFF48266333B5B01130F954242A7D5A369CFE937D3AF1C4F2C64051E -59FC2AAA3871EA827C5B74C70C259FD4DC5DE81E2970519C433F1331D1D08F5DB9BBC9EE -80D1B7972C7F1514F7116E25DF3E382785504969CC0AB8DEF43F5F45676B2090DE9A775C -04B5A4613D38FA586F05753CC38A684BF33D2991F909CFE097F97696CA2C59CC20A6D89F -4710B1EF765EDC4D5A0B7BDD33D8E818D97C9A19848903D1684436488AA7E204F577BA24 -F1D1E0D39ACE2DCB56550281BB24BB686F605B7146660EBB47F8E329EA27F94319D795A3 -71D2D04F6B3DBC4A61D4A7A6B748A60B5D8F3586FF31AC143FB706770E4DAC9A6741EE88 -79870FD251625EE5E77853F6C5D2F621C26757FE64857FE4D0502F84C14825D9BEDAD55A -35C640D9999543CFA0467165E5AA8E50699A1C13589A862BD656A22A50EB6F479D5C79F4 -585212673DC2BA0DA86109FFA40F5FFA1F660F8C055D2E9B9668B2966DCDACF5F189D835 -C029F51B85111D9D48F507AE75A7BA53CA97B39A5287CA4709DBEB723E6D68BFCA745FCF -7DEA768DB0FE6140198D62E880E49E2997AB132521C94D259CFFAC9036B0F2C2E15E22AA -6151E9D4737FD36B9676450E6F7C9E7531FD2F4F307D6D548F37A3DCE2CA5A811EC19778 -12B37C5722AFE78E1425C2C1C06461C1508818C9536FC9117951719B8D431551B4793C81 -CA6938CB75BF746C247A9F48354B0A4BDFB2D6DF3E305218173503195BBBBDDA322153A8 -2085F0FB5ED657637791A4A7E1C1B23CE0F8AFA1ECAE76A3FBB3E6B7A2BDA2E2252B2E43 -4413F7B626AB00CB381737A2BC0837E33C3E25C63852B841E70722F7ECF6238890D63CCD -2C93F7A2CEF10AA710AFD333322F4907E87A12DEF07F5C7BE344E73CF12CB388BB6F049C -D9713EBD215989CEEA7473C00E40F79CC0038762139D9FE2B2BBB290C51A3B4B9090D039 -C22B1A620DC1C3128C0EAFF4C62A29AF0338C65B6730BDB7D5A6A7261C04816B7D11463A -935AA0D33802EC148CB8E7DF6B8FD0FB064BDEABD0DFC3AD5A80CDAE645B7FBBC59359EB -A0D70699CCB53887530C3AC4E796DDA9AA05F36CC0A6D0C2F616E761CDB1ECEC164974B5 -0C0D38697DF56BD7F7F1772771054F18E3F5EDEBCE00939E70A43766D0E99EADFEE152A2 -FEACA0BD0BDFEAD28E3437753ED58E345FC0D6F4E395667411D4246C460DA5D3BF2F5374 -EAEAE1DF1A76A592C4957BB9C4D406257388DE96591969B30D10DED2C5B647B66CC0BCF6 -146FEF353A20A3A2E40C1A7B7964033816D6A544399965E9C17FC44C524268B0228E209D -2276C1071535597E57EC3D9C4D8328CA914F54536B1F63C89325D6B26DAB4A5B1FB8260C -241331D1B55C91406537C5323ADD2E3CDDDC9E199CE067262690BFDCB5184E25795251EE -181E745001ADEAEE0A9442D57002D48D6B53E693C37E0BC64ADA28301235E9799D9D0AAA -B4A23F6D8B4EAA5AD3B6B40618330441F6A24E44B160715740198B551C2883CB17FAFFD0 -3B4CE68ACBE3F6B33E29987B5258C1F7DFB87DB89735F05AE7966FF1F2B6546AF2A56918 -3687B6DC7B1AD435DA0209B0AE7CA01A3A3359291B1435C0BF04BDBE2B8778E4EBEE35D3 -17EB5CC7A3F7C5B7743AE69B16A6B9C89491D121617C20CBFA52E93274E6BBC8C0E9924A -002CBDD7922F3437560E3747B93775FA549457CDCB2A9943AD403BF8AF05EB1CA0EE347E -E832C6A17A3A53EDD50EF553A0E8D6723D3DAACEB6F81CBDB5B78A5B207A98183C3650BE -A88F82AF734CE32FFB1118E54FBCBFA2C2705D65FD4A1B3A3734F188078A7B09738C3EE3 -A12FCE8B7221C3041224D324AD3C514EEE792E3D47B1E8DA34AC3E577163E7AAD2C85170 -7D630EDFF8403AA2720B09218E0013FACA789243FD76719860373949951B1907097E01F7 -2840CC3089FBF9A86B01E6E5A882444A3D167A302AEFFD3AA9463A68C7922104E365FEDB -9BE61D5EC0A3AC5722F2BCC5101BABC86333955964509096B6799F286BEE15441C3DCD84 -A846B35D0B027C48DDCBE123DD9D2DD6A4808F0B3F98BD4BE29E1001905D8606390EEB35 -396A3A981529655D67FF0539BD3E1FF2FABBA0D4393CA781FDE2864DA5D2A0FA6F78063C -03CA44F27436C3421683D242EF3952B8707863F6DE2E3C94ACFA9FC60EAF7C8D09BE2D27 -BAEAD24C01748E1EC790EF22AF24F1F7BF0AA1FACDFB5C8E0A9B3A1E9E53047E4E791D7B -9DBC38B9EE8EB0E5CAF79C84E81897A4B202C6A3F22438D9B043D982F605E5C73CB01CE9 -56E9DA66D7BB53F38BC43DD2962D6589AA47BA3E0AD6BB8E0557127CF8F6F83AAAA3597A -8B57BBCDEEB2223AA2EB36BC84C7BF53F3B7D9C221FE76629512D04EC454D92060750F55 -0E76BCBBFBF9566266A8D033931774C37CDBE5FA71FB43137E5592DD67945201E1D10467 -A3BC5C273DE16E64035C39E4A36D7AA7F4E8389A1FDBF891B00613396194EFDC5B77A9D0 -9AF9C1A4EAE52C87A096FDFF8699EB01E9EFD3F786A7D45AAF8D9D33B934CDFD85C495F2 -09009C628EE54F19A9F02CE631DDC692C3C56D2FF00B8F277A18D1F38A63C394C717A0A9 -0B01AD75390D853D63D0E0678C35022369BC8C985C8229C98CE6BFE1C40770461A5E26C7 -7A7AAB035D6AAA9B0394021020797E627E2E7D17B39FD2E7AC6FEB917A148FB996911869 -49A036A0E5B85D8BCC59570E4C689F2E802262ED26A13C18A57F99A74DA94491C5727246 -D3FA45A7964F212454E119A32738582CD4F5899ED604F76F0327CC1E5746A86CDADA7F97 -E11EBB6524AF8107F3A8F0B8E5F887B799DCF9F9481859EC4E5FF63AF0C294C2AF716EB1 -3EC7DCFB796E3CE4B4CDA1DD15186CDE479CE4EECD1FB27F5A05B69FBDF436EF246E8BD1 -A03FCEA5FB213D81F80D6ED7960896101E046D1101A7522F31AD1BF6C08C5ED8F6574F48 -2B6FFEBF34A2A157567F1B82BCE3A46C14A168B0F4658055BBBA2E9C29A4DF42764F95CE -0EE9645C6E0BFF33CBBF3436F7A4FAB4B2A5055FF1DCEC075431A99670E03248CBCAED63 -4457D0EFC6565472A356B1169775BF5156DDF85E03688FE2AA31A158A65A1D9AA4489CC5 -6FDA78AB85C35C42B1754180577244C5343C21E222DA72B8BFA097BB860E9F834B62AF9D -D50481FC4B1B9861A1C2A9F340237C949FF030096DC29FEB028A00A5AEE8507AA290848B -714C13145AB3F4EA42C8EBBE4A3CC737C487D0DA0CE29BEFBEEE34F5CBE03DC91E5E2053 -F114C70CBE94DEA1653A26DD4CD332F62AB71115DADB2C6B3339878B9997AC3AB5F5ADD4 -9F432AC706A5256DCC4592C30DF40C5C47A2FDC72851FBB0E4EEFDA227B72EAEA758DEA2 -341344315496A6F22D42FFC55B4E90821C251F0D8B5FD3E0802D04E10DCC31E5024D330B -25AD95CE31981E90BFECB17E786A10ABF9A19220DB82744A43BF5B4DE0FD8C54171EA498 -AD14E0972D6EA90B5CB9846354C855E2E13B369BCACBF8F1852CE60227AB27CC84B9D326 -68E851BCE4086558BA8106D9249C3785F3C59E43827307C87C72033501ED888E32325158 -879454289A07888F09EC7EF1D6F55B92363BC740E170085C4D16547007A66B6F0E1FDB4A -4FDE032A497377F8B309B5803CB7B450A246A0CAFDB2F8CEE254EC5F6BC7C1EA38BFDD79 -268969FE9DEB9FD896E40E479222BD480EA1AD9E5E0EF7780D3E48D62219E5518499D46E -DE92464609DCDD07B5C948792B71F1854C114259463E839A2DE74A11A7FD114EDE9329D9 -F1EE8BE5463AF8A04943BF77CF68B0F3CA2571D4BDC19B980F8919AFF6EC80758056F93C -76758F0AB6313052355085DF8F0BD62C7380AA3D32102F48F4F84C153295AB27F3F55694 -E3C6339B3E34166DB450373B9F326A1E108ECD95B0887A4CB8C54A811B398C0B37289C81 -676CD8D528C75437BB2DA5C83C0FCDA94588BD785E4F800E87FDE1F277AFBC3ED0C5680B -27DC483446A828114CC9B239D8D1C2D920CF149B097F9A78E35C0BAFA1B0AAE5730BA067 -B142087578ECDED1DD73E8541BACE5FB813E14483193467EF8585682295816C4E29E197E -ED404E94340398A95A470A9E06BAB7BE0F5FB22338A833F9157594C5030639AE0E69894D -49098CA950C39937BF17194797AAAB7E076A2087467A2D29683142D84B0810F1C603A95B -3A81C3225003834CC446ED0944654805AAA164B088489DE9F71701AF4DA42C675388EA82 -CB8368EB21003C19AA278FC474731F2D74A008F24792F651F110E23EFCAC719E2E9C0481 -10968EB515AC09006E062EBDCECDB6D93772EAB20D7C105DB828A891F2711DB786B575ED -484349390AB27A3A767D8092B7585C8CF32F5FDF2B9D78A27FB8E05C4C25D970602ACA43 -31FC692DC5C7F7C0FC5669DD8B150D7A4EB22218DFAA75E79263D106AE84AA8B573B722F -BAF6D7F79097AE4007A3E519C107AD00F63069BCA7314000DFF2B06E4A9DC82FD10B27FA -16775E13913364DA3020F7CDF748CFCEBB7117CC4251031F6795F4289C4A63088E985927 -B971471069135C4DC3BE1FC3912B02F933F26F72297FCBA9F21820493FB49A1A862991E6 -948A274C9C5954AA6BA752D4B4096C953E92D916369F9AD0DA5055521E3420ACAA45D436 -6D061135613BD328630FEDA1634FFCD8E2F23097218C2449520D986694B882081A791CB1 -78925494D19A7EC770AABFB956E69DAFCA7C72698AEB9DA304765F3D9E351022F02B0C37 -9E8897E597144B416A008212A0780DDFB9FC1D89063A05D216AFED272F8836E5356A8BCA -818D7F491044995DBB9574BFA5B9E346409B9C4F768B59F654E9D607F3D5A078F1F5C0DA -6EAA9123F369B3341B40BCBEF1EFD9D56DD82A15B550E105F03100B18C7647702879FE4C -7D61243D5688B2979BF250CB1E594B1A2B9212EB957DBD3D41C0029A06C9BBC302F6E969 -4E998A090296411D7871E35D9B367C1191A3F9A638BDE0784508A7B4475F768C24BCAB2B -AB375DA779894022D09EFC62788289D9E72B74F7C52F2AB389038D4BDD244E1CC79B01DF -79E905BF50CFF6A5C06E68FD894BB1CB7E513B33F34400DC38EF8EF6E39268635F66CF70 -D5EF4EBE5D4F36430233785252376CE73CC9E6F83BEF01F6D1C5AAECB6848CA50996581D -E069F69083ACF3090F29844580712073716A36392BB2FC1049EAA0E114976B098A344B66 -E0CCBDCE847B2D3B620DFFEF1ED2FC8FEB76D1766F76F3855F2C2DE7CF10F4DD4664B006 -2262CA279472C2FC0882A8F0B5A4DAE04D4293FA7E08D7639B3D7FCAEA1124A261BEA0C7 -560C6C52E61802C8502C66D4896EB0D8964E0ADE75283048DD0A1E243690D989A49FF16B -33740C7A49B820032167807CF695F91C55C0BA6D6AE7FC7368885C674B8BF30931870677 -03A60AD58F42F6766DBE60A74B2C2E7CBCE56EE68DD0D269FDF5765AA414157BC63F5CB9 -123E0532224DEDFEA2E668F3875AE4C5260F93398EF86BD5867E0E18B497FD85C4FF4A4A -3AADF54256544BCD7811B58134BFC41026132D8D30BF6903C2940157AF0568C9B6BB3009 -7577212F65BDEF06FF06760E38BD32AF61BCFA7E2324D68AB590F2E45A9761124928F6C5 -64BDDB6B51180CBF141F48EF9FF6DAAAFF2E379A2CCE80EC839A2EDB91827F9D1BA0AE40 -FD36DBA0E8ABCE564309F7DDAD96A5C7D87212F8D586F013ED189D6850322E4670CE2D07 -18CB688DAFCF1961FB0F4AFDA71382DE9CD976FC29B4CEBADDF073774D9B8AE9F2374C04 -F704860ACB17F8A16B4051EDBDA362CED1BE1BFD0700524188278DC8D6B22E0D585F26A7 -C4447076AE0998A76AECEB8454959F30BF5A4BEF1495D6549392AE39D97388B5AB14612A -D6472A6B625134E17B540AC0D514C1239ECCAE5C75C9F7ECFDDDF66320D00052D874E6AB -792FB1CF5F37BE8F34A14CFAF642917406C3C519EF56C92114E706BCA38731B52D68B9E1 -61BDADBD17A62D1074CBED9FC77F5558CD4970878E0349536745C3DDC0E6BB4CE878B2DF -361B4DCDC5FDEBE160168F4D0DC81436B008714A2EA3BB569961F07BCDAE095A44F578AE -6D0E6B5DC7CDD38FCC37177DF292411C89B4B64612C82029570C5A7B9B55F38E063BD3FD -E00421B42FA18751B624D59495604A52A0DE27FEBBF7689E0DEA085841050DEFB7C9FA52 -D3515731A1BD61D4BF5E82841B221EF88D921E1EFF65F731948CA481E500A46E84487BE4 -E3F9DAC68918F117B77A2B5B68181C914FB764CC5876D2A42CFE47F045F72E5E443B4921 -D0D63323C748984F622F00F63C886F404C671119FEC90A598084F85B4866A5C79E987C5D -BE5458A2A0FBCE0BA6ECB7433F9D75142DE04FBA357042FA9793BC9803E78E573A14E140 -BAE5E044DFB28D9BF672461BB3A3E50E1BFC83EDFC49A962DEA01047208F49C4CEC837A9 -D2318E35301D2B18DF1E8D828B58FCE8D5F1450E4CCF92BE5CA2B30516A4E585D6C83BF2 -80C7442A4F942584BCAF4C2CB5C2F56170817BF0535EBA87C75BDAA0190710A7E2D4029E -CC54559EE6424E26F0FF8E1C2D3D012B3FAC397B1A446918F1D299A19B7A28C4D7F146F0 -CA4E29B96D275B54C16B1AC37FAF498462C7BA8D2C11291175FD05A5B3E08290EED58ACF -680DB2202F229D7A69F982E644285FD1FAF320A0C88E35BEC245D249AFBCF6CAD552423B -EA2AB070F314FB9B3EE02ACDE1FFA602D19E1805F27D1AFCD58D6D227EA765E6630149C9 -59ABDC3067CC97A797C555FDC59B9E4DE3B0681898C970609B1B6B15A15A65EEE2DEECE7 -2BEFB1E2C7A2BE2B3FF19B2CCAE4937DA4B593A60FBE0E0DF3925043E677D44B5FF7B42F -73EB65150EC0533B294B675BD7D5CC6A7BB6A4F043FDF87940F8A8CD366BFC008273CDE7 -72EC15D7367371283EE5BC26CD6D46CE665661E16C691727CAB0833942367DE588BBF434 -06F4DD67988AD1C0D5C3D24DA8A833021F65E4E4393959434E03CCBBCC98699A8B1550E9 -C3192D3D3755F81C51E6CCF4C4E6575D9D4EA77261B987C8FC8CF67035D281D76041F70C -2B2FDC8FCD2719A93FBEEEDF54685031ED2E960D2CCF2B5DB0840B2554B1723A703C41CA -1E6169F96A1050CBA7A1554FF8A6D7E4BAB0B549664DB9B808FE7C5EA9ABA7B071E71125 -54D021BFF7345D1295333E876E28E14F2274CA0E5E4F3838B775890CC30909661D5B86CC -4F681967BC8B5B9169C6D8F1B30ACB914E1140C6A5AC5B6855EE83BF9F8C5AC875D93BA4 -1C62B9D44917BD3B46F65B23FA3044FE5A6F812DF1E77139253576ABA80A57B38D315E82 -CE42DBB3BEFA62E400A194B5F59DCBFE915D3B5DC010B4DB140127BBF0195434F5A43957 -881974EAA69CCEB2E588DA124EC3F7CD00F6BB81AC494088F061065C204A851B8890A5F4 -EBE9D680DEC34FC853FBC85E20E3D9DDA86549FE11396BE73B2978AA8A4C80BA94788D8E -D03D48C88C9E047CAB868D7DB3837EFD41267AFDF4808944506ED385295788CFBCBD89A9 -8DD84168F808E49BD346874FB281AC70FB138E100D914093C582E7C85F5EB6243A941DF8 -253B06BD01E8F75C693123BC20D17307B8E8839CDC5CD180FBBFAFFF702E0E9F6077237C -F81EBE9737C296BD5180F40EB79A41BDEB37FB0FCBE238F1B86F45D8F25B39FD7DD4DE88 -4F1D9659A27AA3F25CE066D8D84FC09932B8B2D3BC89941CADBA33F7AA87ADC13453C674 -E8AF9CF633ACC730085EC2A843949B9E5BED6AC3ACAEE21D620495A0DC04260AE555D15B -59143C29566D3331B26DD93469C682409BE8D37BC93424E115F7DCDC95EECD57953BBD28 -974F249FC98A73A384260A0568A69B382886A9AB09B6215E463319F8736865F700134E65 -1D78B9C819501DC01CE5C55A2D58F12D74988AF124CC6C7E213520C940F6F8CB4CDCA9A9 -DD2B569D06A967208EC37AD2F0BFBA7AB7DFE87AD7A5AF4B6E77E2C8F90C9A97D7EC58FD -2D7ADB97CB6AB5189AB4E5C29A1044887CBF775E09348A2FF946E9D7FAB0A13D7405937A -EA98600DF50B8FDB161DF14D091B58E925BF12EF3176F3EC504E1E75FB868CC46146389C -23DBFE0F908356283136F4A2A3AF2C197997302BB3E545907C3295AC0FD06D2069D602DD -052BFBEE41D7C926B303D4C1CB548EC9537A0F5FB5C31899FD160BD9EC390F2E0F6575AA -032A78BFB98714D731B0804898F148ADF072B3E714009932FC8ADB363B18B2B15627D3DB -B20DE94FE90B2CF68F85D7961E9035DE17AA5505254D50704903F28EF414D3CA13077AE5 -A0BEAF8F5E11FEF25C8484A34A1C39FA1E8CE92F42BEB83158BF26EB1944E6213E5B1531 -C7065B2F1449D3D444855727E691A501BE62F659322006FF9A22A5288260A785611791A4 -56E6915D344495E82303F067471E323B888A61ECFCEF90676C5F490A9DD6B6803C5789FC -A7B0B7A1C7EA4BDEF4463CD5304C626E8D714619CBDD4C4EAE61EA1D2386642DD4DC77CF -3351FA6ACEB1ECD55CE4308DFE9A09763EA427021D90972F2B8711A98C246FB448FB3FEB -9887A101F53321CE647B3B9CD077A31915269E6D049E48305F3B2E84351FA7C2394520FA -BD5EC8CDF9EFAA99573B1788E0C77FCA125F590C38939FDE67561BE1EB47575028ED1F4D -27A7094B0500824F6FEF2710FCC5768F506616AEAE73807BE2ED2E0DD4C1A337993C9A62 -C7601418A586D038E886E1E22843C38A9F34845DF71AEC30726E9AD413A84081F1E31A53 -73D5CFDF816D8F6CCD90C2B438BBF715F0EDE86DC31341A0899CC6374C573FCF2AF67A47 -5371828212D9AA17F18FF25801F83D0AE19A4712E24C2C024A7505A2FB269EB3E7DDF59E -7D95DAD916A5D35B7D16A82764DDBB3773CB0C6E3B1F2FDCC0553B26795C348B6C0DBFEA -E7CA7B74D90257D8AF4F9D4F3C776D858CFD230781D2D6F28CEB29BF4EC4D413DB9B47DE -E4B36F6CCE14C09A033D580D573C21B4A45DC172C0EA0DF41A0BD5CCCD6479166B30961E -A2094DF2262D9E81465ED2C66BBF8B28CC4A25CB7C259BEE2C2F0991614D161B25D4635B -C869B8008A2156BA56B48D6220DEBB6713A035003DEAA0160477F5BF7E336E90CCF67155 -0A55B6A015468E8A8FC8050C979178EBE2F7434E11E6A77E2F99A133F81FB87A75F42EC9 -AE9ED23A3DCB35312036CD819952BCA72525A39594C79C52568556C3A90E95C6E789A99B -04348DFF652C9A178C5F88EE957D2D037FBCF584AB699B276AC228DB743B4C4548EB54EC -38F6157163A870C35A4A7861ACC66118FD3EBAF43154C13A4FB8C52AFAF5F7FC67571D85 -F994E66BA3E8ADE5973138F61AFAC440C1EAD910FF8F79B11B73C697FF7D921266E48D51 -DA2FD0B438CCE7BFC1A1233FB8B5D812D8E18846B6401E9CB3A33C514693F19CC21A2500 -FCB0B0EF63EA74441BE9BB70477A63A641B639C54F93F4D4BB8E76D0E6F49D134FEC890A -B6E118D754ECDB3FBAD7FD4493AD9415ED13C05A0FFD949F3363CD400C5E2B547F1CD6FF -E503F2F4620579B69415F4BC356F943868F198B4243D250992B83BEBA3F07930F0F93366 -72AE171AD02B20606532EAA8F819AC8968430201EFF0FE42E8CAB1A10431FF0353827919 -847B2B20B0B60241ACD440C8917B4D0723D44A5FDBA7681E9541AB784B1A109473D3AAF2 -C035C27419CE30E5EE3C62F0EA884E4D4F164776DFF12D212629EA3AB2B103F000BE0A92 -298F4D73B79AF1929DF56280BAC6F03ED3F9DCFEF4B138F88758E14D4E90C95DBD9FFC40 -173E6F795689C812D24BB1791879326ABD3CD7FD2985FA950B73099AE1B86959E46C4709 -1278D31A41B159811140598A24861E34F2BF09ECE88BC36747DDD892AE3918C41A961D35 -28D8A8649E626FCDC9551E073855DBC34B57F6D198831CC189FE1C452FCAF8980998D621 -F31D2B9C7794DDC8B32FF3F8BE6934B03CE603020E7A37B51DB4E1FC33F625A8983B95C1 -853A1B1B4D4F4942562DB9A0FFAD4AD95A977DE81139687123317B757CE75ECDC8287609 -6D7797D50287BE38960290831474ACCE3F57676811A5DCEC78E91488C53167DA013E3797 -A9A8C05968C8888B2A55EF2032D66F6174B61CD24D0C62BC49250AE6D9B505371CB15160 -C591809EE7551D40D3CBF88D33F8A3A9412E6221D9E656D22083980999E405957E9D5A36 -64EF1F676EAAF5FA309D23C56C95541E7E51958358B436DC4CA542DF18398AB8E4D05FD2 -D24BC091DDD9F4F963A20791D88703056B5AAB84655B3739821EB288F1A1182F67154973 -AEE39C7E8CA894130CB0A9A811A1DE595BF12D04EA825F2A11A365CD1CA85D7C7F2DE801 -985F64094A9D168AE1F9CF287CE99031D0A1742DC08698572926219E0965501497C9D355 -6E9E32D23BD070BBBE905C512C864DCB8BD9E8AF46FF4CFDE9D86E8F34DECEDD99E8A745 -E72885340086FC17EBA499548D8C535CFAFB42D202DF4C91BF817BB786E577C7508CF99E -A088D9B070F5A5201D23CD76C9DFF960F0A77EE8CC94FB5CDB8707F8A7420B7FC2AA40D0 -6E04F60C595DD66DD436A4E2BD606121E423E0177B17E73CDC168DDB7806294A1A2DC177 -87C4296B2BB174D55D9255EC44CF850A68DA75BE1B577E8DC80B715876712DF29CBFB81E -80BE970CB01B9F8018C381EE021B57E01FD3A742CA387317883EB3F06FFA93E0473BDF27 -98D77D6B3A962CF9F42D181FB4AFE59DC053F2C059035649A646F22A927A4EFBA9E6D3A0 -2C7762AC72BC6827D49171F1F57C354FEE5E92E96A30156B8484BB3D9FE7A21B59008AB9 -9692940D35EDFC207A14D20D2FE364ED08F54A255D1F434B432F00C67863997266F64862 -D92AF31C3C7961692F6952157C8922AC8C8061E5CE8E4FE5E024C1324140354E9DC3A768 -B2092B0184FC1A46FAE459AFBC0069ED4C2CEE34ED7D756D65A7474B28FE5F56F6E69150 -6EA2272C75943E3CC9CE5FEB2346AA91136F5B306805EC51D6BC12E5D557F1F290E14CC6 -043CA5CD3D0EF095D4E62BF2068072ED630BF1451B8A35DB5783B6496DA31E98129FB96E -02175D288D2854C505E2403AC9AE94145AF6D327270DB865EFF70867894567B87FF7E5D0 -16848740741342E871BBD632ECF7673E1C3ED00255BB34A67D709E16EA1E0BD24F6510CC -C1097402E3994605B5CAD28A48DE6F37787A77488D8C62614F5FC3340E952066B61C9DE5 -1EAE3FBAD5D8B5AC64F8B261BBF06FC677A28EB58F4C8A08A136AF3FE387E24E6B100774 -24D077650EC787BC8498BE6D7A1DB54A690C768825ED63AC24E62E40D5CCB2AD05A2675B -301C895800F08F936C7175F6BB3A5CBB86536D5EF41B111F3EBAD9769324DA1D88C4E835 -223D976FBE5B9DA39161F6F3A7BA02031BC20EE1143E1FA73599CD30CD43F0552510F0A3 -67E8E0963D12B74C429E15BE22C0AAC2717AAF021D437A784CCFA60E8BE2ECBCD962B1BB -EC8CAD0439CDB73131D32363354CB9BBAE21B01A27830971D1D7B842E3145D5A400BAEE3 -76C639A3B5D2AD8D51B75F7FA86465DE401BB13FDE3407A093479B87B0E3B2BDF33E9569 -6501ABCD07786B1ECF72DA8083FA1D79873753B466A0423F1B504236B95C497F39F5D5A0 -0417B3D8AF9721E5F3B5ED2DFE47D9BD0930F4E9234F181CD24394891F7B554766BFEFE3 -CB4533E3D01DD656FBE2C170B82393C0F3BBCE9367C9D5735AF8317450C7F4B163CE95F2 -6F2F7DB25CD88EE9B01716DBF1FFDA7FF16D54EA39841BFD3EDAF3684D2298ED45C8486A -F5014230F331FCFB320D28D5A1A17D02D5593538946C8669B346F4693FADAC663FC608C6 -E091F481E1C39749D26AA37062D7D94115152B214506B91617E829833AE67807905C70A6 -8412293287EEB2286A27DC7D7B9AF75FD4E32DAA4641EFFA2A79A04DA0EFF958F411890C -A50246E5A1F53315ACE19B22C9C14B897272237374BDA4221E3FD18A7D4E26A09DE3D246 -D604FA90092F188E4D2C6C0144E6D49DE9BC8ED4561B9CD8EE8D308EAD97B6150056AC9B -9551CDC472A642A9DA02BAC20EC5B57698D68ABD0ABF1B0FB5231479D72CF429C39DB34E -A75AB17BA21AB31E9DE9E2584C2EEA8BDCA322F0D03291CEFFF011843BD70C43F49551B9 -B10DA24AFC0B79A87B6F493EF73E690A4A705DC8CDE5E2602EC6E99168357A69816EA5A4 -5945A242CC85BF5E7B665DB8276C11483E879A1F9A59E4FC8D6B700519ADD96909BC3EB0 -DDABA0BA75AE8809B6B802FA830E63583622109614A63B928AFE297D434A33BD0A12ED89 -0C15CAD72DBFA7EB5F30B12077EF47A6EC309ED1009141176F7932955588C053DF307C96 -B719564855ACC024859429DCF8DDFB3F7ADE1BD65C9B6A97BF5A56FAE58F41BE9ACC6AAA -B0356F58900CF66FBAB2E2439C031103D8600FCCB20D209DD510DFE90716F654C539D349 -99130FA43BABF53F8AE298F10CB073B797AA50E00FE9F88D9337CAC4DBB0FE101C28283E -6D4DB8FAE80B4A998525F647E7023AC5B9BAC987D5A9233541214BF0DCCE6C524BC1C56A -ED18B4F76F8010AEB8E1024082D22AB60BD9F338AF6228A09E7DFA8438F2ACC066D2CCD8 -853062A5818DA00F1747B6BAB166F40D7639DE8CA985C2808B0010608FC7923C7771F728 -FDAFB1F118E2640C2C42301C465F40817C13E20448F16AC7D42E39FBE359F744C12DC67E -99A4B92D9691E1F6D2096F11FE4F017A4C2B22E4C550DD25E3E31E8531CE8DE879451600 -4C9236E36E8009F5706C8BEE72F007538DA5918999B97C386DD6D62F7B433DD99B74B490 -263C2AA2D059D2DE95CC604A5442116DAE3264568FFE88A9B1E4801052084DC11101EB03 -E514E220E7BA851FDB7B5C8CF635B2496FF38CE6DAA23FEFE02C25B520473E5E07EB9354 -EC2CB7A7A75FEE158D51A7CBE8EC36DFCD038BC52E9FA6483A5F4815C132B2C40544B08D -8C8A80B1916609636C2B53FE27E2B4715852A6F035C139F9EFA33ABBA2550B8CEB8F9C0B -EF80BF543D1745FA88347997D01BEE8A8E2FD52FC40D3BFD3D438FCFA1CC5B4082ADB51A -5EBE54EE1C95DDAF8E5FF6FCC98C3336A292A0FA05CB5B48C122D6A3330898979AAD071A -4BAC19B03B03CBA077252506F8E68EBF004B962BB85B15A87FE5497E8F2E208117834E48 -62EBA7AEFBA9A8997F71142BD6F6550F3BB358738B182A9CDD411159DA92B0B3E49E4226 -627A196036ABEED57F176C72B30AE16C1C01B330577FE8FB0C0F7E09BF821BFB4F056A8C -B52D5797C0FA48A9625292440F76387FFF46837A2445688696830AF32EACB2B6096367EB -A8C8C42341D2F3EB5D5190D9F7241FB1EC16DF0D6D40FABACD1D7E99EEF4AD6118696165 -3354A8DE539F92DD3426A196A7DC33F92B170D57E48AA80902D9F31AC582A4B569D15C86 -A8E6FC94D75970BC6BCDF2C77318B1DBCC7E398B48FAC8D2E392E93CC37F0BE6186DD645 -EB077151C6F58EE8203B697010EFCA123FA904A4EA80388FFD88C126AF7F6656E66B5417 -8134B77DB4E0797C9213483E787939113C39215FB9F5B3B141512D962C500863C2F362C2 -3B73E9AB89571A003E413435A02FA3569228CC6C0D5EDED34373FC7EBDA1200537C1B72E -9FAEC2E74E5E6C3E13CEF1B8F332E7CE6CBDC4A17EB9CC265638AE57E28E34CE99CB44C4 -AF96FE97893390FF2583486F7D8B0B2D9B13A8DC0551E8AB85046C9E4091B6D5D5B193F8 -3EB3E2131A6EC9DCC9DE88F4B64E45AE7B5B6CF10D4F812C9C784BF65FD9E942951AD808 -FC9F010A0F45723593A354E578F8FEB67978485F40620C83EEF210B6678CF323437DDC88 -5436567D76EEF3A83448EA76A3306CDE9D5045FB2BCAC94A7A58B21C0166D5C4339566C4 -203535359326524E7AE47FD406959610B24FE98ACE978A82B5F644B112EF6A289C018244 -85AEF2D0C38178851D0D5A6612C861AB52B46597558EE8E588F95BC8D657B02AADE2AA25 -9BDDA214A736CB417F9564699D293A98C7A7615F47806B5424CD1FB7292AD1F2D7DF6837 -675AD97FDCFA6825F4E22A4C0930299B0CCF9BCC67806E4E6A8EEDF449D96634C19EAA00 -912240EADD63C8FB02A227B987A17964F5C867079495B383FAE560309FABE8BBA46C3F85 -E766A98E5B8A980DF3205AFEB8416B4610E6853409B658DE2A7A3C2C6A292FF33A46D9C0 -E34FABFD57E19C89A8F88D8C4798A96F4C8C3655808FF336C7DB56F52E0C6AC761DC0E0B -39E33065A02A8812D91AD303F3DA2C1D61913C76F1D2DE272503B223ED71DF65A5168433 -A7BB3C3547A7E6A5A190F200992B73151BB9EE0D8D55F9AAB9D2E73677D3AD16D20D553A -D7A7A1668B19F58E7BB9A5CF973A861645016DC2D07A39D5430D6D1644B88035B8575DDA -D2DB0E6C040FAD93BD0B8486715821F2D47814EBC7EACE1A5CB5D3A2E19352EEE008F258 -6192627BD0B3033199DACE43803176F7A19946985CF975DD1BB313DC58DDB80A2671637F -E89D6354DDE8F8825550F1F616DAFCE19CFA095A36BC49B8437C00DB2DFF9B82ED7226A8 -06020769A534706BD6180DDBEDEA953C98D639FBC8130732B42F0C512237F541ECD03603 -8EC9F5BEC45B45F87A324B60E13280A18A2F6F333C34CC254464F774DD53906B7FBC79C1 -CA8CABD58310D272CB49F4B3C83EF616A9743CE5C56BF52B00776EE469A45B18B8457CE9 -DEA7CD6378C87304224B578E213AD3D9E5FF6E642BEFBD59162DF73F0B631C8831132284 -39374839A1DBA4C4B4C4E30B7D411B5247F258F18A8723659A17A52F8194FD810318B32E -19DC9B355C028E98A36545D65073D0F8F4DFF0F9637C6F599C2F883B10FADE5077B49257 -F16D0ABC0DDD9356F6B10FCB64D6B6ED9888E0312B092DC9D154CE76AC14D14DB564EF77 -0EB48216D431D21672D50AA13307610DA45B3AC8FA46EE7F61D0C643E53B65CC659E91A6 -71BF448EF3FAD8D18794B383523AE67CE1903510BBE2B2D5CC5D29F3DAFF71A54E582E22 -420D62CD7CC8A4E093207432EE4FD0FA3B2E72E5E4E62B450C557BFD0A83C540C1FE9E80 -C62D150ACC0CBCE73BE88F13D7E4D9A3791C806B38D12315C043CC022AC8CD3C61331345 -5D19B2036306F132C074043CBFED8F1C1F60C74F074708D3755A6F28628B31C0D8068669 -C8BB86C6412F32C8D6772CFCEA101D1ECC32AEEBDBE423A7DE28BE36D54D61CED5FABCF2 -F0E731800ABB9B10E413129331BC441F80A6617F9A5E551CB4BF74893227C7D9DF21DC11 -6C7E796F8ADEB43D2D223B4647DC5D53E65786C5A0DE8F3CD5BC6662B051291E36D47414 -F94D999AD31C1D6916EB723436B41A72844806C0A8D4BA41A04F1848DF180A3C3E27D8BC -961FC8509CB3D4069B33C5E01F3C0B04D55AF2EC4CFC4DD7EEC9AC9426CC907DC70D9EC4 -E428D30D8B28A27EF202E3788C5D14B0AF13D750EB7A8C5C4E5141AB5A477BD660753B64 -EF5C871681283A0DA5AD98DB70A90D72BFDCA0E18450D3091EFAEBAD23EDECF3F016BCF3 -BFBF286FD52B5D38D3D02E8161F8485D3B9B78C485A196C5CA052DFF546E4CAAAA9F9F8D -925E6F4D842B599E1A482C92F8CC86789F192987C3750771A11076C35415FEA472B29595 -9A437980A15C2136D26C83DA0AD724B1E961251F80B9D751A89A004DBD66C2540F758AE9 -A8D9A87A40CEC4A048AD21AAB511A630EE7C6DB0BFC5516B18140B0FB30CCD128475CF08 -1B10D9E5DED0BE1ED477142BAE698358D9FE9090CF0DE3FFF6692A18E2AEFEE40CF40B0C -AC0CBFAFD61CA62667B8C6AF75F2C8C610189522E5C334C3EE4C5949629430D193846DB1 -3F2F49284722C3D93FA7553DB263182610D960D1154CE3E72E93D477003E26405DF8457E -919785328FD7A0EC5E75FEA4A69A4B83A0B1BF8A257C95DB99ACE02E4E1AB1C7381F70EE -AFF4424E5DBC89F8744C31CEF9E39CBE52AE7B222C3003ECE5CDB70CBC5705BF14A8DD96 -858B2D91BCD9048CF5499B557B47EC7EAD4F691D9C0ACB5AD0EDD67F18D0C60BCC5B26ED -977B54870AD334A5BC6FE43C10EFC67449DD1EE7E447AAEA62CBBD3708A5C53B50D9A422 -D90DED5D2DE9496DCBA55431336DD959C87DB3C827D74142F295A7FA2AFF3FF16B6B3A19 -1947BEB998BFBA0058C8A0C851E677368674FE190B2498042A1091F5DE30DF16380DD89D -0F8D076F0AEA1FC15F065FB5F094FD7DCB9BEA369B473A796441BB35C3F7D083CDBA9263 -3AECE8EE5EA3A475C84552463F714F38F73B83ACD3DC7FDC9731E55C25735B62EC439FD7 -421236A8ABF2E15F572D93F863CABB5104F2F71C5CD8360ED6A16F0EA6E20965EFFFAB3B -9AE5935C206A074C7C3A21F8B50E6E19950DC462F06515B3271974877B0C33B7D2F735C1 -06597443E2C5421CAE134AF0E035786DE9969914E2F0B8982F9496D64DBFE6DDD678B875 -9825EA82937D32C5D3DF19C9F35700C733C65D3AE498C2039D41BBDE6CE9D975E753A022 -67E5354D1739005A656DEA77ECEEAD9D8C3B85512D8BF6B1B5ABD84B6D05CAF87B254ACC -3F650BEA548DC6EF6B1467BEA6E424945B7A6656F5DBC695D3E5434E0B88E5BE68B5BDEA -9F91337F7A74A5E7AECF9EC30AA070AC66E8B1D8AA70408B0F11683BBDE539EE5DBF9D32 -9B1A1C8CC14407B0FD0BC4E282D2BB466E3CFCB7E2E375A0DD49FEC7A0ED1CB15EBCF2E7 -F96F1094AA840E618E69EC295ACE5999BE90F77C523822EF0C15585CD816D7918D2AB0DB -65CB72F1AB5CE5625C75B493E801D7A0DEE575BCF53E4F0BAA2290275470C5F6B49BCF03 -E4E8E31CE64D3A6A6C42ECE25B6BE2D2D8D8A821C4C727806944639CB4DC84777A2CE101 -8CE5EE0470D863ACDBA2B69B48EC7EBB23BC73760396F13BF6A60BB6D664D7B553C2AE9F -32EE16F06A114A3BC7289747FC6D85BA0332D23EC947B25D6C10750A83027A745C1737AF -E9BBDB080BEE663646BE3894B184F9B892CA8EF2B3AC255DD53388D87859F9EAF8BC82CD -B12EE266A079F78EA317C41C505CDFA41B1CDD8A63B884DE1EEFDA7B7DB1EF77D0E98742 -79C50B55DA61FF95BFA7076ADF6BD3586E2120666BBCC3E431CBB19963982E50B9B1F375 -55AD6DA4AB02B305E074972C7961D66C1D1327AB93813F7A7C6C860A81281795033C8AD2 -8FD44E1AF0668D8ED469DC184B612DAFC1529F3AE5D8420B703821A559D58D5C574C15F4 -9C6CB20FCA5AF432FAF63E73F23638129D3E80509C0BE0034458DDE29F5C88807FE1C90E -5BAC2CFD565D686945583260334165D27B08EF3C7839396EE421686BBFF67996E5FC31F7 -C4C96155412C4E51D5B6C97F6C47AE74BE984B347222CAD8B76EF218F34CB3BDCDBFF446 -C8E52F3E2A121903E260C844B093439194BD3078E158273B28A7674F0528C9306CD09C1F -8D612881D46B8D4AA4C33206EEF23F0DF150AB91D4EF3A55120E3CABF490A2FDC34F85DE -0B4C3E712D3DE425B3B0B5053CCF7729D8FF20207EE09D7ECA11A2685FD4AAE6275B9C0A -E26543A3F0C826FBAB318690FCB471623009FC751E656D31538951000A413132B4C95E2A -75C56BAD12A492F5F44C14016CE7751831A892BAF050422E459E71A614409DFF87BEAF8E -9D61471C279C9B2981C3A1D119678516111B965A060822114F9CDA77DF46059D434C6A0D -D4E57EACFDB4560FD29807C7160051BB778CDD807B3602F6CA02F699E8A42C7A6143B149 -2E78C8796116ACC803B5CEB308B9F8E9F11DCE649719618A9EF689919605EE6FA001E178 -4A008D1D5AA354777566B4F5D496ED915709E2FB39688745DFCC3AEB5D520B77C8066429 -6C67D95C50FB86B9DFBEBA2AD8234EA2C967A02B72DFA5BEA5BEB8DB4A30428FAC98FB5E -6FBECB93EABA637684F4A82447EC00D422DB058D521299658F7D392FC1B0130A9B995477 -7FC2011549660457BA46B01E4D7AD51D1829BBD0C80576E893816FF1355C006FD22876AE -654B0D851931E1BF3E80090B762846ADC7EFE333D7C6D529D6B50FA87347EB35438B18B6 -DAB4B45CD3202370F744013D15C01AF637A755734706E667AFF3A498F437465B45255BFE -C519F8BF9FC37A61707A8D70F26AC6C90C73AC9CBE1A2C7F9D607BFDC999B784C7D15BAD -C0CED80AEE87A20D3CD2C57834020350B4310B17E62B192D376EF6947C8EE477331DEA66 -CCF090F1787B19397BD8129449C47D5E03EEF8D4B8238105D626115DAE76062AB6A01E4A -874EE181607F505FAEB9F8743CC79A0C674B8E5BD9EB8D02A5653C8AD1E6CD5FCBE83D12 -A64399F646860E564F1E118C5F18ED59BE775F93A3CDD8F1D4630A48A43C0F2AC8DA9A45 -7562CC56B57A802A3F8543BED0A96363529DD39675BFF7DF6F532D190BFD5C6B8AB3988D -6D375A117DA0C00AA1C9AB60C5023D52793CAF943B7318DB12377D962E53DB536BE2A1B3 -0199D481CB100B3DFC30F3D01EC4EB8C9CA7CE497440C54A12F1EFA9B50ECF7C6AC073F5 -12AC731C94BD7C24209A1BD1340DD6CA5C787E42DC97E23B125B786D4AA2B149D05EA6AA -891AE6BA361D1A42665E123EFABCCE667BD894ED319B8CA398EB6A5E213F813FCC912F54 -205D51716450E1744CB2A5A8612EBDE46F35257AAE6D3AEC55D65E07C50736AB52295D2F -5FF8D43AF818B05071354B5A462DCA72E6A5E482A807802A1DC14132E50425E75C6CB612 -F558228B7659A6CC4F2BEE307FFA31A861D88C994C650DD0F1845A26EF0B8D975B9E2120 -D6C669DE20802B62F23867D708EE1FF1EA35CCD53F5CAEB8EDA12E12A58E9F90D150A692 -194564E1DBB173B1B3AE5795460A5D1204F1C02A960659A0C0063A7D5E7497A581B0972B -B235C90F7D2F89D6F1279AC5A0A15DCDC5B1391F5E5C94AA03320AFB4895AC4F31F28C29 -3D9F6790243F7070E0AE21864C7A42129AC0EEADAD9D11CD447C307ED64DB0BB41BC3BDE -C9EDA6638EFDBA140CA92B7AD459482B2F573E29B03381A23176CEC332BBD7219231554D -C5FE2C2C56676A137945671D5F55E080EF0306681C44B994A5FEB444A672512C424991FE -6D8D33D099D464B44C8365D37CCF13792CD726375A5DA9CFFB56A5628FD564DCC124D2DC -4FC1E2AC8C0CD8DBA8E27138B3B5DBF786AFF59096E52C999D6A26C5637F277FFEEF34F1 -841A3420594149463AF075107E62315AA0B2D78CCF9A72D1EB9CFD1E7900B0CF877BE2F1 -C7A0B60A1D995F2C5C37F7EDCD09998E7B7E3E2A2C90D4AF8F9DB1ED529B9C3DFA0531A4 -9359BD1C4BF3B82A095562D38C7F15C3FDAF09BC39B670A529B9B7EDA1683D2410856031 -5737EAEAD181EB46EC51BAB3FE026E532E65F7E76A368C7100DD7AE43F881B45DE624CAB -E5AEE7D7EAE8CE12230A0336A098760C71E0003321B6F512527AA59726B249BA92A18C1F -1508D2E3881C1E004B830F9F24A706153F4B4565AB16978D608184FE0FCF816F567911F0 -9BFB10C7FCFE2CDE6ABC0C83657809FB8BE214E5570ACA4CB31226DF4F590BC37EAC8226 -DDFD5DF293A15CEDA79699E59CE459F1BFC0B08DA76C1234F996BF4B2B345A18B1AEBC38 -C04218864D6A7ED071173DB25DC27B8FA8A6DA897D83085CDDD24B3F3F1CF936C74B61F8 -020620AA9114411700938AB9E9269C13F97723E29E86EB5F14D1E86D15E8C8D678EC3CFF -DA4577F97BE67A8D3F60F56CDF929524E00A400C35BF46F64134324791FCD6DFB72DA7E7 -8B7EAF388F8D3C860E8E295867BD9032E74239F627DC645D0F2E99C6F56E3DD919447CE5 -CD3126F491688A53F54FACAAE5A14C796CD964F693C8556103BF132E93E2D9816282CD3F -32B84CA3798DD4675F6CC06E0A26C443E8CC9AC465E57DBBEE15BB206798C8ABAE8BF0F5 -DF4F029FAD45DD95671892AA63338E63779E321AC933FA3FFC368412BD62387E45BF0808 -7C3594EA7E6628BF2921F2AD33C4A7AB22DD7EE3272150D07ED085C5EEF85F5CF78FC9B1 -468D9698273BCBF896DA6CD43E088F7AF97AD83BF300817D35F93D74FF285EB6ECB223C3 -9368103876A36B5D84C099136868530F1DCDA96B56560E6B0B18D2C66C7FED082850CA25 -E7947934A1B66176B5C332CB1DA71B6D49754A06873F8C37C2C64A16442F0D983F6B989D -8153F027A9C8FED72FBB1C2A7A56361BE460D85338E47D0DD878336B040E685C48993D7F -B6B12CEA753190E47BDE31F458FC098A286EE4EF94A0804EEF0324F92643B4EB5FF1767F -9D0A99B59B1CEAA7FCB5CF1AE8B5E70E3949B085287554E8BB456CBA6EAC53040C589860 -195605D082EBF7E46BC4A7D2284C6518D8F49D524712B15981CBEE064FF6BFAA6BE46386 -BB84F6C20D8D0EC6A18A6B74C30A4BCB0F2B81F100A6E78DC4EBA3E6B9788F424467BCCF -FD6C58F5DA79A9691CB6D74DCD537AA085D385318AD6EC7C2F04567BF97EC15A73E963F5 -37CE3F70338D0E3994E0C9412702FD7BAEEE2E7A35A65E57FECD397D3EE54C863E641E6E -AC90E91A8C0F00D839B5ED9D9B2D7D78088907ED499480BB50EB9EC1FC3608A8FC1A20D6 -0C1F86BB28318444201E7E9F0D812D71B125B467BFBACBEFE734A7635786A7AB03AECF40 -AC5A6262239EF8E0F538231D2ECCC1720CD40D56CDAF38AFC197BDB28AFC98F57FC9588A -F65EE7268ECB44AEC3F5DA1453F0B4021BDB7D7829043C2B1D55BDDCF4687FF7D5092824 -30AC8A512FCD528156758D24318A9CF77678F040D05FA800B1910B33B7E12213008CCE3D -B9A5E90F708B26AD23F82CF3088D030B0559A6598FCEA3392073693C64AD3BFEFF0A05C1 -C9BBADB073A756AF42D91F8D88F0839E32C317319AB514A6A24CED9082F6473E2B983EEA -6724C8D82ED94A9A2BC4F375DFD2C84CCF06F9EBEFC67D357441CD976F0CBAA0C8BC2DED -B2AD5B5CC894AA880A164B68E2F5031566D8785EB72CB183F23AABFED617A6A9B08F4B8A -203D029CC05C13537C2FD2C98FF701CBB7FCDCFFF2DD7C1B152D68FD70E9F15ABB7634A4 -CC1DD8BA1F5EE887060F223B792F7D204A338B8A3526841D45D872DF6DC3A9073E4A828F -B70D993043F881AA83A543EB448B726197AEAC9A78CD6456035E5DCACA540D559601B595 -580EAAB91811B756A069A6EBCB887120F245D9CC70C730BF1F7990D119BA7CB75B5278D9 -045BCACF83947457578586A93E32B03E95942B3C036A21DAF4C6F0C5852EB71499C3B9FD -EDF36F528E9A0124992798C4BCED2711E4A2BEDA7A7FEA0652962B4448818A141E81BDF1 -2F11F423BF5675CF46B506DBC8FF2C4695FD27FEC069DF0A43B7136791E0A3782FC4C296 -9E06336C4F6109809F6ED605A56D1330046925FB5F62032E0E4E2C3FED27427C8B766C2D -26738A0AC701E7FD89EA4C9136E5F82306DB83E2E9C2B0CFADCE967B2A8EBCEBD67544A1 -89614D6B61E9C77AA77E3E739C03D593E00B07EA925F6321FF5B8F3C0FDBC3948C6D649D -96529559EDDFF57ECA28B2C0FE35D90D010C10E6E1B826CA23415E17ED863ED5715E7B4C -075F0E1806E51DB91E55AC8B64DB7731E8A33C1E8F5C8FBE17309859E5DCB58D10D3F658 -05923AFEC306B4359EC6A6E8F9DE3500799B7C7B322204AE472ABC69EFC886C11DE790E3 -603304713B3312C9CFC76ED0E421E2A034CED3E88D53A8D80A3F28F2CCB9E3358B152EF4 -421447CAB89C002C355274B50ADBA185A44A746FA19D7D481F7CB902E73E4AD2A74A1CE6 -3D9978AC3BD8B0DFD03E09425481F63EE2CDAB4AE17CD75A3AB05F9246B3DDC3E0AF1D9E -CBB521D540C01CC26CA6F3AA5BB49C804D312BA93E92CF11F6BBAC18A0EF051C52C41191 -8C01263AB5901221AE0F1BA6C924B8F937B49985E6D5C17B54E39E649E6D023F0AA42BC1 -D75A384B05519BB0E4118DEB70D272542D60E64957B749BB76016A1D356C681227228948 -5D89E1CD945BF9DCB49A5B831C082755540A032087A2ED82D166E292303CB1180C49E739 -5E403D0C5E6931ED6E36B52FAFE37CDAE28183F15C8AFE3DCCFD9A48A4BC21669E4D3667 -0DF71C4E6087F5B3ED2FA7AE8B5AAEF2A27F063332527B09D712CA18521744D89F90E9D1 -3BCD7EB332AD7BA8055BB8A859C4C16591FC3CE1474E260A74E3160DE648F815383B0310 -DB2FB9A4587FE13A4E909A83594584CFD382F05EAF8654DF5B44E39496290A7EABC36381 -8978F6C05B5EB3838572EB0C64C1D81E9AA0906FCD84E62B68E2D3BA876D536E7794067C -9C2370FF2E2E46004062B260CBFC29CB5FA0219C2EC6C8AB8CC4418ED8FDDE6747F8EFA1 -76A6C6D1276845AEC38B41EAB3727BBA0462E2E809D76E0B5BCAC08FED585BA6E5D8D0AA -3A36FEE108F55C23879B62C0A425F176E3C8C9031BD8B3E1B6C3D8DC383FDE0E36B33901 -50296F6869A4FC7E095517136B547295D1DEBFA341EBAEF34A179B070EEB60AA91839D97 -AA51768827E4A1CD55C5303D1D99341537B13FACB6F490072D8139BBB060FA1A02C93D3E -08888E313859B439AF27A3E5E7709BDA43F851D13AB5B2EF395A931A99D0A2FD8C6088FB -33D318D8EE1F7C7EE2D2199A638E3858EEA06B3A167F69FA5AABEE4558773A75610E7E30 -F3062576A2A7FD3E9F08FDAE5F1931A7FAEF85496071AF8E16AEE74C0A756927E0720708 -7846DF0F9A7C5444D007729FB69042683DFD7DB0078199812F85FC9DFF1E45C77C104F91 -37787E3867D5AC37FD7E86D52AC67672D89F04782F980EE918C6152DFE7657C6798557CD -ABC854E81C980DE5AAD8E0BC259247F73B92572973D482BA7E4F619F50B0DC247ADD0997 -CE4E98A71E4A041F46CE605D32AD047D2E4260033C3FBF80525396507815EEF46960A904 -1B83CF32AFF7712BE97D636B4162190F2D13CACEC58BB25E89496122D23CFA6676E790CC -29F48483788C724531BB3EDBD557950162907B68541B51ED6DD74C06C2BFD5346CC819CC -8CD654F17C9E798168C90DDEEE78B6AE37709D35923AAC0EF066146D93C8179832E1A7F0 -44C4637E560853D227D3A14EA62E2428567E0CEBCAA3C43B0977DA30251BCB74E445E981 -6521CF8F1955A9BF920121E4FFD1E022FF42581269DAEEE779282512DD46BDA9F7BCCFEA -77886D52E0B6A9C64A37AE0564DD09B4868BD1C6860FBFBA2FF022C291AAF670DB7AC717 -D82F709B07DABA0158FA67C0BC0DE958FDA1A63ABD29864C005FFA7FDCF73AFFA597D16D -51A1E16FED7C1E8DB6972353AE498A9F1B0AC3B778675312C7F01A7533E1A53F31964A3D -372A140EAACBBF7EEF600F69D8C466905CC21CFD1D1EB70B2469788BCF405ED84412A5AD -04AE871A79DEE0797426510EA8F790993002857BF2BD33963EC10B329A596226AAD8745E -EEC9A84BDF4793293D941756C6A582D273467EE704A878C40A1F8E6F4130DBEE6E484582 -4B78AEA786EEDF2E119F0D563C969A64B29F13327C52D03A16CD690341B2E0CA3B622F15 -ECC91DE30A47C82390F5EC38D3A52C24D3F4ED18E8733C1635C25854F05C394686913404 -E6A11B597213B0D506EC7EF6B9A6F4755B5A71099AD0FC9FF11244D70A5B987603F59AC2 -A01F251D9CC39F24FB322ED3FE0A0014A412D7C9A94088C8C2FC99657219FC27B299FBC5 -4E08F729AA6C013BB76CD320B23DDE9D9D9B78A34E6424BA1EB1C95B5005A53F90D3A2FC -DED3AB361A9388D2EE3FF47F4F9BFB29A1375351FDA929DE5A89346D7BDE86588EA5F95C -CD052B256653437D4B9F98F82A4E9D860B9E6CF4616E80E743936059A3ECEE59298A2CA7 -D83610215D893D065D73A0079E6BA899593C2D46866E980DC125DDA38519F181E20B026F -86B1CC7ED4C00C954146B530CAA58C3C52BE08BCD25DE61A6D7F8BF7C7D1E325C4D2D610 -169CCA13C7AFFA18DD3907C06A0FFCC09C7033B9B721871E31E4A25DFF7FC74899E1886D -8F3BD163AD7C34FB6A948C0FF667D97C8E918D8E663490CC7BB6AAF3689689725C07569B -D17661CB0990AF49011A3C324CA124C4CF555C021041B7D301FAB7D36518B34771E424AD -B62E962D8B2C46863DB108E1316AC529A404741DCB27DF4A081965B96ECB7C4564550BE7 -78629AD19568AB733BA2A1599F585BF5132B5B5E59F51BCF1C284AC371799C898950667B -44E71E5FC7E221C927DA70742469E3BFC1813CF5EAE32F109A87BB258438A6B744D3D642 -5B3C42DC2C542A8382C3B7BE8A5C43DE7E4A123D4130D3ABF3E95568DE13C5A5421352A3 -5A083A98EE09EB0EC99C0C33EC688D2573E9969AE74329D3D6E925C568A5BE0811C333C3 -372551F2A32BD9E0FCE86D3D2E83379BD55634101F863DE3407564E3A1A73D8572341037 -A6E3AAFA61F7ACCAD510F7C17261408E8BCF0AA72436BCF21F69EF6D3128CDFF321A54BA -3014DBB6E3354197EA88BD4AB5EF052589E3635601EE76508DADC4E2DDD9B9710CD11963 -B8B611C5D089CF34D6DB9E94FA9696EBDFE31DA2AC089FB93B8F5CB31C301607F29494E7 -490278F0E378BFD712EA4AA99234E3205D0F4E0F0705F352B62574B884E571183CF1D44F -C911A617AA1F23AC0BBE3E088A84D04AC51349E3E92ED227268DCB4DDA76B2DE3B473331 -91087C2A70BC8B0554C3F21D5B5A303F6FD58CD4343F0EB68087715D0086C3938DFF43E6 -92F01DB8319C4C2DB1E2D0B41117431086D4C51B010420F52C94C4B2040FA0FF2ACC4A23 -8C44EDE007896F73FD591E491C9359598F5786978E481141D70BD1FF759CE62EDE7648C2 -9E1C59FA4F7F61A2ED8ADF9E4654F1BF161D7E19FD0CA8307993F2FCDB726E4C92412D6C -F260767375AD211B46CDF539D66B2CAD7410FEF73A289812B6DFE69F6E6F24A3E66653E6 -C1BC17BA415FDA7E4FD466433CF5AE80827D928EE9A2B4FFE178E37B01E8AF99A8A26490 -0AB2637E25B3B5F4CD857E7CDC2F589CCF52D546F217D9B48C894E11F57BCFD6B6CC54A9 -B2242A8A39FEC8578F3F7D9B726F977F78103E4C2429A3C9B96372F3622D7C6FAD2C660C -FC73A3BB8539853BB061AB6F1EF3E6447983CCC1131276693F0BC5C2938DDE7864776E92 -8C2AF847D27FACFB07656A2DCDA533FF094927D920E227E9618A47E949E20A61D97412BF -273AFB50BF67F54190D982231FEFD98ABB2676E59E106F5E3945BB9739A87DB7E0091FCE -97F86052A8C9E9A49753E66CC322C3051FA489096E2FA9C2E5DF52E439EED2B9D1A8D918 -E19A9C8F97FDC6B9A8982A1AFFAAC4E50899661D2BF6EE5EA6F1FF825114A1B3316BEC52 -EC64416C7161B920D7DE9C339DE346A2BE6792F82CBCFCE4FEE70F04DAAFE5FD13778B1E -D7F5F6BBC097FDCADD6808536570ACCCF31DEBCAAE581CE6D4C6364E58665C530026FD50 -1FC1B1414B0371D2BE2675E304B041C7E635DC98DEE3F1811EB0995FB3167480F31C8F8D -85E3B5F1054AB5B5721B7E8C3FFAFC18F50C8EB58A5CA56DDDF3FFBACE09BDCB27852DDE -9A1DB9A9C4A51092D145A41E07981235051BC56F9319F03FD37B28388FF4AD8007F98B67 -C7E8FA79B54EB9F249A0A383F7AB987B6EDF5508069528D49FA26659AF0203E73A13AD7B -3F64D294AFF49E42A76D493AEE50B099E049F8750AE058C2863FA2F4EF9EB18F6D2C11B5 -906194F7B480DBE6FE3D6610BD08AEE0078BBA1411B26DDF14B16A3DAEC2B18B29EDD557 -645FF36507654C2A86B7B2D18C5F886E8F02FA3092D35D4802AE25A6CDF17C469E85F67B -1964A75CF22A241F2580875F639ED480E7AAA04620C6C58B5C839F0B659D9D2AB6EE6E0C -80EEA564E9CF0F9F7F0E70410426047F0EE92451C92C483AE8F456FD95E21C7549392C5E -41018826DB42CE4709FEE1A86F6CF18A0DF73A96F8147AD819E5639F95E6CA508B9CD05F -D0BBCD49AA42A09A168987B7D8747E4D3CAFC699DC40EABBF633E2B6339A824058BDD026 -180BB7BBE9937EC7B87E853DE8308BEBA2D7B1156E0524DB6D983B9EA396B3BCB9A6E425 -8C55325437EFEC9AA659E57B07B838576B65B10A9B4A77304383D9540200A24ABE5663F7 -29C64D293498F678469024A1F552E508B49B610D3EF334279AE58F4BE914742752E9FE31 -1642DF1310E0E54CABB5CFF9CBC0A9FD8C81AC09D7762D9A989C2ECE1B24CED02D991D83 -1E6BBE94F7D981DC75EE82BE1AB6E1021046AB988E5147D3E037E447B1B38834F9FC48A3 -23A734D2DF86BF8313892964B6FD68CB8E4DC0B1EAAE8E85B137E34C22C8F6CF2A5DE4B4 -B914D13FE7C0E3B73AE8A998CD19BA81E3825ADBB97854B7B89C7FFD8E059340566B7348 -36E6FD18BA8B1B60EFD13DB954CF005A501D70673FA63F79FDFFC78571E075E0503A472D -A3AAADEE2A7EC2710E7E910C9B3866BEF6001C47235AF38A70553649D910DC9195389373 -A87A62E97BD65CCA58128204FAE813DEE989DC1E72D36AA9675A25ECF1B8FB2CA45DF4B0 -23887604842BD3626CC1DB5722382315912FBC9C383275F430A76AC081366D100F40E42B -7A4D3A3CDEC8C47E8C56C696A756EF3EC9B47CB9570EABDDD906EECC8F754C92B174562F -118BE4FF9E0E84E15BBE5323267155546449138A613D2767AD28F188442F1FD558F1D09D -2C296FEB0FD94EDFD259F9C0E11F255FA4C39DA709FF2AC75FC4259BAD43DD8B27127F04 -049683A5A26A38E27654DDFD99247AC366003DF016EFCF2D96C6B2F9858F21BCA07EB0ED -516C2BC8EE39B0C568FB5FD8886B21632AC942E7E02C7BB24E007A08E8F628D74EE676D6 - -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -{restore}if diff --git a/fonts/Monospace-Bold b/fonts/Monospace-Bold deleted file mode 100644 index 5474cd6d6..000000000 --- a/fonts/Monospace-Bold +++ /dev/null @@ -1,2354 +0,0 @@ -%!PS-AdobeFont-1.0: Monospace-Bold 1.15 -%%DocumentSuppliedResources: font Monospace-Bold -%%Title: Monospace-Bold -%Version: 1.15 -%%CreationDate: Thu Oct 27 10:50:21 2005 -%%Creator: mike -%Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. -%Copyright: DejaVu changes are in public domain - -% Generated by FontForge 20051018 (http://fontforge.sf.net/) -%%EndComments - -FontDirectory/Monospace-Bold known{/Monospace-Bold findfont dup/UniqueID known{dup -/UniqueID get 4234665 eq exch/FontType get 1 eq and}{pop false}ifelse -{save true}{false}ifelse}{false}ifelse -11 dict begin -/FontType 1 def -/FontMatrix [0.000488281 0 0 0.000488281 0 0 ]readonly def -/FontName /Monospace-Bold def -/FontBBox {-141 -1034 1457 2154 }readonly def -/UniqueID 4234665 def -/PaintType 0 def -/FontInfo 11 dict dup begin - /version (1.15) readonly def - /Notice (Copyright \050c\051 2003 by Bitstream, Inc. All Rights Reserved.\012DejaVu changes are in public domain\012) readonly def -% Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. -% DejaVu changes are in public domain - /FullName (Monospace Bold) readonly def - /FamilyName (Monospace) readonly def - /Weight (Bold) readonly def - /FSType 0 def - /ItalicAngle 0 def - /isFixedPitch true def - /UnderlinePosition -221 def - /UnderlineThickness 246 def - /ascent 1556 def -end readonly def -/Encoding 256 array - 0 1 255 { 1 index exch /.notdef put} for -dup 32/space put -dup 33/exclam put -dup 34/quotedbl put -dup 35/numbersign put -dup 36/dollar put -dup 37/percent put -dup 38/ampersand put -dup 39/quotesingle put -dup 40/parenleft put -dup 41/parenright put -dup 42/asterisk put -dup 43/plus put -dup 44/comma put -dup 45/hyphen put -dup 46/period put -dup 47/slash put -dup 48/zero put -dup 49/one put -dup 50/two put -dup 51/three put -dup 52/four put -dup 53/five put -dup 54/six put -dup 55/seven put -dup 56/eight put -dup 57/nine put -dup 58/colon put -dup 59/semicolon put -dup 60/less put -dup 61/equal put -dup 62/greater put -dup 63/question put -dup 64/at put -dup 65/A put -dup 66/B put -dup 67/C put -dup 68/D put -dup 69/E put -dup 70/F put -dup 71/G put -dup 72/H put -dup 73/I put -dup 74/J put -dup 75/K put -dup 76/L put -dup 77/M put -dup 78/N put -dup 79/O put -dup 80/P put -dup 81/Q put -dup 82/R put -dup 83/S put -dup 84/T put -dup 85/U put -dup 86/V put -dup 87/W put -dup 88/X put -dup 89/Y put -dup 90/Z put -dup 91/bracketleft put -dup 92/backslash put -dup 93/bracketright put -dup 94/asciicircum put -dup 95/underscore put -dup 96/grave put -dup 97/a put -dup 98/b put -dup 99/c put -dup 100/d put -dup 101/e put -dup 102/f put -dup 103/g put -dup 104/h put -dup 105/i put -dup 106/j put -dup 107/k put -dup 108/l put -dup 109/m put -dup 110/n put -dup 111/o put -dup 112/p put -dup 113/q put -dup 114/r put -dup 115/s put -dup 116/t put -dup 117/u put -dup 118/v put -dup 119/w put -dup 120/x put -dup 121/y put -dup 122/z put -dup 123/braceleft put -dup 124/bar put -dup 125/braceright put -dup 126/asciitilde put -dup 160/nonbreakingspace put -dup 161/exclamdown put -dup 162/cent put -dup 163/sterling put -dup 164/currency put -dup 165/yen put -dup 166/brokenbar put -dup 167/section put -dup 168/dieresis put -dup 169/copyright put -dup 170/ordfeminine put -dup 171/guillemotleft put -dup 172/logicalnot put -dup 173/sfthyphen put -dup 174/registered put -dup 175/macron put -dup 176/degree put -dup 177/plusminus put -dup 178/twosuperior put -dup 179/threesuperior put -dup 180/acute put -dup 181/mu put -dup 182/paragraph put -dup 183/periodcentered put -dup 184/cedilla put -dup 185/onesuperior put -dup 186/ordmasculine put -dup 187/guillemotright put -dup 188/onequarter put -dup 189/onehalf put -dup 190/threequarters put -dup 191/questiondown put -dup 192/Agrave put -dup 193/Aacute put -dup 194/Acircumflex put -dup 195/Atilde put -dup 196/Adieresis put -dup 197/Aring put -dup 198/AE put -dup 199/Ccedilla put -dup 200/Egrave put -dup 201/Eacute put -dup 202/Ecircumflex put -dup 203/Edieresis put -dup 204/Igrave put -dup 205/Iacute put -dup 206/Icircumflex put -dup 207/Idieresis put -dup 208/Eth put -dup 209/Ntilde put -dup 210/Ograve put -dup 211/Oacute put -dup 212/Ocircumflex put -dup 213/Otilde put -dup 214/Odieresis put -dup 215/multiply put -dup 216/Oslash put -dup 217/Ugrave put -dup 218/Uacute put -dup 219/Ucircumflex put -dup 220/Udieresis put -dup 221/Yacute put -dup 222/Thorn put -dup 223/germandbls put -dup 224/agrave put -dup 225/aacute put -dup 226/acircumflex put -dup 227/atilde put -dup 228/adieresis put -dup 229/aring put -dup 230/ae put -dup 231/ccedilla put -dup 232/egrave put -dup 233/eacute put -dup 234/ecircumflex put -dup 235/edieresis put -dup 236/igrave put -dup 237/iacute put -dup 238/icircumflex put -dup 239/idieresis put -dup 240/eth put -dup 241/ntilde put -dup 242/ograve put -dup 243/oacute put -dup 244/ocircumflex put -dup 245/otilde put -dup 246/odieresis put -dup 247/divide put -dup 248/oslash put -dup 249/ugrave put -dup 250/uacute put -dup 251/ucircumflex put -dup 252/udieresis put -dup 253/yacute put -dup 254/thorn put -dup 255/ydieresis put -readonly def -currentdict end -currentfile eexec -11167FB533773667FB8D3EFE82119D83C5E325D3F9FA9CD7D01B1F3F3E52876279E4660D -B5D444F0B7CE226ED8DF687C9F94FD3D6282F90864241946A4B8E8575E48452B9C0794B0 -E485E0EE753D96B6C08DFAE68281203752A25CAF8EADA400FDB4F9AC57F07D7C3CED86D6 -7F5FCFCD9D4635282E9D92A5D9598F79FCB9FB1A677408CF7EDE532374FF6A6A9703662D -17B5D4F6CD9CF249432F8C76D70BD990DDA5FEBDB59A17FC8A068E1DCF23729F4CCF2C91 -59376F20EBE27AC7473D31BBE76EA67D9AC99ED58644032A828859BD9DDE391FC993707F -97CABF55422D4C37042F25E17BB78E63EABE7783BE0C56F59E74EFBE7783B90310E817D7 -A01D0AC31EA0C9B67EA7A3EAC553F3DCD76270BAFB428DC7AB7EE802E06EC54B705A5A6F -125250A008FA7375643EDFF171457F65345A08795AE0F1E5FAC5A9CCD3E258A9CF83382F -B3385DA7FEEB19F6D001A7B5A214115B01B441014E51A9BF8057017663645BCE7E2C6228 -940658CCE20121AE23DB19754C876CF1E7ABB40B2C949C0D45AEDCEF0165C46A0E720BD4 -6260D7AB7E8B5A77F64542DB42BB3C48EF0F9D026C8563478B4B80B60DE0005A3C61B5BE -DEF534F95EC79CDBCE5AE2CABEAE6289BE6D998B2E0B090DC31F890A264618C9E9473962 -3BCC88789A953C3C9BD07F5B1D7A1621B71A12FE379E85E6562D62C449F1EF7B467D126A -41D13410BF85D7735CB440A7363A7C9755F3BAA6554FDBF71FFBC2B9EC7EF2BCF0228D5A -98361A9F79AC87EB346D5AC82847C2FF02AAEAAB6C8272350A534C5BCBD678B28C6F7B97 -44BF3243F970909CBBE5E4116F2A1F56EF992D3EE51889C80FA54C5C9982BFD90C1ED83B -3D7A917C2588207D5A15D4316C408332591A8845B322124D17D41E10FABF2662439FC0FA -92B839F0A6AE2065D029FE012F75D7B4B0947202894211CD4786A74385DC0817DDC3A2FF -8EFD3EE4CE9F31AA40282C2A0E88D02ED77F991C910D3CC20F1A6C513E105A65117D6FF8 -B448255F66674BD2CD7B66EEA96CEE551D97B27E7B0BB692664DB358985F0DCB1E5FA9D7 -F92799971280852C5DB56F5E0788208521AB6B2589034B48624D393F005525342C7441E2 -67D1BD07BBF43C69DC7BEC5A47993AFF6F6A9747787AB8FF45BCDBE88FCF290DD28FB3D4 -2FB726AECC1832A03E970FEC71D7CA532B45C8C5BF64CEA9F6F9483D369EC9FC0D82E3C7 -A5863D816D35503EBDC1CE27C57258E0D773318E88B9006AA04541D8F14B4F23F7B3D23F -6B4E990457C5525DCA3B63EE75C3A53611FA30AEB04A33EAC156049E60651AE830726330 -C3530A1BE5F3CA8AB63BAD85DA0080A22FA54A6DE4AD3EE96BB9EC60D3EC4AEA7B5FC82F -8EC803B2C6198E5ABF9B67A82B24D8F5C672E6A825FE0481B1744DBC008B0B1110761F23 -ACF02284979F836FAC0BAA9216C35A5AB25B95197F282592E27C9FBD8D5EFB330B08A956 -B6079D05D4500F00518B164CECA074491CEFF09A99055371AD3D0A9F1DD2EF38B33A0FBF -6C83E4AB7584D24400671CD568DE38F6DAB1660578C65AFC0FB5AE268AB26D47F38CB9C7 -E48BD5A7D4F62199EF7180D923958A41F3FDCDB0A856375B3BBAF2C4C32752FB0B641240 -E50FD465CB53BEF09BB0D73D204B2064B3B6322A1D227E8D7B4FAB71BBD3E2FFC59712B1 -EEC12CFEAEAA8135895D705C6BD8DC5726A21888E25B675475D53431DE441B7177F41A30 -A216DC48B78D025AF5CFC53ECCF08C494EDDB4D460CADF0E325C81B932F4BE839E5B6F3A -3AF49B330AB3DD8637D9D0BD305C15D20FB84B14725D4269A78D316B2C2401698B125DEC -EFC2D7DC0206C6535846C435E5DDCD2294C5ECA8FE4C3342D032CDEC2398A43971E15CDC -CC308BA14659D338D478ED2C91DFEE282D221AF7150507F3F35054CBA77F7B68B102C7A3 -B0A94AAC5EB7ACC45F29A2B23A8BA397727E1533E78F84870A647D8D2F364F0A9D9CFB1A -F82AA4A2FA9D4A33E2F508BE63488D4505E4BF2B22029A24EBF8ED5BA75646FBA0B80D8E -B076A4028B10A89BA8735E03092071307C212B76BBAB410DD4783C8653F472A853105F4A -0900CD58BDAD0DE8967A8084D49E03CAE74D6724924E2D85411B0E712ED4410F59793490 -429E6271123A4A3B45BE180248BE5F2BF16BFECE9B005C9AF12523C38E6DEBAA9F1BF6D4 -AC2B193FEF981CD5E4ED3573521A82DDBDDBD61F43EFE8CF474FFE43D82DA07FD8A1A494 -6E8C187FC6C85663A05E65BE968841C923CC2AEDC5193F624FE2FA5B4F33232BC9361141 -60C54189960EDF10F1B44C91417CA26FB66E4A89B19AC2280C59CB7C3428A0251E34B5AB -90368B31EDDFAA2BA749EFBDB7C99EFB9C5E67E9C6C62438E73DEA816919881E804E3D8A -EF1D5108C4895E2E285618AD7DC3A42F1E28378335D46ECAD9B3058B165257BDDCEFD817 -350ED1B3E3ADF86C3BA4E9624C2E592A8216F4B2700BC88992913406E7DB2B5F5DF3174E -A6D7639B616AE160282DCFDC85CAE0C73F3E695B09EE0FF5752321EA51A914A7C89FD9FA -0E66B2F01EC9033EE9DBD246725CB36EEBD34EB3481FC21C4AD3AD26B394E858E3F4C3B9 -4CCF83497813A5CAA32C5FE41787FD97734992458BDDEA1A9CE2D7135A65B592B73FE851 -C2671A257B5518E2C008553432C6FA79BCA95000F31BF7F0AD101A30607D1D34987D89B0 -F3E1A190231908C2451B8FB0D18EC8F873AB09F1419D48B041A02BC4F819FA17E81C3289 -77EF1BCA4E86CDE766B795EC8A1B299F57DBB4C72660533C8A96AE701F9EFBF198FE4D5D -C66C3EAAB293D0D9D908236037C83A759F2156AAEA78B6AE37DF0AA85A5F89215171FC75 -3A323D43A3295A2462D8902458F15F6345815BECCD373E3EF4F0993F7D52AAD4E2030CB7 -2862D8FA6E6138B71ACC7D62E7261FBD56148C8DE661AE9844FE920ACC2503E278DF0B04 -F669145B9C8D435BD90C3DBA004C09B39227A5409965E6ED90E5082B923D69B0842FDB38 -0D742890F9A9FE4BB8F923FFED2581277AD8FB61E2F17BB90D1A7E4195D7EB3FF833FE3B -72E696C3DAE0A3A49918540BF1C6046FFF094E01680EA558415209926FBD70B3CB4B044F -DC5FC844150C311F9C1C031F4D5B99DEE4F72F2307B8EFF74735B1ED593465D0D7998E61 -DA4D497AF119FC332156B8D882B4005FC8850E4DA96B7AE93E1552AEDE068D0E2B266C45 -0753CD2DA48A059CEE49F1E86E2F77F701FB177FA32D5F93FE4D6A01275EEB54692AA6C8 -95EE530E862079535A543DE4067CD630A7D8CC83AB9E04377B8D3A05F23280A6E1D68356 -C76D531990EB15EA707C0E5BB5055F428997E2A731A4F7B5288E54B2C4B949833EC117F3 -0A0575603796041BE985C63F48CD55E76638E7E54BBCCC9D2C73ABE423C6A7159CCBF80C -8FD931FACC6D8257D9202645B3138E367E160CA3CF22E1C5ACE59AFC77BFDFC25A5D6DDF -E6C2F6B68D062D0490D05B05B55A7A0C6E56A52A2EADC106E3BB6410205CED012BB49DC3 -6EC89674C22C7D17E3A6AD10A2812095454DA4D44414F42A8678BEB35D372D3851EBC535 -888D9E937906CC0475986D2656E16D78B391E8E8D3E9C91D980D526C6470E79B728ACB9C -B9F63C6000B9E60AD76959F7B14F06B631778911EA9DB59D8B9BE7DECC68DEEF068032B9 -272227B91840B30B7506A3FD57306015EF686A174F48B734D9070498D2184773E7353A24 -51D3276238B8874FDEB7161D1A8506BEF79EC5245651C29B9251EE17F834D200E2219A3A -9CD838C9BB31182C00A52E06DA6EA4E446FCFB62C92284116E14C3D38973F1704D5EB2E7 -6E6F88F7444364046AB43C4D7D44A23FA47B5EA158949A3E1F15DE70F40812444C6F0F4D -A9940F2B3CD1B7B1450C1BFE7A6E111503CFA45FF012A6DED44CBA623FCEAF5262BBF810 -90A4FC1EE72D5EF3852987026F50770F7410E486F1D15D25888C8D88188647F8776CFBB0 -C7D4F02644BD13C84C592DCE82A56F08920B2FB13BAFB405154895458F55DEECAB846104 -7B157C02450E0E529A10559BD8CD9592FFBC923092C1EB0AAE96E5CE64A6D5B636988F69 -EF02E3F5B84451BA2F6CC360B647908FA940E844C3DAE8FAF73E9ED416D6B8A20660EAF0 -2C662828F3E137B0956B15AA9C129A312E753202D429FC734325F1F82A3D9058ADB87688 -4B979CAEFF660A8EF9191F4E0D2CCAE5E5458139A0AD0637319FF41CD7DE9877AB094F4A -3F27EC8F5C7D42B1D892B829E1DBBFA9295B8383B23658ED25DA227B9F625B89E26C854C -0130CEB1F82D24E53D5FCCE082433A4029B1B4A5905D25BA809EEA54895220DCAED1B2AE -879E7BEE3CFA3C71FFBC77AEF4A415C96F2CE40EF47E2080FB59AB00DB4E8D527D9E41D3 -8DE95CBE66EAC589F5831C4BF0BBE1455F4960FE388B84074DA43DF499BE3810C38A4BA1 -D23F3A6C331F09135931FF0A7D77160E3FC9CBF4937D5814A12848C17ED3F62FEE21B11E -43889F3947F67F66BE8DE7EFA954E2CF8BFFAA33DEE3F3C397FC572DDFD7E42578DC39AB -7CACDE5A30E25CB6D949E2C89B02E48F70CA2D0FBA47F19B72CCF99B4C71C69B1E1A381E -F620B2BF283FD34CE116F5C2DD1BB9DAF60BD431A6CD475ADA9F7490E17D5DB183763467 -0C167B8E958A4C476820EB53A778B9131FC7205BCA2EE3791B8FB54AB6996B82B65B8E60 -71529E0E3A721E6306EE6448EC9607C427F543EB8C6717D0BF598F619D36A3FD7C0E3DBB -E7B5D923DC8EF2BD288C55EF93640E4249E0E9E36E1FCC19CEC8619495B71D84236313E8 -C552ED0F230DBEE3C395269DE393EB34F630A5043B054154A47EE48BCFA1B3DF9D142315 -F1826809F0BADC495B2C7DC93D34155D843427BCF872288B49D2A0AB22AF861112C324F3 -4428FD31584D3B5E88ADD1EDD809DA66F90C756386198CA263562A95BAAA64B1CA36897C -1069CDE2D44EE87FC186A24C10C23B8F3DE59B41D1AD8E01EDF4C32EE70F053DAB84D24D -33A6024D7A86570D96B34892F8E299414E7084D99B3C3A89531A7861A39EAEAD9506B0C7 -017E3A730C91AF6857DECFCE2FFF482DB160369A16BD17456EB74258D2D39F7177998A85 -6694D74A57318BBE392EBBCD069FCC8EFB71AC1516E350FE4F936BECB2A8DC4280BF3A64 -27F1B741C4FD53AFB32EB78D9C06D74B5F71DD967E087F733D50655900E086D358B46C2E -8EA8CB494C0EBBCA4B0A9C74B48E0236F9CA651D73D2DB6FB1F1F6F7561194C8858F3FF4 -B3F46FED001DC472F71BD6E16EC1516605779FBC1FF81D6ED6996F955C001DB98BC8E7EF -16065AE3A00E7C65B4F080F78C5E0CBC9EF8D4E6A8A3E76258B31BD4F6766A4B00A37AA3 -E5BEC4C495D5B92E701B7423FF09FE895CA54F82D584942A93ADA1C7AC5576345DB685AC -6E04586E55C997FD31D13FAD4D2FEC0181A8A0BAD0CE863F9052735AE3F245F549B8F2C1 -A5486F65BC217A57D404832AE633EEEDE8806889AEACC54237FC2C493CABE98111D34EDA -6739E5CA8FA33EBD70757FDC1243E9F1D58D69796A7BE700CB9A39F69ED0D811D4D286D0 -80BCA0D9E78E54B63E640C53BD479106062953EDCD604D10F3FF50620AB8D1B79F1F873E -E47512F37296FA930C5FCECC28FC6025270DF4B2CBC428ABB88BA940AD55CCA0EBFDDF91 -3AE3271FBFA6DEE0B62D6B94F40053A11410D91A1CA9DB0E9947AB24EC592A9FF3F00FCE -F1C436A94332952DFD7825CFE35489E12C6A8A7521AA5B32B307A7BE5200E45E1FDC5588 -96F0A32E97E31CF40BBA08833E7D7EF78DDD5D48685B19943705D87E40C235C0EDCDC6E5 -93AEEB193C8957E5A05E17F4609FB3626BD14CB597362AA65699A50DF076A54FB1012403 -E32A3CD7761DFF0B3F41AAC0BD55C1148A24BBF31B4CA15608F12DA8F671D76E33E00AAE -450412798B7BF74C216E112883E9920B0EDD24701790AEB565D9BF4927BD3856493D6B56 -2C5A231DEFF338A986DEE08AE42A6FB978608C3B9A4A1D8E17164A08E2FDB5D1E1D38AA5 -5E2E4B4D2F5C0317ECE305DCBB207D7599943B1116A0AF9B917E1EE7FEDD285F249B212E -AA66724290030E1220C5E26EE5623636FB5897E0CE1E0DA00B8E716A963B4A9498E113A2 -C6E68B6D35503EFB27C4D82FE3B48A7005560DF04BC6AAA01EAA47070C81D60C40614920 -12654837A5317AF1D7F24404E050CDB6C3D1B1BA2480FC9940707A9984D507A3C078365D -30662300B4E28756F69F8B65F9212B4A0FE63448CAAB6331DA9E7DA65347370F03E51135 -591456D774040BDA4BF0D318161C082F69ED644E51EFE26EFC45CFA0391220B09BE1157C -3E4B55CF5203F2AFA61D7C0F6F281460A761987144ACA50A2834954890D9BC811B72D0D5 -FBE77F8D01496257522EC90143BDCBBC30EB08B9D15097E0AA0AC15F6F7FEEE91224BC4F -531A65905AE9337D97652775BD7C43740E29EB66AEDF91D658C2A2F9849A26457C8866F6 -F96D59E6721018ED0637D6126F08EF685174F130D9735CA45227B508B52FB7D9BCCA10D3 -BF16A889EEA13847DA7CAB63C73C0F068C3BBEA8E162295F884B7E28BA144E30450A823B -9025847C739B6EEAD71967F8DBCA0AC8FBBC2A7847BD7B957B8E44EC96CA2888B47F86DA -786EFEB0C741D7CB67CC25371E59148D4C3ED2C5349A1EBE6B9DC8744EBBA600856B22F5 -1832C41955FF582F4E0337809EEFC33FCDBF9C31723278A8D085F1404D16A573314F2876 -85C67FC651E691B1C12121B0E209E3E7A0FAC4272D58F16863202CC7594D0A6B10A4948B -1FEE719857ECEA0CFF0D0643154CE968A7E909A6CF9A9672B2159717E854044AA6A13F05 -A3581A47D624126498DF26635EA643734E2DD2A2EFF5D2F70BCDE6F39C9D54F0A1DC05D7 -8BE1C28495B0064C2A18A02859FD8B1F91DB7D29BBBE7401B1891CAEB5BE54468DBE8B76 -74C2257466643C14A9657C1E79627D8743C14B4CD25C03AE56AB0D1D5EF596474C7881FC -0706543A538D2017E48205664D7443834DE0344BB76CCBFB64824E753FEE37F39581FD32 -27AF8959D869EA87D806668DC29436C60A8C9DCE55349B7C992F821C28A28482843577A1 -44C905FED079A06273C7960BADCB5196F3C9E2DCC87C0B1E03C5B5CC64AFD58CC72DA649 -040DEBDA7ACDA5BE6DEB142FADDFD883DC4F004B7B7FC5A1A8A44AA9C4A6B3CC034D4F92 -CB6293FE7A3EAAADE9568655CC3CF1EF283B1ECD15EDA0A2E3CADE0C3148A5E449CD5D92 -557FC15E2A3B99F6CAB2DE4E3DDD038184E46F1914481C7E5B5A1862C899AAFC1A4965F0 -5C152968522019B3D635C2A67DA80CA60F264E6F75F419ACE6F48F32C5B6FEA7E340DB0C -5C25F7FA380B1A7D7F4534F0ADB02EA93B4901B581A9EE79D3710248F0A5E03BABC2A066 -5583642E51E78893B375950891A694ED7C18B2CE872619ABE151DC8710F5395E79E5FB02 -5F05A3BD9364756A54FB8B31C81C2285942F9FA6940BF3D676C16FBCCF34A433028A9A0B -18A39831E0F04F03D7A4465DAB80894AD108CCFD1F004013B9D619E0EB552DAA5BFE0EA5 -53FCC2D38EA0FAA38BC25AA6E954A2ABE35AEC8383E556D1067F2A8F4FEAF745DF55771A -95502B33A40807C7692BDA00A142A4EB394838F57880B4ADE4D21DA150CB60752D5A11E0 -A309F50D63AF0C59DB2D58EA0C827441997566E8AC0F39C354CE94175BBC62A265FCA7A1 -87B3BE75E83EC96FFFA43F6675D9374771E2AAB0FB1A14E9843F864852CDB0E23D30F1E2 -EF19FBBB4501D41F4878208E041A8B5C0A46B3352A2CD1F5BE78B3C89B58DE076CC603BF -04163F64660236214F9B029CBE96F0F4DE40C8919EE1FB5435FBDB25083FB3EBD505B0AB -CCDAE8CF4AEC0DA7D890621D68D0056FBCA5832892EBE9E2BB72A2BCBD224F1D3E8E7AB4 -771CAD9C6A4A0E40A6BFE15313E15EDED08DB8941E04094149B69FAAD438E8C7047C8A41 -ED0B10070C48F804C11FE88BCF655BA3636A4C7426584812DF512535225E8499D867F83C -86BD170854BE047A028889695FEE4E7FC63DBD109AE00664414FC96496F85DC4BB719BE6 -B7C5BC4D7289028A003CBDF447018981D0A8E11656A4D75D6F5145C5DE04CFD6234551DD -F89930E9267D1080FAE4F9C66B1BC736C7375B902FA53D9E8BCF2B5A7BC4B6341CD65F79 -9673CF52F26D649882A3A2EB1609DBF2D4A4F02DA65BB417EEEE635485BAD51E96EFD4A6 -BDF0861B1922D31BAE22AEBB9DF54E2C5ABA5B97ECCB069903B2AA28D790560A64E3B93C -E0D3FDC457944A22A390C874D655AEA7BEA5B305B1BCA2F13DC73F1E8DC7662E20FC276F -1D29E9D96E8EEF0E3B2B0FAEEF541CCAEBAF485019979872A72A8ABCF89071E28DF389D6 -8418B9EE2488F611AC58EBBC150F3E93AE1B3A1C5426EFC55B22E5A7D1DABF78E4C6D196 -757CA1120B657ACDD4EBD7276EBD4A67A7440B46FA59C59E2E6681FC2BBA58FC8A82804C -F8C4AC4032B09681B6CCA415C532B91CDF0B0400AA088C9044C3895F3BF46C611BA136EB -AF72086A9D2BC385201BBD78DF875CD8F7D67C0D4F26D3D9C6345C55FDCE9B26BAEA3963 -A7DB21622C3B3B3DD82DFC66FE74937EE3728FB20328B047463856F9BD4E1B1F0D088A3F -19408DF937A84D543A5BB17445979A37399586A368E99FC2542D8F401D0BF360CA619854 -EDD0BE31318865A20F221772253518E9E09BE9DF95901147411D4C0879D26D8F930E4B30 -3FFEBD5FBB076BD9BC5B0A4C99F0B85800F25994108428F98697DA6E7C14F1780BDECC94 -16B682AF9E92A7AA7DD0B33EB695DFF884D14BFED98D3D9F84E36ED4FB2DD86F1A42D8B4 -A2EAF46CA449E0ADD9BA067F2DE96897318BDB05A560BED7588999185585F81C9BAA0AA0 -9449C1BE1F14AA0C729E6B66622D18B8D5340B74BCD66B967E6F29365A5745012C881F6E -CB10CB82B46B7AC551B5ED79C41709AB70B4AB493C4BC6DA1CAE87011B5961A5FF4B0ACB -17A95F29D49FDE6830C3B2D170968738A8815149B242B4884161186079DD6A1217FE9CE7 -E60E7045A21B10138832AE5C880FD54FEC7B71974DC8704DEB006E01EF9F61F7FC22A117 -123D5A2EA6AC39CDFC6BBB6380404B8F98CCD1E4FF7CBBCACC4AA13F260C081D9AF5108E -518516A2C58B27CDF940B960FDD3D51AF3FA1BEAA90687FE8BD145E9984AD71187BE737B -6765F385FC7A58FA771C84759CA27F908038C2B7BDF81DDB6797A3EB4EB6E8ADD3FB9FF4 -E92692577747890EC0CF77796BCC291929FB27FA69F10AC7912D9A7E6FB84DE14D9D6D12 -115A8630F8CD3F26A86F291714B931D3822B8A07E9276659D5F36EFE72858A444557FE0A -3BDC70E9D52F941E790EE7B7454557B792002BB07AC33F10F2CD2E5E16E88018F6F79D54 -34E408572D30A3316C3F1BD36E1BA16A49C3623317C62ACCCFD869EA76921D729E70F2F4 -63FA8F0035EEDE8EAB1E7BEE4C389DF3BF6625DF10CBF19701381B68525BFE96C2CD919C -2922EE99525048392C1BCF26B3141B551E9DFE25A2D0E84348BC032C28ED8A118DB6A083 -B1AC44A0EC9184D101FCC6A9CC4F5F9756783376BCB2DC289982795796454835FDF5F325 -DB4DFE924D2C02458FEDED43FE8DAE2EC4BB61536CF755E7E920835455CCE84B5C0C791B -9CB6D494445F304B173628D8057F45E9860DC8DE045E351750C0E71B2B13F78AE4941AA2 -F3E2E8E05125DFE290AF817D87693AAB16345CF0CF6CBFF594371E9815A5F3360CD52D8F -095AE10808F33F86E07E4B8A2BB3486F93D04C88FCACC7907E359442D0CAFCC088657360 -6C54F56DDC5039A88396731AFC577DC3324A0D24AA9348245F660A496410E3286B81D6F8 -7999933D898C0FF0D3FCBA5F9D5CF3326B863E941236E31FEF86B7DEF1014D1C6CF86B92 -4FEBF9FDEBD3709805485B618DAD03D15B5C401B94B2F4500F2FBE72CFEC2A69164D6185 -DF5160441DF72FC509EB7C1C1322AA5658B09E1BCE9BC99763E7DE13057E836E57D24460 -DEFEA1CE7C2553BBE5F5CDCA7869B7153A0C5349A7D0B546F971FC63864BA7F00BFE51E3 -905A87F67398D568709D27E5A746970F72EF9C71ABE7CE96044ECF80352F712B605A6B10 -8426A06A27E13FD837C520096D15F9B1A44E6F955E3FACD91B643BF0EE74D3FD6E9A10CD -F05C01FBC7BEA26D8AE8565CB89BB2E52EC98A4F4898D146084CDF4E6509462D267CE81D -D7A0E6E2EFEAFA1BBF696803FD40F021716C2838C19D32F741FA334D228E2BD34DA2D561 -E6609CD823CE02EBB683A6F1EECD93C9103E5328143EFF6C9E05956969D2F25AC992FC76 -39B5C238FA4A3157B959B4AF11B6AA05823C015134836A6560EA7F07EC86117511E13B10 -75D0D2259D36E7B8065D930184C7DDB1AC2B42A566FEEA6927313BE91C7EAADA352D9E76 -43D467F94AD5ECAE37BC145278B4048AFDF432B2E2F219661CEE53E159490F1E0FB04DF6 -D42F4B322AC01E5732859AEC445D6E120091996DCE46602EFA8C01EB0E1D8BB6D0D12174 -E4990498577B86CCEF0EF5F7EE913A3A8D78EF9CE4F37B0BE1B5F40A4D0B00EADBD92C7A -5083E8D4B093D7BDA5B88E08D5DA4EBF7FBDEA06DFB8C5161A92548160163EB7AA97B603 -96D869524163EE546E1E35F764A4879D2DF056A5E77438D45D81F9356A4F8EA0D007E0B5 -DD2441879A48AEEDCB1A2F493C3E648EA138D4DC080022EC7A62E08373CF032F48C2F585 -0589F04122726500E8B29216CCCF6ABC2A04A726224F9B029A25DE8C5965A6ED3F6E3518 -B72C6A0A64802424E91DDBA855C20EC358F6FBD79C30CC6DA41C9C117B23139C150DDB33 -7FC090A907DCB0FA4DCF914E3CB53EDCF7DFB6D2A200F7C2E8401667D828605C64D9A62C -7360AECC44BC3951D2ABD75976528B0B98913A2741D0E160B48FC0458FF56DDAF4FCF5B0 -6A351BE0A90F851C44BEC636C0AC688226C8B0FD136F2B612BB66ACBA8FF149783F24B99 -A0FFBD405F655FE2DC577E01953716C44965782D86658859FA313876424484951448ED6C -E43106D4F8FAD95C3163A1AD47AB14DAEE015A257735B0B14BA8C1F807B54E54670BFB7E -9311D936086C6DDADE803F4E304B6E823A937E1A92C28C5A61D0FA1DA992DEF383ADC936 -E910075C9573B15ED356345ADF2EABFBBF8CB6D1D35DB404CB70DF440642562D8778E5E3 -1C547AA1DD408A97F44048AFF9317364BB3A8D35503CA5F0FA509CD0A20DE629DD243EDC -163402620ABBCC4E9D7E679A92E7FBC45CCD3923AEC1C20C8F15647B0E661F82C738FC61 -FB3C954B9097633B78D21C958491977377BA0FB845FA5357F3519572002CA6A88FCC39BD -CB51A2F2BA462905906DC5A76632708E41585A47368D650954826C722853A1B9364D3F21 -0A844A8AB86EF33C8176B76E891F2AEE7C1DD8C6B0A2B52CE2AB398533B6D862593D30BC -2BC3046C588E63E2C02F17A5336D7B03B8CDEE76F5B8A8AB32F431F9FD1FD85013779781 -274597F8B717CFA22066ED723769550D604ACA4772C711C672FA57A9A30E962E9ABBA798 -AC43517D02EC267E25CA09B5FF087C0498660A975A7BC1F726B9B0362E786A5E6DA97B9C -83C8B7BE172423C79CD95A2DAD481CAEF11924E4357833DF7692C22ECE4A7C92B6C84B8D -4E1332A9AC1C897DF2777C9A3C8AA4B77574A5BC296BD2BB4DB715609DEB685CE804B710 -D098CF51391D799C2F59017002C2F2018970BC614F4A4A246A49E795FC2627A5361A474C -4EEA15FD114C5E067D2F091A25E56A019A2DC6E00F9A3CEAE73F68C7387A2BA310AF9980 -8709635A5A2AFA101FBC0FF8AF9D7F7CC1E44FD2344BE0ED353D24E8624D464938BC13D4 -078B481D9B32937D75B52CFEDAC13FEA859123B76C50856986F05DAFA7AB1885ED53E88F -57CB20D166DA5B3723AF472A0C3BA1325015BE2097BA520E15E0CCE3FC8D3AEC37F3DED1 -671FDE5EF193849D5141B9956A68DC514D6A9FCD67AF25D8751AA32D114A58728CDF973B -05464EA3CA55ACBDBC0C2CE814CF10E8639273C33DAA263C217A8C6F1A8EB1BACCB6C7FF -E50DFE35E2919D0CDD7C099FE7313B8D610C90034EEF74908906ACE8631A193C5C6341DE -6A311DAC36AC2E9FA441E985249302F9273EFEA3FD5AC02111A0B697CBE2FF96B245D2B7 -0847404C184BFE1E3C883E66D90EA64C797597CDE06554DE22537638509E69D9E18030F9 -E2ACC66700F2429D8C5787837421EEB83B023FF531F48B40EBD3E58A13A0FDFB227C2A28 -C9A81C16A7554BD0831F68AEEC7A1E834BE1F90CC96D7E6C5B06A5EE89B231C183E2BAC8 -4840BE8EE0CD47E46517F6C46F27B3691E5D271781E612602AA935061867860C660E6BBE -E57583687BE3C61186D98BCF7EBC3A3AFB9B88C7C466DFA58BA37840A537F1206C522FA5 -DCD1C129B51AA8EBEA4F5883B7D1EAD667B178B56FE7D831DAF15C631F52197F7E92B34E -DD68CFC92859C49922404F21F4BBBE4643501E39AF897D93EC8B89FCAB6BB8912F42E805 -532691D4BBA96077BB351BB9070DC2D5C17D60374AA9C8CC6B6ACF929B77E252F71A6F61 -74FE8058A8DF23CFF45A046CF30031D87FBE2D408BDB0C9939FBF6F16CCA38D97AB8B19D -7278EF78814FA670EC235651A4703B229B50BA6B3EAEC8A22F41AF0CD01984238C34C2A7 -9E18A8E493F64F74EA3638FC4EF88B7D788648B4A2ABF02432988F9A3C871FCE7C59B339 -4E00539AB825DFDA2C420E378D1A20CD0FB6F060349ACBE266DB820841088A9FF50C2686 -F90561D8248881869D04A809E738761CD091B084610BA958A39CA3F19CBE38437DF0FE69 -D23264E56B4760044F11EC435631D06C6C7934427BAF1015C9BA4E370CFD16F1E892AC3D -7932504A52DC9D9576CDCE2C37AB393A55180156F6F583B753E117E42F6BA85A64155118 -2FE36FC5D5C4C80F88F8825E88CA9F5CEBA97FD8ACBFA3C87FC906F443361B71F6B2D875 -DEBFADDC1CF3EA8A7D099C30A4207CDCB3901C13FA35DA02FB95DD0E6EB587D46D739A27 -B2A325237F8D33B1413618E8FAF1C9C146581EA841E8B85174D1787BEBEE6E409FD6B64B -3B066F62CA10009B10FF02A9D708203C02EC1F3309653B617F053754EE9863EB202D7ED6 -F5E47D80B48D99040CD17B44646694D8BB68F39FD6EE4ED77606D35B4B668A16608AF657 -FEB98F826C291B26325B6EB8587CC3EDFF18FDC96C56241ED36A6115BAB6579D5CFEE016 -75D3E4F23ECEDE16AB09586B9F5A56511EAFE9BD38D5B36B0CA45F1992475C129798465D -0B7E94BE9B308E87794522507AC3AF7B29C91AE0C6ABEAB8989289F238509063C3E74CB9 -393F2934A5FA0EB173E2982F412875AB7F1ACBEBCFCEF7647203869322300D4C110D30EC -C61E846AD1FE42361F357830D5D6DE7DBCDA6154F8C5B6591EA2580F34C2C5422150BCC6 -E8076F510E571BF3633255677A1971CB0624BB1A6DE11FBE9CD1260FE400240C4C5CC59B -A1EC6CEE2E054995D33FB5ADC781D78A371A9116CD8F9DC09CFF2F3542BC1DC1B4E61D3A -7310C9674DC24DEC68073F4A979FFF96DAC759988735089B043BFCFDA203DA4F99D8E719 -1FDFDD18F3B53895F7AD46093B8A9D55CFD2E527A50F46DF23E0288FB8F61E2254DE6933 -DB7E78462CF03E7E454F6774415D3DF25926B9C7E48AE576B05FE164CDBFD3AF56FF9A94 -D0C08EB26C4514140BA55B503A52D98CEC90C721AC3D2E280288D0F73C2A5ACE87AD9798 -E15AED95526210EC6428D10C1422482799D1BF69DD623B1B16DE95592FCB6366B5E91C1A -3E03F6D086258AE19576E5E66F9E6A8C029E26FB7471ACE648E9A9FC74251ABF854772EE -B42D96D9C87EEB12785547AB30CFB71FE683C621CBE389225C1F0DD6CC7C24FB9E5AA117 -A4A9C83A78776C0198745A21B6E154A9D560BBA0D419092CF341F1606686D396C9F417CA -DBFAB2D360D2035196C85A204AC2F0F3B3EB17BD337E6E9D57BB414613A636E22E944FB2 -556D9046E9CCCFE0B82BF68E0148B17CABC0A926DF4885D2572D53435CF8CA462BBD9A53 -AE3673D6C6A7BB9E857B9E01CD95F2336EC1DB562088E8C2B4C6DA9F8E7F6506A6E69D06 -82785BEAFEE2B57C1BE191673F51C6E2DB711667E34518363119A27D7D3618AC791B920A -E66FDFEE50BFF094E587DF23A4C100EEA75AB4E1B3384F99966543D48A3FCAACFC76E5C2 -00DE81A2DF1C7D7E4FE1D8FF59FE187C6271A80B42C9CC854096BD3FCE15048E7AB421A0 -89C15E9574D535142E877C1D72BC5A1173D157A1B61768CD39FB88D574A1BC3C67BBFDE7 -02EE677084111B8ED795273745892D9260CED632285E633DE80F3DE62FBF73350D71D72B -84F5A18D3BD43386D05642FDF1FAB29CA63B82E1969679FAA6283160946E0E3C7B3519A3 -5D791580141D2F980023C39C122C2D102E4243502B517678C7A4E522753F91F4EAF73C75 -C644080E3509EDB077EE84E1DAFC06B25101FDF01F1FDEF68C326A6F67253E18A0336EFB -2375FA4F70A077A2D09471AFD31FF4DB23B1FFEFE8A0CE644E864BE68E05EE75192D65DE -9D14F9A385AA2B9C4E5BE385FF1E2C8C9ED1C9CF4D48AAE769AE7FD807280FE96EA290B7 -8DC5A9F78F89CE562183C8D8DF90E6AF14B20C0431617FBF64BA977EB5DC3BD63BF0B81C -AD3D586409EBB6211CCFC8CF02A74A30CB9B3D2BFA8F954E3F9590A664B16E4E3EE7092C -DE1D42C778AD283AA66B630DCD68C968B393C23CE8D76AA2A9B911AD24D3C73C02B2763A -088ED7A1CF3B4BD07C9A0DFF7B642708B13B8E9C32923FBF1531AFA279E162804C301BC2 -F69F4E24A05BC2D93BB622B5528D2263FEF2C8A4CC1D6F01C282FEF8A188484450FB1359 -DAE4530DDA82A2B5359165BEDF8FF28880034D8EAC5E7C03A8FDD59EEB8E2564B3889509 -27EDFD59C2CA931F4058C6406DB402B71CDD3EC21F2533903830DC407F814B86ED983E29 -991A94AF27C008B2B448972C6CB7FBC5C30D577774624318C371737D090F67F6C36FC195 -F7E2DB836CEE170DE9ABDB2D99FA06E340CB144F8E65A29F13DDB34D2D462B38C7CB6695 -09D77000F9044C659B941CDDE2CDD35D12D6FE94B502CE6C67824A695D42828E2D111AE0 -752383F579A86B38BFD3F173D34FD9937F11027F44748A8903342287B85AFB49BFE24240 -0049F4683217BD8974D21EF4E373EBE69221DE4FC036AD9CDE8D1986D16260F361255CDD -6357354CCC036EF8248802C5A9DD6BE470FD647A913409EB0AF9B629050604C166A70835 -3B78E1A2A179B3161553FDD55B036867914EFB8A9436F668860770DC512D8779E53883D4 -DCF5913BE9C0AA9D002788725BDDF0B5FDD0B3E49A4DB4F79E9D28FB4872CDE8999A0E62 -A6A7934A80F1DE7B84672A65513F4B1B845437DBA6DD1DF9ABF70DD356DE74C924213528 -F24124F153637EB9ECFE91AA71DB9A92C19B376F7E409F81BE121349E2D5173B821F018C -A19039FBD57F6F7012D5E4684D149E92FD9E1EA48F3037B162560E3F29C6AA8100C0A633 -D685733DBB08D30DE48A53E28A3D4776B715355EA7E690664BD3F1F77AED2343A05F748E -DB986519D8E92CB843BC8C62EB5F46E73D734D079464EBBC97693FB5A95FC3CD7EAD4A42 -AE6090F18938D286AAF8D0AD64C77E46822EEAFBB655A0995110AEA8C61C4F198EEB8E8C -CD40D1A4317508E96EF47F6C9F4E6D37D81F8296BEACA5FF63732C8FFB8798545E86539D -6FA3EFB324A89107534E638B54059790DAAF10234064B5C51B1B233F977777FFCF18AEEA -AC8E9691C9C4E5652B68D4BF4D262565AA53E2E639FA7DE00A6E8E81075DAE11D09DC355 -2DF890E2F4FB7BF42D94BEDD9FF9E708765DBB5E2D86984BB5E9FD3AA69529A7B4A547A1 -3E7DD7AF3DB740A8076FB06D05EDFE10D4F77467D4950E515CCA452D9FD9FB023B7F7AD7 -188060BC823B479ABE20DCA872E7028AB0F44C36DB113876703856A5C632AB2D5F6543D8 -98C9FC6EAD7609E3002A348619733FFB0C715F55842ECA2FA2A1B89DB93A3BA102504DC3 -BE1F54AAC59EC23E6EA3223912EAFC711DA3210451BB58AA7AB7F14B1621C61D9875C97F -D4DEF3435C6C8BF9BA8574E2D2CC43EA26E34C774953AA0790E650ADC9BF79D57D90F994 -C1EA2B452B4CC7A59463C7CD5675632250C7A51A13B494D7228EF4843C8C1A75E3E2DD33 -3B64FA9ABF7E79185E0CFE9E416B619BAB1F0E27524B1736A97629DB8A9723231E1BB587 -8F94C1A223CABA2435BFDCC4D2879FCCE344F6387E33DC32DD59D38388A7EB620A28153B -C3BD9BDC43B6918A64E00AC4B27B4BE4A1C7BBF0A6EAF2656E196F70526C7ADCE42B3A12 -DF7DF2DC001F96C1C9D6B74BBC11177772A906922EAA6D745CF0A63DEB2D8C0364D2BBB8 -0A0A2FDA0DCF6E4325742AE90BB62AEAC0DBF0962C8101216C67D0535E96A464BA2185CC -612AEB75F66FA580590C43D13C7C8C25B858F63AD20258BE0C77809A641A8F8A662B9C81 -0F4B3D1A53A80E062BF3F388A2AE1D4877BE988DEAFB3A5EE0743EE75CD07D7BD867606E -45AC6243C9C775429CED85E6E5CA20021C6603514D6A6B36C153CA063213F8894ADBE917 -891A1ECF868C64E7BCA2580A0180F6746F4B6016A5326D778EDBC993072DF8D6F78A53B0 -5CBDBD5EDA4C30CD8FA370F701F093A06904AFB9D82167C82E1D069047D37B9A437AD75D -9F7F6AB574925D167B6C4BEFEC85AD45CAE11BFC1396F5E6B39843E71660875105150AEE -F2290EFA830DF0B9817D30D52B75FCD43BD20D30ECCA85B20B32698600DD8A8D0BC107D0 -C77B43C87161B766C69F02E81D58DB7006C5D5660DDE997AB669060C70F8AC2FAC3E13E1 -BCBAAA34143320C795625287013C7EF306BAA36A61B9C71F91AEE7E543F4586A7D8BD432 -BE60AFE2EE0DDF5718B227784E7165C4D2C4610ABE9521854902526E553D0A0CBBC26EF6 -E109C7040C3E876F71581B2831BB782CED2D8ABA918859741B1F748E0B8F81B168C7AE91 -25957055231EF91B31C3C09E2FEFF6C1BA4CDAF73B07684306BDF5F735DE2980E24C91E0 -A96B53BF903A23A324E2C3DE3432762CC7995CF5435A07252D6B8053DFA0A02AAA0E52C8 -8AB643C591431E6D3271B7AA05C5B5EC445463AF4E13D37E419947E18F22EF9CDF1BD04E -2E7F106D231986C21CCF02D103253678E4F56EAE1078993E69B76D07F1DB6B7C91F2C754 -7D521E7FF0ED8DD23A6277AF86E4F67B1D9B4FEC627AA69470922186E477EF75A7D77EF9 -FC4A16ECF9A37597119B804C927377352CEF88AC515D6E914FC1EF5AEA7AF1F3D3802C82 -60305538E678EDDDFA87ACD3BAEF1A09F4F4AE1AC97CC0E7785F3DB18B6EEAE005FCFD6A -C2A611CB6F4D8671C08791B9FED03755A13B8AD33C3341CE9C4FA948103DC77EF727AE31 -0C00806D7639F922B967830BF717CACFAF26E2331C571CFE01B214ED596815C833CA2973 -1D3B159B691BE5722D8ECFC2FC07E0E2A12FA9E76AA3F13374310C58E8E7CB36C68DD1D4 -3E1EC626199B5B77D977E9786CD9102454834775BEE6EDAB046E7BF335BC4572544D9377 -D60C6C389934E35E40252BB891D295E8A64C12C3790DDB9AE563FBFAC83A3AE606116ABF -36E94DB1368234A61027B95C152985B30D67C03A99C6C6A6DCAB9AFF3A8B5766302685C2 -A6438B11F72D91D3B1D2DCD97832861DF613EF54D4858B02A73D37AFCB0BE38C44ECC588 -20F47EA30645B18817B79268694829B33EEB7990C52A4057BE22490C688ED1D4B0B8096E -F6E24114065FDA365D05F9804107459ABF86DB0E7F38378C018003F089E79764B45D087D -02DBDBE171A3F280F8BB673D13826CDCFC624AF331BA9732D81E16E522B551CFB43117A3 -D2FA42EE3159041494C5B94E66FC3D59C0AFCC0785C89F4810F772E72CF7133CC7C75A25 -BF0648BE3E0EDD3A724DDB9277D8956876F0718ED0FFF0D7CCE2A8CD683D2246EB26C7C5 -0EDA3D83BF795B55207FB1B8F9559D27194AA9B0DFB8900AC8227ECFB43EC08A7B325DDE -D23F0ABA4A1B771483E181383EE1AD282C1E69B5A9E652EB71934CB6065FFB8FBFDB8307 -785AF2FB59FBDC229974A8714C47302429B17F5B10492C7594D66BC8CE44A8C42755499A -F34DD4DF71DC73E2DDEB16DA14D446A0E0AEFAAFA47A5290E7ED5AB76C076B892156B159 -A5FD0E83D88CCCBEAE6395046A76559F8F33DBADD30F8D530A342297E4E6BC9E0A0C9F17 -60ECD67C3008E01E34E5F688377CF8B6DAC331FAF3974572242DB1850F972DAA8D73F9B4 -1A21CD8F3ACFAE89915EF1A2E369899F81826565A454B0E68C02625AD18E47742280439E -B28A956044CE0A1A6E71895528109927487B2E543BE901144FD3AFE5811E2D5937439E5E -29B6B5CDE26F27174D6DF8D026696953A6ACCB3E84AD623C1183484F38484C41E31D18FE -52BAF597742D38312C7F83A31DC53EF0FB87325CC73E13A9A8B467C07237D23FAD848035 -AE90BC164C363787E65E8E759BFB8A1D0E36205BD6F9B5D95788E2A8ADE9D6CD15E1437D -F89755AC4FA834643732D4F5AFB8B379C8A404EB2D5795FBA40A0344DDFE3E0BF2475616 -9AABA8F303DCD70653B3FC4F15565E9A3C53E2190F3F8EE18DF5C5E74A5EBA1375946280 -93BA397B914D8AF25792043641E70260C6DFFDDA2E09DEA65B3C58260635C4E3E0D4E384 -8D7CC744A7D0E00EFE5A4F35B392E536F2EEF714EC49168304DA679F87088CEECC5DDBA4 -EA30D04BDD075553947644E66E5D5F50643FFE8A48D3B16633CD2083F05755BD47B71767 -53983E6F4394FD61B4964F749977AE31C2D5C25C3C40D1B7E070C7A019EC00E3C55A3255 -EBC73C47F2A4BED7BF0387F9E494FA3E2327D76584727AD5E8198BD80A56B7EBA9B0D92A -D0310E640E53ACCD7DDD57F3A286A301FC3E1ACBE21A4E9C572BB15721A64648027EB8CA -13BE6FD4C97E304406554A623F3F9FC0F95497D97A325BBCB5735E2A67BAE21C6650F633 -05B25DA1E1DF9417597E09C8EAE3C3AFED656BE4A8021F5AFFCF55CCDED9BDCE2E7E195B -1BC94C800ED80960503D735684810117CDF144B739AA5F912E71530A244D4C9DD5BC1AA6 -4A6DBACBF7B11706973418E8C2E04CF96E21B56C41162C78FCE26B025FA9E920C9C7641A -1303D118AC0AFB7C87A371346C19944F5AB905B59AD125C892D213989989BCE2366CD210 -8A07518095BF0051EE471575E0189E41C7350F1DDC40526C34081730EDE9756CA029B128 -6C63DA99B0A4422DED67441301E7AC53A74190D24E9CC438FC2826339FF05E3B58F8FC83 -FB8F58B14DC842565BD87ADF791E8E4413030B60A484128B0A91F91EB8F69B90FAFEE2C8 -7326618D44D4845ED40A2DDA09B5CBE186E330D4BD84A49A28E3F5D1AA6B37773C12FEB6 -885436DA31DF8145CF2A993242E6F2177BC470F58DA16422C8BAF4FFAEBD8B0D4AD5D41C -A32147945C2158CB5113C64ABA334DA9EFE8A371332F1540E374E0AEBEAB6BDDFFD4545C -E156121E3348E6BC1D3120D4BA238EBBFE05AFA4FDFB3968494088F06109BD62AF8023B1 -1F8802FA6322E0F11C03C97C229C80C656EC7E96E4B5D7BC8040E0901BECB86D9A4A5C70 -52B867CB27F11307C4CF24BA0F56CF555DF0A8F247D5A98B1B04B19EE9B394B3FF9473B0 -2D943013C77EBEEF429D97B42BD8E25E251FD7BB352C3994DFF181324936F0AE8267CE8B -657D167E89F690B0079BB26351FC13A13F968BC5E99FD306DAFC454A5F1A7ED0F388CE57 -62AF1A627ED239CE9B4391FCA709030E0734D5D8E1F7F89B3BA991AB9D4AEA597C4B074A -69F44BC22323039A98347F49DF7A98BF48E617184A03E7276716DC5895B5628A004FCF5E -01C22F2304746521740C919F3BD418DE025AC898B104BF9D15DAFE189246D3FF215BE37C -E1134F41B0D0F0AD80719202E6E3691465AC0C9430C80028CBACD2B80A95A6C10F39A5F6 -12DD73AF2C3E4E0770FA137759F5ABFED0186BEAE50031C202975200B58CD5C7AF95E60A -DDB460008A52BB26F4847E6E290A2CCB1F984E97B899D7B63948411FB074178475CFC3DC -E212536D720C6F704C1458D45E5F2D7DA34903ECF51947DE98552CB2CC5705494121A96D -BABFF6E7B1CA155EC91D910DB288BA8DD87736EA60C2B5A35AD67E4C4B323F1CEFD5844F -1B6947FCC7A11305A1CF3CBE545C891CCB7A10F9685C9E2979F7DED90DD1D5C69B934635 -B1444A33B4CB56210DD269B7CE94BE1282EE7A2E2652CC743F33D25F1E83680DC05392F5 -31CE3343914C7E6C77D9A0AA13DA8E7A97B402924097FFF414076A8E055E76FEB93C4CBD -8841A560092F4ADCEAB9AD16D7EECD6696BB47AC93950A844B70386F77572A3766CF3AD2 -500DB126AD78931F8FA3D7DA41C1F3E8FC42CFAC03070E28707D0FCA1A6A837521BFC1C1 -86990ABEFB76BA56B8ED8475F19E3B6EB8AEB62EF86989559B76679FF475C79DEC1A0DD0 -FCFA1FE72E35E5A50086F49757FB1E65957488453EFEC4E973A48EEEA0F4D64054DC9667 -0AEF518AE6999EB2A61C1DC53795AD29A18F30369C3F4378B78DD76781E7B96C39D068E8 -819ACD8DDB59E4D0B60D42398E336838FAE48E164F7935EABCF60B8B6CDB887BA75245FB -F061E3756EBFC0ACA6E0FFE3CFE8D3F67FB75186DF4557165E1A492FD523C7343B1C2D37 -F05C4CEBC077B8DA778BE378F322AC5CC3B06C2A74687B0B3AF9D08D453753B5FC6E4289 -F362954B80C0E4DF1915E1719431244BF87E065B4A033E0B204E6072D006EB10DCB9F916 -0042925BB8A82EE47AB260686DF9EA59803AFD45C4D0B19234F6BE7913519D61B5E6250C -4E5BC6CF722B53B283F4D5E5D2AA7DE35B5C87FD62C9E9DFFD671BAE7E08E68E11710E80 -5448DE7D5D65F4AA2E27EF0FF16CA3E6569A53745123A9FD7F0DC8A57D1AAD7CAB961645 -F0BFA125101F21F64F0CEC860CE306F02FB0AF49F0C0C6D11B437FEA68992FAA2D6CDB42 -6686056F769470CDA1C158913715FDB4D4687D06545AC87BBD5283D8B9E1FD1B1B0F256D -7C675712C2A6622A179F5AC2ABCD06070A038068033D07E64E0C70DEAF9D61DB3F4EFEE9 -ACA908C30023FE3CB81597386872FB5D5557BD4461D513B6A62EFCBBD3062E67095F1DBB -3167E0338EAC1A52B38FED183AB520E882595FA77F561312F83C102B04486D2942CEE713 -92563D7E609E81354D6F8192CE3310890CFE69B41907B023C3451075383E4BCF6102A669 -4B0593D81EDC415CF7EE2C2803CE5810EDC28B09155F92CB20C139B43E07BFAB08978CD5 -65270BD77658B0D4259BBD9C3A2200B64F73ABE0D77CE6D491253C7590F98F3AA8AF8BD0 -5946A659EC1099D13E733C96A4D84405915B12D7A5399645D0C37C1944387D088FB083FD -22BDF34BB31B396F618C518DA593A9584F8ED6E9F299E72A6F0863B4A3C9F184B1AAFC98 -0CC313B225EE3384D2D814A4E96C744E0DC6A666114241DA125F1178D8F1D986B7D31548 -F9B6079DD38BDBC0AA94F135C44D8B7B6E9A0A0B63FB5BA59152E97F61515F49B906C9FD -42772EB4016B53417C5A2C8E881B0376656115231306FE3AEDEB6182220C2181DA354D5C -28E0D758C573C113542CB5346ABEA9B5BF0243146C186DC5AE0BD9505E5517A6224EA50C -315C9BCBF6707540621B95B9F0BCCA2DF5BF3E8021CE9DDD2A74B6DDB0E9F6DC8E3BFC11 -C0697E87E6C4C642D2172889DDF4C17FCD3E463B30D7A930E4B26BA7289702ED77F2AC66 -BC9ED957863A22905F0996D337CFAE61389D3C70ABE7444E8138BC1BC31F8E572C0CFAD6 -BE60B1AD639AD39BE03AD66728C1CE5B7F2DA53098008E10B82CC2BECEC7B45421F0BDA2 -183588B519182DD0C80B0EF409E2F34C38A7D205CACB19864507CCEF34C5B7A18B9FB51E -3AFBC0970A799FD34464F7AA8135C32914D4DBC466DE2922595EC4A255405D04139C0CD7 -F162674F39D8C01F1E6062B5C946F2F4F5E2F49ECDFE43D2642272377C5393E9717CE335 -11B8542FFF199FDA0867DDE128B387A39CAA79DAA1DA1388B88A5C921BED6709418DA595 -7C8D96831B6FFAB26238DD3D11181345B4AA07FEE3D76093BA5C069C9CFE9E823416B6ED -487308D542C84630AAEDDE0B59A256526169B820E56504014812661336692959ADEB6805 -C7091B7899F0EF46299C414925315D10A8C9652931AC7141FBD3DBB0C34476AB2808FF11 -9B10C17C796E67EF18A386F9E55E34E0D32701D1F77C78FB542D49C53337B9074D92DCC7 -0D4AE59389BF27E9CD453608A19855F6A976347AB95CEE2B07FFF6765F97E66978173C61 -61E38E6CC3BB2E278C61BDB601DB7835E9515D347F37A63EC6DADD2F72BCD46AA4FBC82E -EC40DC7ECB825867B98D6F457BE4502C98DA8756CB9285B7DD1C867B9FCCE8591EF331AF -44E38E3523AA39BF0922C6F59F1E9343AD34DD39DDF485FAC00B38EFF62E16CECB735ABF -903630A30396F2912163FA8B23E97F5B81E2B5B538C454967644E63B351B068EF4BA9B3E -70C65BF5BE8F0352F7C0E25EDB22716A632FD832D51AF2D26C880035D8017C02B0065DF8 -44E289E6D559125A31F76E256197DEEE1F2CE1D0BB7303A3CE177B692D3D0F8931A35048 -F86168DEEF39FEDD4860DBE06F21F21D35E8B982D299CC945E2C8E1D73D1891ACD1AE977 -9584F2F3E9B5621C6EEAFCF91E293996F35562C16AB5F35B6A0B55D9FA85FE3B08692C03 -E453B44C8E1438205A9F18DB136F954C7155DA1288BFB6927A4C308C86C682B78087FC5D -CD3976667B4CDFB90CF4E882B1C35D9515760DD4ECADABE73C3E9758E0A8A3B01BAA6A2F -091CFB987E893A722ED935642252512C3C3492FE736403EBFA8FD18FA9E9CC5B0E802E4A -CF77415626A072B3EA3C637D2F998B91B7A7274C2DB664F4A9D73595C2F47DD61E303403 -04E0DFCF9CF520E33AC7E0978B004641E5B6A88A0657F615C2FAC770AD1DF1E31BFF6E1B -8A32F32F0BE2A2649B9BF3F046D8ECF27A0AA62909D0A80262633733EFCB4C21A295120E -9B9D193A12073BB638C3BFE75AEAF1B3F43FBE3FBA8176DBFC8AB0CCD2E874DE912E3A7B -13421673D66744ACD888E2687051B8CBA461B90E7302963CC5DB88AE64303BE9BABD47BC -05A780E1545EB389973A5CF4CF9E53953DDD085E617213B10B3836101E98A0638C1CDCE7 -C9E0D9FE79D94FCA6472E2C9C9FAF3D7D9F260FC849EED1236AD5774045E52CB82B0F7A5 -FE589651B53D7E9FE4A8848A702D6D5D0A415337F6E8DC7148ECCF94B23AF1C11616158B -EB253C903DC963B61D2C27DDF6E13CDA799C54FF9762A1864E516B913C401713B8854414 -B4CA200EBFAA01F382C70F27589796D7EDD4A35334853B33347F231F24C1817657C93000 -2B59E0A2C4A9796822D5F7BFB3193DD9808398FDC53BC25F402AB126C1B2C83914888851 -037FF02EB53642AA0E6CCBF0ED5812527BB367DB4E67A6B8046DA7C215448808EAB80496 -FFADA52671C89E018CBC8D36CF78675E0A721FEE1112BF9C78D478024364E91CFE2468EF -B6A0BD9E1DA67863124D9F5F996EF1FED356C7FD2AA3DB3E3F6CA36262E896894FED244C -F3BFAD999C6F42F13D4AF617C03E29DD1F8ED75BD11F94B1BEA408ECFF117610EAFBF4FB -241AC338E6A8714A92F2A5AEDE86C493792743F648F2AF6E9A2C692A9669180F629947B2 -6474C03FB8B712031E24F7529143F432607D57E81CBB91A0DC6588EAD2DF8AB5C43C45EB -9DFA398AE8272E43503D987B36504181B2E9AF2357ECD3E6FDEC731B623D921F8D1D0A19 -027876125DC02D8FD29CD8521B36373D4498E2D2D9144C85BA8D5D9AF13BD5C8278F036D -ADADFACE6FFEFDADFB88D3CFF12B2CA14BBA16CA7267A4CAC32A0EDE215D7C0FC7EF3B6A -59A33CD5145E2D8E3530F94B5BECFF74357DBA205348FB22D4E3D40F77ACE73BF519CAE7 -5277729978A61B1B9B76E846EE15C8139B927EC9E2F8B684E0E5A30AF34A0027B9F2351A -B149CE2C8DC951CD54B4D6974E0BD74BA6C2F83BF680F0A01CB39D8B835C097E262A77D9 -55A699E86D30312427EDDD64EF7A3ABA1CCDEC22EFF658FBEB30B8FDF59A9C4185A55704 -530A1499CD700E1D6AD5DBDE3B662DAFEBDBB185C32C7E34406FA6B3878D5B564ACC5D9B -EDF6C7B42411081423FCD2BEB0AE7EE02272F547D551547A11F8CAF8D9F2CFD8FF3626E6 -3CCFFCF9277E6003911C54371677D671AB17424633B776DC98004EA4EA0917E085616ED1 -273E73F2FB891557CC5A9BB65FF704EE526EBF8B34359AF0381A61059E7B740D8069C128 -0F942C6410FE3ED272251F2653817FDDEF786B1F7BA9C6CE02C56C33D98E937EB303717A -1AA3FE1CE2D10A5D07F0E7DD4269F44488ED497E75C92657A2CBD792B9E3DEC8C073ED52 -661DC43A52A6A8218385FD37E1D7791E540F225AAA90480B69468660E05F5B826851F985 -8D127FF6ABA8E58C4F69961AD4896B4EAD41D14399A3F7588E04E63FC1435DBD45530015 -D9C5A1DE717D3923919C31B79898FF17D949F47D354CD81840DABDC5585E3ABF11E556F2 -9EFC55559AF05084F95A5900033AC0AA2FE370C49C71411B98B69DAD30D9D9F75DC90A04 -E59234156EB4B9DD2F923A2DF771818759BC86E763FF36898697F37343FE7197EF5ECCD5 -0933E2C446D7AD1AE945A87A3B7F62F8E14899729CEF06BCDBBF29D65ACA3EB4293CEF53 -501735F2DEE6CB331ADC94F27492130776C3E3B422975275C115A1E9882C6A4559A698D4 -46C5CBE11497CB48EE316810CE428A6A08BFFFB3D196DAD7BD4778F216055C79C325477C -92443E2978BE1EDFDE5836C722B96A070269D2D3A1438374BA6071FAD1FFC511BD8974A5 -803AFAA40E3509B10223D7924DF9215650E9F13E75293B799B4256B7DB4878F3936CFCBB -33D0A37E209A1E3EA8EE6A3455A84E28552DFD56BCCA0BFB10B7F7D25983D3865A9C617D -C85CECEF64CD8E470916B0111075DF6D051186CCCF48813C07E53D7DE553FA3B50B6F7D7 -EA60B3EF169527C6206D89C15436344E8C4AAA490C0D6F300D3A18EE3C50D30BE9ACB50D -5BAED6CA52732E7530C67CEFEC9ACE3659FF09897A62F22A6383F7B62289052485B2139C -48187D0FD3F64D65EF4E2678AB5133A09D448986C96C383FCA7E3518D91BD02A51BE54A2 -F7221ADC7317ECA49522C765BF38BE70EA692F063BEF59D5465E3D65DB466ECE7568BBB8 -526587C1A4FBCBA6D585509FC29F6223D68C4BA4AB48D83192EF4D323FCFCD2C399BA52F -776CF7CBC0F7B9F828A7441FC1540DF41FFE91718AC9CCE2EFD9D0E8D8FBCE8402B441A0 -AA2F95E4508D703E86875A48BC8C579A2CC0D3086B99290845A44B3E14B28D95246607D5 -ABD998C92B5CE660D40D31BBA97CAD73DB5ADA4613520BD4C4D19F34A9D3E57D66DB2090 -30CC7F57D5108AC7DF5F528C04A15B360C8CD1ACB78F090AC2518C1EA0D64F0DF393460E -25C7F07970E49ED6DAF204DD86A718DE11F8DEC66E247880CE1DF51FFD8A5797C63948A4 -80D37C43C508219F322B346B65ADB3A801FFB1033D409838FE05234432EFF0FE2127AB0B -EBC5890CB026BF94AAC5DD98E4153015B36D30B72E5192DD9D5EC6E8609423DDFF7339DE -5EAD4AE73019DFBF3BBD13FC154FCCE5F459FF033A826C7C4DE12ADE39CD85D3366B8CEA -64D4CC905F352424FE9120F447B75A51379885369A73600366055384C7BE79205D2B868A -1A6246C803C27D558DEE4EE108C013C6CFB8AC1016479E37C0FF0D4371ADE9EDBC986BE8 -A8861975C6761CF9DFB6F89244B2B447AA9E48E8EEBBFE1AD875AFE06D2BD72D0867FE65 -68D316B08DF35217AB5BC65200870036F850433BA2C26D1AF67C859E8DEA24AE44C6F303 -059B3AA2CC0F2DCBFA798E151627BB8CA785FEB783D59D10132725E44133655873FA414E -C6C9EB631DF1D0D3ABEF257BDFA9B1BBF6C17731195DB3B53EA289A0D3E63F41A330CBCE -863B1B6352A72A11F54C813595FA055BB5FF7F27735D4D3F5C87ED89FD18A4709B73CF8E -64F9793F12A0946B974A03C4BE4C1C2CEF752D57E323981438F021334D69737DB7B9A0CC -4CD5A93A3B9478DFEA4096D143BED8D3C4E19C7BE85436745B6BD0D54DE8DBCD1268E5AE -D92F8D23596A27B730088F4529D03E2C88966525D62C4A90D4869514362F605EBB9852AC -904758B83108A59E29BA45404380D86D51EC2567A3574A9C6889B22CC1C23063A782746A -02F43654B378E2C60A66F583FA666105EE8AC6C54C17AE79D0BDCAEFD951139FD96D45B8 -2F75F1928870A9876678588B6FF4B76F3062A0B895F8095ED27A8E620C2CA398EA161BF6 -9EEE9567D3C4CBE7ABC01D7AF30BFBB269CBBD0BCE7208BE1C94E95639E99337C56FBAF3 -AF87E956EBBBF2D87FFECC8B32220949A038C48BE761CAD77799F8191AC0975236C15458 -A7957630480517AC0F89026DC1B4AF3B005DA7DAEDBE41EA451D4B28516204427BACF5ED -968101E14C29396B7BBDAA67F10A602207F365E96CC6E050248C46BAE78348C4E016AB3F -1A1DB7E9BBDF6C8CD37615A12891667153DE23FC013ACBDE84E5E490FDBF9066C1CB00E0 -528714B54E71B5626E71D387B8FD41B21E2DD15CD595EEDD545A90E8F0D02388820B2A97 -527EF7DAA65732B6EE2F07E2936318FB75143DDE8F5FDE804346AEFF05637BF48A705A85 -B6F3863470ED141E118801AD9F47FB05BDC65AAF8F398BD3EB895C3AC5C94DB7CED1AE7D -1D7311DD67343AE0B5724A8827CC26E463AA76B00F4CD3168F1C92C64EAB1D001907B900 -6B1A12550668E688E2D0ED3355ED0271228CBBE4D56848F0B08EA24B00B5B20BAD06EE1B -C6606DAA509FDC41D2BE545F9FA650E8FBB0E78CC856A5331A8A6476FA3C44487B9F37AA -5DBDE9BE2A64C69CE8438170E2B40893AFFC0BE099EAB03E5034458D54BF9B64BEEF7167 -A25AEC8A1F7217E492E5674E4C8B343B9249B384BA88DCC4F8902FD4D535C0246E1609F5 -4285F84C2D4B489369576E74272255C329942F764CD4A51C730C99E7F5F8B7C52DD252C8 -500319E4CBE6C696C77CE1ED8BD05D22E4861CF9D156B95499B3718A47E5BEC9FD72E1DA -DBDBF137EFD6CF8BCE7D64A27B8C9BF6E24C929BF07F5A62BEC7BC760706D31B98DD8E87 -97559CF8E4357AC49FF6B47667228686A3AE789D68B059FBAB877F3F1BD00841A1F151E1 -EFA94F69BCF41D4F9DB5423430A2AD2BCD53BC87A5178F74EE469772FEFE1153C8454288 -31B12B8276E3E54162B64B393BBF23F1EAB4D1D385FFA5CB3C57809CAD0A453A10661D25 -685A9C56B41A53C3B1CE6E41418D8B8104A2BAF3667EC877C9B6269BCFCAACFAF695EAA6 -BF13891E52B4FBB7543F1BE26A867EE6B515DA051C3C7BA25BA135FC186D4379D9AB4949 -582692485409A5DC52BD6836D8CADC2A48A4F5B4FCDC69099C3EFC7166ED293A795DFDC7 -3FC01A91C9C15219723FEA15A4FAAC3511AE8D0DCCAA1FDDF7E2AF4CBA80E38FC6D2D8E5 -B9AFE27366ADFF0529348BE4E56484F0E31BFB7B9DA4F06626599FEAD323CA644677794F -541EC7888B181EB0AAED60E6F0E5FB4F2FE2564E2988D6441E58C2C0C1DE63CF65D625B1 -46FC422A0E0E77C43C8FA2CCD310B5694EC8CD1B9A3ABFFA25687D4013C0E5703094D5ED -37295E540A1B2B2E836FF73B23E8CDD190D1FC04DC6CB9D5947AA853F6748388D400B6FC -7DCCA73AFE6D1FBC61A7A3AEE4D24BA702A2F4493D484F19CDA1A850C95486E4E4D43F8A -A584D14F82AA0B3862E1FB06E941A90FEACC607D27AE58CF19399886879BAB287A429D5C -0C821C26C61F169F1B90CF77878968F56737041BE38776374546623553223E6E2A8682E7 -737528C915EBD41B263DF7E12E4A4C6967FAE40F90DA0D0410E0F22BDE01F018D63A8C23 -C157E72C6910157A63B33AAC9E5F3C58F771B8CD24F0E24C4EC17277C8B8DE5DDE52176F -A9740EAD3F62125BE32678C35005CD445EEAB9AA1E9A71FD11614426E171EE85F5D9A17C -536C87D58C5140A64B080966EC5A3E0AED8BACE84496BD019E6023AB562FBC1F28CBF296 -3FF98D715ACEF7BDDDFD65DB78CB3F0E16C440EE636A0D7C05CB97C085F7C5222ACC6305 -4DA8C3F7D950B0399B7250BCB66D0D520AB951530E728B4892779DF0FE56C9A27E279DD5 -02883DD2E2E4013D03491C52B21DCE600D68156106418DF5273C6F6FC9A3E1E9889DCE43 -17628702B21201E48D23A7E0EC5E1DAF104F3BA1F659B8FDCE301C3D7ACAE1B7CD6846BD -496B16BF6DAC876C117242B3088287DF82F260F960CF90849F515702F71EED275A40A579 -B0B8F707681B5FAB21A81FD992254AFC0D43E88D641445FDAE5D6874C4EC37B2BE38D5B4 -6DEB232B7100BCABA7ABBD53F5455EB07ECFA23B1703A2690869A8D0E60276830D7B4FAB -231FDF2784CC788CE61A4909B89C5B8A5791FC3160166BAB1BE25E57BFB2D162CFCF36D9 -CE524A56A15DC752BDEE0CFE605E5BA650ACCF0DE4286C70EDDFDF8527A02C3958B17C82 -1769E8EE3E46FCD93AFABBDAE4809836C56C242B0C6C63107AC6C3364B7C79BA5C62BF62 -EB6277B4F6905CB999C568AE118A690FCBDB37433DD2B360A7C66EB52DAEB0662D61DE6A -74637C6C8B373F9EF9A473486F3A4326ED5A442BD2566912C9531C5EA6BA89553FB67C16 -1933CA4D7FF5886F2F6B3ACEBF939B682968D4B0590B0D39A0871A78EF3885E47F892C16 -FE93101266B12AB988DB622F4E408C442937B56007334AE919983566CCF994B3084C0D42 -5EF94563A51CB142F0829F5398B647AAC6E0010DFCCCCC15BD0EA5A6CC90EF8F790980F1 -4C8A27B2792B3C83E1317CB932DB3B28F008D442D374AA75573F5A324D7C5D6DE8ABE5D2 -CF78A931DCCAD7831AC5A7A5D5DE80E475DB271F0CD21A47B1E7DB5233705ED0D421EC5A -2BEE73D5949400151866E065B28D6E1F6574E2D335BB542D16EDA5823886430390F9A0D2 -B937F7ABD1DA9E04894ABC066F8CF0B8BC196BC1465A378BA14D2284AE4DEA134DDD7440 -77DBA60CD0F9E478EAE5F7DC0D6309C9EA514D44C279700088581B29BC0136E2F4EA3E9B -64403DDB054736966C331AC20514637A3CAAD1B27C569045C444D48FFB63091B6D20CC67 -FA5034880794ACF58358861548044DACE9BF02B4A23925639B7A6A5DD4B6AEB2F18C1619 -DA2E4597905CF4A00ADA215FF258BF38FEE6923D67424DC1B05015C8D09DB1FB7F660C6D -E061FA2690AF2CA528AFDDEAEEBE6291D61955BE374DEBC8A915639DBC5382A17810993F -92E7EB5D2492E76F6142679171DB74170A6B390CBF7E13CD5307CF04D4C471BE0C7EFEEF -B36F609D765DAFF2E682983BB0CA6B70B713F1217C8F2272637C8AE97B3E15D5D451AAF0 -44FA166A93B277E334DB8EC58EA397CD013B53DE2D7944387712E80F086942728B9A4877 -C1193716F71ABCD563EA769AA555CA4C48FBAB634B1AACB77C7A576C4DEE78C5CCE3D3F6 -E483B076A4024292A35BC7080245E56B6D58926983C0D9C31206130B3B8AD5CCCF8A8659 -465C36D5C5FBEDD7B455EB4BAFF35AAAA12BEBFC6A7B40AA15B5B957625C37494177CBD3 -E3E59740FE558926927022C6411B9F07ED9BBC31AD206944E56146CA8BC0A9E8C9172C0C -0B7C46FCB490EBD02E86F69564B8030A3280E376839D680786A0A068DFCF0A3DA5048898 -69C9AF0362765CB583B785FE8C0FDCCE4F39527A7B73565CEC9E798FCE909941522819D4 -519A12043D35DCFA7D9188EDFEE780E04A868346C68A3ACE74B16641873B8985C1F0C263 -9BF63ED86CB556943932F9AC71096EC23E9584C8CEC8E95C52A493E4463B168BEB6F259E -71B2B22B53554E487A897256E37BD4C1D3B48DA9AA5C5CB8D5D85C61D6E1BE3A607BEF1A -A8ACD46A93FE3C07D0BB9EBBAAF0433C7E5C6D5040CF9F5AFFB1AD8104D1328005CC5B10 -A1993D3EEAF3C3BA4A0B1A260A72DDA6ABD5358DE5171F1DBAB667AC022F46D3BDE54809 -790CC4EA533392E6C039013D4B0FA21E36143CD9E708C89CB13E09D624551CF86BB79C3F -13868988903A7C5C744743FC8CC6B48219FBFFA584E016953F8CF342DCD69077D9387A34 -EEFAD0463AD98FCE21EE8342A3CC4B9CC10F6804EE9CAF70FD1C56CFEF02B7CF2D89CBAA -E45918EC9445AF3D1C43DFA501D9B3789314063A748A6907BEC153F294D6D046B9C76D01 -4CC021D3074C0A2D8E92B45EBF14C1C5AA39546A2362CB8A6FA0F5198AF84119260DA3D3 -A89AAF0A976B1D5A020ED16268C8F1908400DDB8E27F57DC2B00E3E4F0DF1777A934DD89 -311A8C7309C24A670A6A9E03C094B548D223C31521DD7FC2BEB3DEFAF7904EC0123FFBE5 -4E627D9AEF3AD29FBAC003520D0B165F3AE91AC94FD8F3FA9A6BF9FB81863D03BEF8506A -A74C7DC0B50BD327C6942905BD07FBD62E4C3B16A06070BDFBD80414CB9D5261A5F721CD -FC7D1F1A6811E1362F9372CBAA3C8DA63BB103B2C10BF6F2504306DB05835B80FB70BC39 -DEC4DB3ED1EC4C2B64CC907D751407B6B8379F449210D0BB68CA1C445ACEEBF9C31419B2 -C4C5B8780991D042AB3948A5C5C8005E0BE1859B13F8AE6D4AF62F00B415BE5BB641B964 -53F037C492B988D839B96AC0FE01DC0EA9E064FF06EFFEFA446F41AE8E44AE58355CBBE4 -57DBEE1EACEBE69E6686B687CFFE11DDF76C2EEEB6662B1A2A176BA63E8800A51160A6DB -886AC4C5868D17487273984BA2A47F39837F197D6A9B279D71157B6ECC2A72F83C1A5C45 -B17698F3183C00B6A61C732604E5520320309069628602318F4F68DF0BBC2BAC6E90D1DD -ADAA738EFDC3F63E8F24DEC44D41D2CA546AAB5A88FF61081C144DF568F35C21A887FBAD -C87166B58486340679B5F844DBDD772E9848400746A207BD04F470D2B2F14A36225FD693 -E1BC7CD6AA3BC7FE471C56B411B084FF8A67B0B42954C0915C7388BCC44DB2CBA0A70F4B -1692AC59029B8181D12F6A1F22170E04696799AECE8E6B4A96FE89B7A18A4B6684815BAB -D8D94F98302D44EA827914CFDE8CAC4CE48586630DDDE0FD1F9A57E8AB0EBD27F6A25186 -7986192B6D3F46C796247B1A220455A49745710E32F4D03B4F15636197C6F84967054365 -F7C0B1C20DADB63AA474551586EA5F055F8F3EBB1214ACB3128D4C6FA566C8E506DAD848 -6DC4A245D1977218241A5FC37AF7C03342EEEEEDB2EADED36EC0C43BA42F14E3E9601784 -5780F5C6E5262D96C0C50C87C9CE4E4666D1EF982FA7D4F99EB0A5EF4AB0456FEA1225A4 -E6873C1B6888ABEDCB0D84275EB400E73695564A15E338E00DC77981DE14FEFB40796373 -631102384B1A3C0EC239F19A2DEF2689F75F5D55E22AE9EA06A8A33424765D84E458AF21 -B8C99E6BBBE5517587FF76E7D02BC5AE43007F2228014951C93C50EE50EAB764BFC8A084 -86E97549CC9A8C53E442C8AF409C98382080D32974A105D60383E077138C34F887159B4D -5745F7B6443B446C5840BB92A3B0BC317EDB0CAC5310AEBF16285AD0C4DCDE6E27C0185E -9CA90D3086D6E11EB43E65F25F74377AE8BABC97E0D9ACFDC1339D0613600BF6E2F6FCBF -66A0AAAEBDF0E9B3241F57D08C17612666F8286FC17AD0CCC5AF7F355668E146C3FF61EC -07A85AD2A655DACD2CC58D5D0216CCE6F8621405AC7A4A160B6B2C9B6C5857D40A5BFABC -199AD07AE8BE3169A9182F81F80A094608F1C2B894A6CC33CE4DB65AC02E3528601A27B0 -FB7E14B2B97F6391B0CC8963A71C6794E74037CED7C0F2D9B7EA192C44A5C1EC78535F45 -A5A38F6C9E9E811B950B7D0B2BCC7AB21E8B10057E64A72CD86549B52D74C806C242FEAD -5751BBF62735377DF1C0582C89B0794D01FDA343EFA486AB2746A6780508206D0C42F020 -94F3B8ED6371412FD4CFF17DB123DD857DF02FEF68954C8A64FAE88C67351FFE15834360 -1F9DA7526CDD58BAFD5372A39BB7AF47A04BA972ED382B7CE3FDD92B98B9147EC77C5496 -773F33E58D6B9F48447D3BEB6B12CF2FA194EBD93B318014CA0EFE61E6299E097B394F88 -6D15B7DE6DBDD12A8B38C5D0F328FCA5798E951D950DED554353AFC64543CF6735456CA2 -72333B0797B4CF24D247BC76F9FD325A2044F01046343862E92591CF371C1A2F6118E36D -2AA1EECFFBE7115C525A722072311E353526224622B96265B29C10F6FA3E35B8B4AC8AB9 -084F74CA7C2E39C19361F97BADE96E7962B8356C92DCCE8B5AB85C48F569001F238D113E -8E0D83B793ABB238B8DBEDF30F33BE03ED480AE7672942C7F60FBB2B2ED85451DBEC08D6 -3F33AF72437E6598E90C52D62319A1F2018AAB1155506A96D4F2558004CAA6EC715D8EF5 -A34C7779ABAF2CC9A288DD88B96F0F3F1E45A6A7049348446526EF562DAB4EDDD8BB3030 -E913252DED80A8075C1C93E27509193CAEEDC132A3176490B03C53DACCC26417A5838515 -FD4A8093EAF7718341F9A6973474EBD66C63884BC78E318CF04B9D3449196110EB6BC018 -C1DB6CCBCA2ECD1016F1E884320B14B27BB8A15FB42E190C30E45965C32C21104F49FAA5 -B3F983C768BE7C909127C19EE6392D6E9E698D650CEFB7AE48B2442522D88C6D6FDA41DA -B8B3187F497DA1BDA3FDBC8B71A619063D9461393FFD5A072F237B7FAB49597636B7A41E -91DE676102B0FB2ECB4D5135C015B99419925667444BAB52923DE73287D3934DCB1BDE9E -72ECC4C55A55BB24A71B5A37960993BC88A0C66B82C2E2AD597EDAE4F74FE918106413E7 -233C832EAD1D2A2E515D734960730EDB2A8072D539E2C69CC5C9E569109B20670157AB44 -41BC249E8DAECBD9F2115663E7C88AD8C4067158B822CB278DBE410E8B1E3E79D4E20C6A -E8FBB5746390C823D5D818C3583A41A2D080DF439916FF23709C6E816F7DA9FCC60E5B6B -FD17813DC59636D33A2523AED576BCDFB0DC88725D6B6F286B2C3DD85E53D825DFAAC9A8 -8572519A254CB4435907A2A57EE96CE3078F80E24C0DB0FC3B047684460F5314B1EE091D -6CE4B884D06DEEBB7E1ADF4B44376699AEBD7A5F4AE19B5FF8022459E9E2D43117F4C1D7 -630028D14169FBCB72DDBE7E4BFB4B7EE1DCEEEB91623718BD1E5B9E16DD4F3ED2469BC3 -1BE0D51A530DE079DE096431EB3C624898333E4A271A79D33816881ECA7C355C1C0EDE72 -039E2800D050F507D05D8DC2A6F79C1E58D269B1CF397160A813A827B5D5060CE32B3454 -DBFD65339F3B75CEA60BE92A1848B7CA7EB730BFA278E8D549D3DC68E9EB32553FA32360 -4F516DCCC56EB0751383005BCA15849491D9A0BA4227295B88BD819FAE10216E1E2F7CCC -DE0FA17076C881DC4ED1E03F3004437849D059449BF180F4E5A547218D6CA90D235A179F -BE73FCDE7531099D073127D048B9D3050959CD6DB6FF19E57BB9F296536E33293F4856B8 -20A8E948E00F7FB3226F846EAB9F1A7DFCB11871E7B85C4A7BE6A023BDB2314FD77868FB -E02DA316769382443FDE43AD3979D243726923904918AB90A8405B0184189C7FD724DD7A -E4EA99A6E31C18B5A00448A8146A9897584A935118BBD8F7BA9EC471461E5D932434345B -630674C3ACD3C97E0A5C1E6FB286D9A3ECF40FA51AD7C1FF9992E0EFB3633F4FE8450FB2 -15947E2AA9E07D07A98723DFF9D31CF3C50C4796D98DEBE12BD475765D8AEA0180CCB73E -C33CC144FCE23D5D90282349CB17E9FA753A6B8D0F3FA480C5D6D4E11FB30393DC4A774A -6C568A6794F6C71DBB7A1E0D9F5BF8DAF1EC3CC18CB067FF86201124CA66FD8F7B884910 -DF8511ECA9F027A27CBD235BA14613E32213923BE966B04A79A6328431B07F762BD7AADB -CAC4E00EC767F91C3BDC7FB20329CBC2A91A98EF384CEAB49CE57F3A4D83C4A690E49D37 -BA278E9D39B92740923B3F3E5B8AA7743F2B8EFAA230C211884999091373843DBE82C2B2 -3FF81D8D7BDD75E9782C9F3BA1C587402A335ED42FE47F837366C61306807EB50BAB23F7 -196DD1080B0389BD1221115F17D9B51FC600C77D5B02D78F05ED65F895AD34CCEB36EFDD -8A3289F4AC4472CC5513E688B96053B6DB54198E0C0B51C3FA3723AB54F2615E0FD7B488 -B3DF35A895E558A05C100605A213129C0D8DF08C92A772450F2F1EE7806DF2B5C5DB82BC -4B72137716329403F9CCF85B592DDA02CD4FA4780D60E8B9BD7D079C59070046432F8A2D -8BCE7098D4A81E6933807B0D9EB617C2D8F7DC8E29A5C10030C93918378EC771EAC7FC78 -9BB4D5D1CB078D4B2F0F239039EF9F1B45D768CF1870089F76F54F86CF4BF7A443A1B333 -EBA476838752720F8ACF49C0147F62068606057E9E8F55D3C26BC0328216D6E55B9A18E8 -BD8FDC0AE1FBD60D1244AE9B060313ED36231A8610D0DB8BBF8B9D0C218082678F828853 -2BF2FCCB4E13251E1FB176AF17CFD1B4E74B195FD65493F74C9755562D91D83CDBBF8693 -161FD054345DC816F885596C6B5F423605D0DA925E27D8A44F6EC50E36C368B29AF9FA5F -7D634E4390814758A934E216DC092F352B49916F6F117EEC457AF1029FD0FA1B267BF519 -C85866DB602A67F6ADCB772EE699DF5FBE9799BD6B0CDFEBFAF2FFBA9E7D1C7A4E9A8D72 -B1730290E8EF082B6313E162E1C1EFFC7A404C28B4B3E4C9485041E941455CEC85C94BC6 -B727E5872EC049B0F6654CA3F21E107FFC105175C30BD172B8FEE93D16EB85F14DC911AA -E9CAB4579778040FCC18F15C35F5CB1DDAB8C393476B882571B1C81777835F011B5DC4D7 -91703453E60205ADB46E9F9049F980603DEFA613F14F370EC8729C5D365BC4D128C65114 -833F57FEAA89834597C2AAFCDB74C5CA0A35B6C380EB029CBCEF5B7BE1D253760653677A -78D18C6230986DA5EBC43888B7CD821C1EDC997A4A3574F695CFBECB60C7F07C5FC4B9CD -CC49ED481593019AB8400DAE0BCA31F101B5483B3DCC330631F1EC7F4E5D3EB5D6E38ABE -DE013DBDDD4FF6D9689C2F4F3E7D0F2FAD680B94B5375853A079678C3C2FD7CECE27C8F8 -7603BA3C73B1CA9CD33F9D114630E413F118161CE5C6B38C8C5827710231B9E8905FAD73 -DB3AC1FB0C7883FB8C0A96E05859265637903B41E662CC4D5FB36368E4400737C5F34F1F -465CB2065E90A9B453C7D2A3102CE69537616A15A462087234A358808EECECF2E1704E35 -0AF5A17DFC5D5E83798E98861B94A1170CB4DA8BCA63957EB1B7E0515CAAEC440A291161 -F6B81BA7DEC7270FD3F2C07B8629E1CE3FF15376660078185A05C41D4FBF99285413F001 -4CE1D20E4EB2EF6676D1AA2FA8A4DC9BD3AF6F664F9B4E4B3BCF606D14AEA0DBC253E9A8 -75AB27F3D5A7328850C2E90B6BDA2420E82BC0ADF07C005357514257694FD442A6E701EC -CC91B7E0845B17CC8F09892BA35CD5334DD73AA0424AE8A0E1CA52D2109E62EDE237177F -1B469CDCB95F1ED1934C09C1C71A9061D0C29059C00D7A6CC1DD2AA2DDC209164890161E -8B4532199F7A5503A4438B3769C9E1F8368764D4F5A5FC7CB397E27844ABC9F2498A6BBD -B6AA3C33125B52F692D2E4ED469E7B3ED78D60BA285131AA78F581FECEDADBFD2E7932A2 -D96A86944BC7D3F511558E3BFD8AE1250924162874186ED3D12210C79C044682F7BC3029 -D9A352D3533BD903F26A180686482129DE478F6A0FAD7DFCB9EF25F13260B9B0273645B6 -24583701E37773426743C9AD1569FCB3C69277C3958944EB211758D1787C86F9DB344713 -9F522EC5328337AA586BDE5B734EBC6F5F392F7BD9D6910F204C63E9529C9561FEEFF567 -800BCB0E900BB465DE21A576A809A13F3E4FB24A9223B41E52BC297040808840FC7FE337 -7B7B71A0318EFEA9A421FBCF3B797BE09579FC5559C3085163CCD30F2757E457A04923FF -DD33B439351FBA13AF5DF216A968D8F093540D70222A5F98CF9E6EE6FA6ABA02B3BFFFFF -1AD6B5A3E48298FDB66E69459C7E9646829B032E99DBC5B4C98731D868D14159E95224EA -9237CFDF32A20DA1A4CAFC0D55CB9DC4BAE3468A0A91EEACB9F6C76F677DC6BB83BABAC6 -7A7238F67F41F0A67EAE0578F56D3734C87304C0D3800E9B52DBCFF05F6EAA9440691225 -CAAB4C86856463B0E0ECE208CF4920871DB1EADA477879A4C64194DDC2325040FA104327 -FEE2F853DB4515C154B3B8A78419DC4B17C78F14BE6C7E8BB47388B11075474AEC54D6AA -C53AE725242BA69651DCDDBA6774C3DB95B947A044D009DE74575030C947F25274EB0A1D -331D25E53F231FE7C2B7817F44B6E98D0B845BD0A31DD9C8E3B6845CC80B259C0B850278 -5E0542CD65CDD0102FADBA33501C1251340F10AC63988FF53BAA60345A145455009B80E6 -D67C8722B22FBB74554A88B0284F641DA252B9A2556B5EC15DE1EB75C0F74CBEF4FF7CA9 -50B90497D23A935511F5B7EEA0B92BC686D71EA186B49B21E9183279379637F8BC3A3079 -3419AB94A6EAB55F602ED0D4EB20BF6AE82050C432FEA1EA3B5BF2A16B879E586C1130D6 -CD5682D7A1F51704EB03EEF129D7994D80183B70E3D60A5EE4CA8E21D4703605FC8E2CDC -03E1FD17A2B788FD74DA79A0942856C022E9ED417BE6F097328E22717AD8A4976A855FC1 -5B8CDCB66FCAD6E6D87021578F2A3D93CBA708390E849C1A96E234EB91F54F53299529BF -1BD1DC11722FB9DB27C98F2FB05D62DA1B7EA32CFEA033EF7C1C47B3FFCFD9A4BCBAEE4D -66C94E8488D397644A2735E9AC8E0A5B4C61504D43D85B27026F15059B0717A0E9C2A893 -FD1A0C53815951FE68958615A581D9F1C22DDB219C3C7213F20C496AA0D04E9B3957F71F -94A2A9E20FC1DE943A30D72E20E0DC0AD7D974164656FFA36F1940909464CA435D47546F -4E74ACC7817BB6842CF97FF285E4EABC7CFFC7A314983AD5DE3FA821AEBA7E95252B0524 -D423F8FE71FC1E4D8883876DAB19415FF39A330D8F1F2E9E728F2D47EA05397F8F6D4A17 -7BE4BE649DB34CD403FE663509DB51FA3DBB4F3DBF4C969DDE8E18CC54AEFDBB23E286F3 -EF0AD94165558C2E1E91854A7B2D547735A3BF9A4AD940C328709F99801FD5CE9EB34C2C -394BC530B2F79D6EB01FB151A20C03F64A76D6018699B09BABE16CCCFC516FE46A906633 -26E06B7BA28EE26134B52B96696BBA8A235103E8516FEDF892039A768C632C39CEDB3AAC -19D71D351AE1DBDC46ADA5D3D547084243A87FECF11DD3A99C79E08A17969322C177544A -A0A79990D1C52BDE6777A77DE02D9E9192A6D06D4B1D2FA19A95D1EB5B2F700A3D76D383 -D6D8E68D85759C829BA020BEA26587350B8BB4A22BB437999F0207B51E3C29508CE76AD0 -CF2FDDE225F0A1C2437E8607CD180CCE7A4975A535A9F1AE496A3A7D83A276C67BAA1981 -66BD3AACFA8CF66632E6D18D256F878143ED7EC542D7C29F16B0CE96D65201519B1A1C6F -941B4812CE4597C92727C2B1E3D41AB59F3B026C32230374B012491D5DC66E20871B0EFA -4A1989D8AB26B772A7BE6002E4FB4AF7F5DD5B0639FB0E59349A6AD7522240F19DEFAC33 -D0FD050E565E36E87C5CBF0D924A3EC16BCB31277F53770CDC95254C0B9DF1CBEA0D4386 -299D005AC2C1B4985DED85978FA75596D95488F9A16F77CD6572064B658D6FBB7F765CC3 -18C1032AB570E04589F6B56A67E0DA0D485062899BBB0E760E649B0485B13F76922AFF97 -59BF4651ABD8AE83EAB7544A2CF451E9BB18F0C4EEB431D46B65CC1B9049F243FE740FB0 -276059C3A80EAC689D5A511399334BBEFEE83FE0138D3F46FDE381EA63DD0A5AC4E36754 -BA7AC6784CF3A1428945483EC5DF805B846C2C758EEC2DF8A63B55EB7FC0762080071E10 -EEDAE6674E5539B69A6335C68F1FC10BF1F41157D082CB9376292CDD4362F14185D87F50 -369E7B562DD7F75DCBC86A5E8187192B61E3EC233F9E26230855498C1A580470CC20E233 -C8215A825640A89D8E21E4FC2A4EC8CE44778B4C96B217C0CDB6D2645FD5E4DC24D293C3 -84512BDF80C6B99FE14E429AB9C08E7AB2D752F44C1E826E91DF652505F6C84F050707B7 -9E222C6861D5302739CF4561C0A5FF82CCF7E7BB2B3F23360B8B0AFE8D3A272F6EAEB35F -5419938DA96A1EF1FB50DEFDB9C9895BAA791556F51D3BFDC373AC0FEE03560918977CB7 -851EDC56750C708883149FA8D939B5BC7F7035ED3E2F2CE7295765C0BC09FA3E18D350C9 -9B40E2810C1FD915C2AF3AF93855AEA12DBA06896A51C9B2443E2D9A9068FC76E353699C -B8A782C2126D7947101849809294F5763E150498F31BFE1D5D8AF704BB59176DA3DF2CF9 -0013ECB8E30250E5AF4152D892F4BE558D140613936DF6F9D43629B1594FBBA870B0FE5D -1BC168BC183C60BA2ACB3C9BE52F853AD4FC1B009801ADC0FB070C65084ECD3165874E91 -4915B5F188E4CC3BC03240CBE3224662D2B3AB7B3E177E6ED05C7EDC0E96600FF6527A4F -2A63179E47E74DD67A4D11BB1954DD479D7B66FA38BCBC85411B841D963417853482EDC6 -0753CBD2E0B0EA725170E33CF7B7F801BB348538360EF54A01CEB35AD465CFAF5ECA3EA0 -CE3DA1240E1C94A7F88375ABC46AFB407FED5EDBFDD79AF542956435D271EA685D9E8474 -ADBB88246355C959AE1408A5C4E9209FEF36253B0EA5DF070DF4BB364FFA3386A7FDA80C -046EE0F54552D258C3BF0C964718077914D4A43854FEB495FC4D421C2939978770ABD337 -3160C7D8C9D81F1F3ECF40D24885AD5F26805DFAFFBE9661031313540B02E71E1B9676F1 -5DA9BC5311178BE39B0FB98F3D7F1064B7E76FE3A15315E234C712AF8542E4E1CA1BC2E0 -8AE69382A34FAEFA2E0F67A6B62144B0C767A45C5DB57648171D43E8E07611E04E230C15 -5A16B786236833B51833EA22321EE4A3B2E273EA7D452957438428BBBBA25E31A5332106 -54AAB61F2302CE54F7B2A0128327D60ECDDE0E455FA05B16747F75D9A27638A174482ED5 -DD91C796158D9A20FB380971BC4E30FF0BC9B9556B4B53085044044AB9418C2144087A39 -3FF2988DAC87F5B872684A327B30E362978BB4903DE7A4C3967F62712B8EA2221CFE4BC8 -72E0EB73E63A06844ECC468DD8C9D2D774C3332553B9FFE6143545F214E3DCC512E15990 -9EA880363696C962E6912D26FEF0618B88BD1587CA13C3A82A423F19CF9347D55D005380 -3B1B91B352177813C3E20C5F04AB4B9A2AA11CD39E11125CEAC385C25299DE0B617D81AD -8091CE925DBF4675E7D70A515B83800F1115762A7E964FCAE0C61BEFEAE27CD77E39153B -DAA1C87FBAC70011B9A0F62A838A8122903AC09A39E53F56935778804BF3D025F664A9C4 -3E314ED0673FEA3ED9857079FC6A49A8B77617014A7054017601B5C6E75C8CD05F89C2DF -D8ED46914521C2D972BBE86480177A3A2B2DD174C77BE7FC9E0069568B392C124774A1D8 -DED4DB00F17024B55A5048A4F33C6EC5B0BB43EE3AAB650D9BE28160D4C0F128BE5FA21A -A29DC060CBDABAD9BDD6CE0B5A4B2051E038794AEA31C482C2B5586320652D940FC3D6A8 -012EBE0EABD7BC1491162F8FC1C40D07B904B5758515C1286DE71562A790E8A86B6D626D -6327F9C7EE4EAEF270D5A6081025B95DBB7F57C33B819CD417850311E3CA2899703649A2 -623255DF77C213A59602CB749F49A381C6101D27D7975ECB414D601B1F893AB8B8159410 -E92550514FE10C04C2D218C7B8EFAB3A007816C50B3CB724411558E8DC8520908C205239 -501DB6FF5B5CE1767C7EFAACE931987BE0797361B3565571F440FE447A168AB3360C3E36 -1E6DCF8F6482885ADEEED01DFA23F47C6B44E6268DAA6962225B10D37E57E20D9C55376B -9D6A880A90D535F91D3893FC09B5409F2D2A428BBBEF2D9DC4686BFF8A863A6CCAE5FCBC -5090B2B9841AD3205B0EFBFF72AABED459118C799C6B281B64500243BCF11D5531BB74F8 -A7F676670EA1342A41AC8FBCAF459C9D11D5673A0592AFF53ACD4B94904F7FB3759C59A2 -A7E5FC2126ABFB56535D0A6240CDB83223EDE4371D910931D7994AE05CDC24FD81FE8126 -5E40835FCED262A0DEE35F705E0668983D65A8CE7DB1177CA8B7BE0A73A99D4D3C44F401 -DD6CC8CC119FC36438F18A924D6DE1C2040D2BAFE336277A751D6D4D05A828AB3FB8BD48 -A7DE7C166360788AC8DD81662727B330D860166B2AE789181E4231B5AA3A205663024162 -C053F2213D30B5102B3C430F9B67E3FCE64FBA1BB617DE61D2A64FECEF8B6BE7D4074E75 -DD4AA701474CB17982EC4203E1754A19DE41874EE1818BD4F243869BEA6422CDAD1FDE4A -84A1410C9BC92A32525D6DC52EF3E90F5829CEA418542FCA02FDA62666386F628543CB04 -D08188E6B9B0092E6D00C6C75C5CA9436AD0597C741D4B2C63E585470994B5466C509B0F -D077B49D87DD6BBEAC8C6C4197B9C0789025B49BDD9534F42CCF987DF9B04B18D19F9343 -A91696E0E206F4DBDEB45D6D7697B49C4FF5584800CB512611EEC8415BFE1983BA96BB82 -3AC3E496D9D79C6426B97A1455E070695A27E407CCFCE7472F147EC95134B89BFFB87146 -982FB4756612EE55A782F303B54670333FC04E707FCB84D255B05D52AFAE8F473E8C4FF1 -F6E95EC1B820ACD2D3E980A1B778C4568693AFD446C6E416C48A45CBAD61564329C4ECB3 -A98B4ECFB3551D1F1C03717D29A5DB62C8F1B21D036714A94CE536D0E84E3E10800AB513 -91E05C62F2A9FFEB3A738E3262E1919FDF43EF49842F6EE5D309FDFFA0B74FF64262AB5E -813C8042B2F450A5CF7B547A8383039E7C14567EAFCE9644DAB0A54249EDCF4C24EFEF7B -B3EF129DF5A11E12A78FEBA6080680AF4476F4C0AFF6E8B27B07D6EBBF5B1FEB28341344 -3154B99A65CFE335224F382137E3AC87777A6719AC1CA6832B61AE8CD6A1931105707F0A -DDA25615B526EA2543F6FAFD00D70E4091B6D5D58C9CD62B19C70D7469F6FDCABAE2A517 -66C9B0DB0AB351973A4E2FDFF81DB1651DEDB905ACC447FAB2B2803E90DF264C96092528 -8211E23246BF45FD1AC67983A7FD5B371581B8BED06B9CF8E6AA6C4BC84771219E7404B5 -6DCD474D9B859D1891FC2231869763E6B8F0615D7AE7B83260DE84BA39D6D60F50BA70A9 -EA8FAC771A0F0A745932D00C1328806D938CAE671B94EEFF484E5FBE9A74A97CAD47358E -A3CE9F399407407FC199677DD7BB6B7B9B00AAE6EA1633EE18DDBD40FEFD138F8423B304 -4B9E9AB192B7C767D7D63AAC804F0D5309E0FE72A8259BF12DBE7A215B8FC8460C285C4E -26067E3C558163C1622617B082C6FC941F8563CF4ABECD0DBF79CD5DD86B492E3C46D0DA -BD16AC96ECD6B41212431FECB4EF59DC7DD3071CE030BD5DE690BCDDEA9A2594C50CF77D -53B223EEA513B40CEC7005C4F6B6DE2D3680EAFFB6FBE0DE70E7DB5C11F2BD4085C123A4 -73E5CA0785FE70E38E081B5971D4C390A87CF5DD83C8BD63C4307D22A1680792E27FC431 -8D403102A052645B4AAA9BEEE578CA28E2C15DFE12134BCCB2171C15A45C5D4D8ACC0EE4 -A2C8AF801D64D5979E52AC410A69277160104A386D747814F0DC0C178CCC2BB40E175992 -9D3F05ED411630ADFB8E4E57CD223E012F457A8A7C2BEF27BDFD41D3B39673ACEB92A48C -E3464A8720196A60E21C1736066FD19154C02D7BC22E821C76F4B89185FA39B48B00BB85 -AE14236DFF7E1EE1466C65A1B4B9453D8ACF727CDC0EA04D85E2A4F41976E4833C145444 -B0465FBCF96BEA9554304FBFBA4C39ED11F2E1D9588EAC200B31441889B081775BF75B6D -7AA3055C85ACFD57DCBDDC12257F565F1980DA3215AB29A2545B2FEB107C91A454DD3C32 -D7D620943472E7AEB5805E64EE7B1D3582A2DD74D439AF03C00478FC35EC9017F1A37B59 -A31A196CFBC38B4921A76E41E3A6E2C0E5059FC3848DEBAA378D87736B01C6710B5B0DAE -FB06D00BE44EE7C687DBF6CBAE699D88694891A95392324C6C49595C7113FD6D521A182E -FDB264432F3B661D4E86766A7DCA2E53F72F7FB78A0C436DF0D516EED141D796F3591226 -E617BAE549DFFAC4CFA0F555DF7DFAA525DA35DB699A892B09E654992F99F89CED6273C5 -9EB9C512BFA0465E61FDE63D312B1B2758E645893A19C82A81E5E0F5AE8E51621EAB69A4 -1D425F9F78B47ED5CEC857DA012E641D5C203532691F9177F4531EAE8E6A7D5A2B1B374B -B921CA70F41E7F32A8D83C54AE01DC76C88A96C1403FEB6942029A86B1306AB096F8A42C -2D7FE35C7E9F3DD494579CEF39755AAF7C74909CF5F7322C4FFB2C5A196658B7AB49056A -E3DCABCDFE40DB0912B5E15BBAE08B72D7AFA7D64265F4185401E6E723E151EACB8C7494 -819998FDEE918EE491E4F9D5F889378256F2F7858762A5E049A618ADF34DB73540486414 -1187E3CCF635097AFEE95F695F806BA1419D85C50FA033E4E9FCC155849677B3A20F6451 -D8E4E5AB1BFBD967B5F53C21A30EDF1286A0E19FC557598294586D5184D1CDF8BC83594E -17333A522E32233DAA8A6EB39A6330013C32A2E74F0EB6234B63D47A4C8D21E1618E5906 -5EB21FA9A926E01A78A60FBD71808A0B75F65786A9E3E08488FE89E433C287DED44763E4 -F317DAE0709D7D54EA969B751F4C62AC976693FCD366804E66B2BA8D955945B86D492E74 -F17C0484FA5C45D7F60DB0D4578C5725A88A9DEF8E5D31EA02411CAF6F703AF96F50FBBE -6739B57D4C1C318FE7D491C94565DEBC43078303D329E87078EF9B48D66C3E98ACCFEDC0 -A31761AF6854E5C4DAD36C809876D93C06D91416770CE8852B5E54AA22F6EF1A5BAD532B -E4F55FE7E2AB457F3242030F443975DFB0F2CDCDC1BFE629C8BAE7AF2D21C9BEB3EA10CD -E4EAC54AC081CD3C0AA161C52BFAC3A9E4F0FF77563D6FDDE73E44E926E1BDFAB4B1A11E -2B4A7E1D2CF9D6B9DE48D99DF99E0DA53F5A449B344AB2ABFB94BE9E60E6E9B328B58337 -A4D4BD60CBCE14C364A2A1D5C02410C2E8A98CFF3A48D23C752413A4FCCC5C044AC99451 -20B15B31CC5C7B5FC6D80866C1110B45F9B274326656CE6D74F3481B7D5DE8E5AA907509 -C15914FD27CE89F911641DFD588812A8292504EBDA5645E8C510F5E88EF44C573CE46D01 -EFBC6E3E1BE9600D77210B10330748F210F2CEE4841940A78AE1352654139757283F0FE8 -12040846B6B24F1D96EA06CEDF19F0E3359C8B30C3986C2E20F5801C7F74ACA621E8C4B2 -4C38B9888AE24013371F19C80165522AC90C40832C71E617E042ABFA071BAC4D87D91F86 -4209F5073D3E54A26FC2FC8F89DE3C1B121881665D48339FD2FE7B0ABEF5491941DD26D2 -B379900687DC8DAF6E35153F409DD58DA91742E93CFAFD431EDB7A32FF814048DCEF7459 -830CFFFCF958160B1B54525EFC46D8892C30561D0D7780625B0876D816A0099AF1EAE992 -AAB126289D55638559BBAF487E1A9E2F118B3D498C49767B28FA680BAE464632C94435FA -E32836F8093885A91F66CD5070B91558616853AB410AABF0DABCC02BB85344751A2B2911 -3847CBEDA65616487A853D9104D0E00012F179EEB06D9EC54CB50DCEE655CDEE79F89318 -F8212779CC310304A2F604402C8EB99DEDB3051CD1EC0D03309EBDB8C3B5A89E06C49957 -5E00904DA0106F87D58FAEEB8581EB47E982E29C5ABEEC747205A33C7B05A0CED74C3403 -0012BB647B5AB617AC8508E8A0F254E102406EF1EA86DC39CD9335FC8A5CCB1504757BC3 -AC11BCBE92800AED15E84FC3A6FD8BC6C27C4A13AD946DBC65E45B3C1F72D4D2C1793512 -9CAF2C6C238F1E57F428CA2CA51ED139015DD06B931A9FD41A8A759142F50D4A18D9E071 -3CC7607EF0337C7B401CC2E47F0DDE63B32BC1DF572F94991D1BF97F1BC17DCFAB95A834 -E34652C6BD93277754DBBB1DBAB6F0158CBB6E9304F9A1B5DBB370C3EEF6A0F937A0C7BF -789CBB57E308D2D3EC0A0F04BC3BAC016AE4CFEFD4A5F5FF9F2289460CC7E6FF27A7B421 -BA3BA86F2A48C2002C4C0379D90B50952B6A629ABEC22143A906752E0BB2DA15C36EF74E -DB102D691DECF27A7C252D866640FE74BB7BD351C4DB5C8E4956FD73CD6675FC53DCAFE2 -256AC5E46FEF1D0044B5A347682FAF71ED9CC08F231605BC342148E3CAD6A80ACEECC89F -767E814046DE67F5277CD737D09A62B499DFF7908242C6E5F17987573334AC66ABEE66D6 -1C61D14C3687DBEAA7BE38D248A7B8CC775C5B577305C3F41BAF7C7D64B43E7326133C2E -795F50EF42EB3F5817277E2690C8785064AB6BC61AB04F578549BF671D88E113DC704764 -91AC7787C2561DF6AE9F3BA5FA24F5F2C49B8B72833D030536BCF0AF10592FF37E223065 -ED6F4BF075F70A7D0ABA84CA427CCACF9A0CFE46A429FA64597C677C71A231C997AF401D -07FD7FD98F4A5826DAEC4D76B2E6A8DF68AB8EF09A0A6BD0097840364FBBBD4B93950A16 -CD68B07CDCE7C341AB8647A3338B1608D67CEA47D26EB1ACC0F94D928F2930C2CBEA594E -B773548213CF17642DF03784B9293BBB8BAB745893C2CA0F9450A337E448A282A285867E -0B0A2F5DD49A23D475709131946B03E8C2F7B2D21DD7F1EE583B22A73D81E5F72136802F -D917750E53E63031FFBA218DAF8B3DBEC561581706AED8A5CFB6593F5CC98BABB048587E -C9EE27EC04859B6C233474BA9FA8F8D909B17705C6F2BA0CEF169B46497E712C458354F9 -F0E1B72581F18BF74AE06CEEE0DC27FA684432625C579A29843D44973D4BCA13998DBEC3 -0375F1C05CCA91819C3F7C7F2A240B515AAA8403230F9367CF391F3538ED5BD391E70F24 -51B6CA9F969CCCBB58A05FB86E90BA4FDDAEDDA84A73CD40617486DF08FE7985A55F77A6 -B2CF450665F98F0D173D0DFA608A4E89CA6B7CF2F86134CA0B97FE3FA0856613C7E71D9A -4389BEBE6C1DDF23A7D617ECF980EB78AC5FE99665CEBDF1BB8C1CF29C345B94591CE29F -3E77AC66C3A9A1FB34526A1F335E71FC1AB62B4E8237E80CAA0265FDD418322B068FD4AB -0E603448CC61D57106F1BDDB5785AF5A18C211021FB6F91AEA6112BE9F34A75C6C428EE0 -8101FD9904EEF19996EDC2235F3CAE00B0FD20331597B63535D001A5A2951F4057C83A8C -04EC71AF466EB9EE31CAE51F453423FC327FCC256D71D4E2D956538C16231BC8E6A54FB2 -85E7D5A967CCDA56DEE48109FA4776F87466F0F62355CA0990097B2BF7F947C0198F13F6 -EA5321370A9CDDD612DEB3C91766A19B4228AD5A4D782D9C51BD3DDF268D53C24F6E4543 -52B2780CC5906D6D08A27AC49043FC1ADBFC07ECC113D815AF2BB5922E42776ADBAFA1D8 -E8608AEDDDA45E181521E5A8C39BFB2E9E72A7342D641574D84AAE3D23F114E2C675E50E -98C0C4D59107E15753F2E29B2EBAA4D40A0FCB785E0F20FE5EC3F4C42AF3445298625AD4 -656A42B95D3F3BA64495423BCE66806EAD119E6F949E5E0CB7D20D8B218FF77704BA5CCF -C6B96CDE2E22E2A1866F80C103C986D01BD96F2207438F8132ADF46C5E889C2752458D26 -050C2D2D9996A7E90414880A34BF4F6F7EA862ACC40E6446C8C64BA66314493C05D5552B -FFD967B26CAFB3238DFB04A14757FCF34B547F81448D5BE2C385775093FA69D2B5264954 -7552C28488251224E4571A0537F87370D575C6093047374077BCDD8315E40EADF2ED65B2 -9BE930D5A78E0E4F21ECB50582FE1501FF48EC392D1717D5037175395D726475E79B5EA6 -68150DA75B9FA24A530FEA3EB4D2E4D73A66C800452FA1053CCEFD77046B058693170362 -AA4EBD8C51C334C4C24AE69086BA5A9AB3E8540E0AC782324DF007DA127A7CC2EAAB55D7 -33201140FA9B632F11D41030ACEDF37F12D4E4801645CE624BA973671E41C1A11169592D -CC529462D2047E2A5D06FE543E5471D0A0FB591A9D3568D2B642C2DAF22BFAF136DC1635 -11611AE38717F04BCE872368BA82FF9256AAB0AAE93D52A286FC62802FFE2E8FF98414AD -A2E28D0C07D95FE5C9B025A9AAD8A355710C6085D45BCA501AFE400EE1F9B34545AECCE9 -8DF25A6C7330711288765392C4529746FACD974BD8CB996395FEB547A9D674F5E56D4841 -32A4B48D87A380C52E05C86083677D88696CD2CA221E676C8F950FEB61CC6CE37D055DDB -83089B0814A90EA5B3EDF692055D7DE2208F5F5151667ADD999A0301E9D2A017634D3C5F -8B645C726D0BEE71D4098E0739B44D565FF574FE93A250AAB0879413C38763AA3B294956 -BF0649C5495E92262A3EE9E3CDCEFD1DCED80221217ECCD09A04B2759C746D720C3E88E6 -22174A8E496228CE9BEB430557D8AC5A813670400BCF93AEE40CFC554A933EEABB239B80 -EE603F1617B3238E4EAF043699EC674D348997BD3105B8EFCD06E55F78AEA6AFE81EF9EC -836F4703650D803CD01DC38094F11CFF0B34734308908ED646E5B37BB9524C886DF94F83 -B2D470752A139E6A06ADAEB559E3D5A1F4EEB78F896AAE3D9836D4C7D4576877307821A0 -DCBC61D1318B937ADB53865F9F9B6B90659DC518108B81196CB6E81D676B1EAAF9B0F3F6 -FB499A99BCC7169E7F37E9808634E2A0CA9DF40F204F86FCD7BD135D177ADF005B5D9D9A -0690DAE940905664994FCA90777CB9B3C4591FC0881FD146A41E9EBE7B8F74DD407642F4 -5BD399C6EF5471E987E01A009F532C2E66305C890B0B582824B527ADEDF668456AF3776E -4634332C59C3133D8581D47EF6B45B636422CB5FA0B117FE1AE0361B93CAD6850624F353 -FD41296FE84391636A2EF92A3658E07B857DA4FC19889E760494957276BFF9543FEC23E5 -2A7C9174B581D299B52DD03AE726A95634C8BAC12F17B80B3B40BF98BE848CC4837C3CFE -FE2E3B64B5A8BDE695ED0BA15451AFC5F0576DB1E9E9F29F05D4DD02EC3AE44E15171CC5 -EC254176D86C83C062B7206966E7F0A8822816251C0AC4A746F661897E24D2A44AAE93E1 -259A4C582FA34DBD0B4952CEBD2753EDFCC37ED685FA00E67C455D03072C2A218647B582 -F58270B59936EFFE692E0F27DF5D73AEB8D2CE0970629D51B9EB91C0D2712CC3BC71640E -9ECA1D662FFA06E071D1E013695854792DDD672080A0AA42657C9664D6D850757DDBB167 -9FF6A837674A5DBF38B2A435C2AE04EB86D351FA0CB82F0D5F00A96D55976B44D6B6BF5A -75346A8CD71230B6A44268B73188A84C47F09EFD13CBEB51CCF7ECDE43A3BEC6933643A6 -68B023344E407CB2A6055EBD6E75A27B6FFEFBD095828A8C5B9A14FD78AF99BFCDFB0A27 -3313455D19B2036304167E9F8264FE47E1F5AC04EC94FFB3E1D6C90E1758758D2E811C7F -DF1EB0AF24EF89E907484BD07B8D825B98D99AEDF1FE0D67FC98A0159DD6492503B86C35 -FDBFA654E3CF4B00D0E4E50A77BAFC6D4CD69A668AB5D0436E9A2DA573E04EF308A6A928 -29F21A8419FF3B7689590D3787B3CDAC9B6A98FC0AC7B06DA9748F5765A25708C3E9DEB4 -1DF4EFD5BD9E0C1090BA956EB65087F5FA803CE15BD0FB4090EA9DA33F86512A67CF8775 -BA3C3D834FA4D6798CBE5D5439279DD0EE083DE2026B2EFE83C203C632193D30D390443F -A5D1D1288C2B7395BF91F3FA657BDD688A562EBBA50DF28EA5834DC1F9CE073B704D2DD8 -594620A53DA722209A6C4A9A906B552B562917A86373C43132B5997CCDFCFA398C35EAB2 -D275883CF4C5AF773B535BBA0CACB12ADBD2B3407C8F046F1D4F391EADA619AA2DB788A1 -93B7F6975889D7676AFB6EA09978E9590E75F7B106112D0B62063A21DC59110EA5E123A6 -51F2BB21FBD6C80083E5B3405835F9AB6DE5A7C579F8F7B006983B897E4C9224BA21EF0C -DB8546D2F477D280F554F98AABF7F6D7E890B327129F4D43E3BE119D1E9B1D42FA1A7F39 -0941803CC1752DF5A9198AC5AFC71DD6402095EE312A89D1466307F0353A610881A56891 -4EAF39DB13B984A78C1B9EF169EF8781DE0BE7B20698502E8F81BFC06DBF766B3CE28A43 -4801EB4FE9703BA5933AC6F0872CFFCDDADF1135D02714C30D5F54D36DF3415F416D66A7 -EA918A64E00AF9213CF9CFC63B200BBB4402E53DD95BC8B5AAC20E62964AA87173563396 -AFDEF06AC069AFBB08D6600AA3A61C23682551F73B2B7E4DD70392464C439FA6CEE41A1B -4EC280388A8DF86195788A9B766DCB0E1AD6AB7A1C66A1835D7AAA8FC92741104C6A5553 -C149A5BEB648BD3488C13494D9661FC8F9DD431E9EC1989CA9B35E67A2BC9FED7BC3E362 -6389B29B863DC77F8ED314B47B4B86C9E559A6E41366D47672D9E9314B192833D3752C70 -3A571CF80D6F165C660F42F58DB5CEF453943C7DD0D252476F678E44C6340B7E4D52C927 -5855FEA030BB191D34FBF80C039955C2AC6F0C38F6FFE281A52F13B62543DF45BBDEEC7B -A2CC3A125963D1524EFF639AFD013A472B336E43E9256C3EBC5910A05F641EA1ECB98857 -FDF7613E9A3790F9FBE16F8B1E9CAC2829EC0B651F00E1B6B56F0025ED82BFC5FE1D227E -3DC00ED525823F310A834A747ED0FB5F5DAB7EAB307D0906AECE8AEDC3808C53C3C9E954 -6771D79028ED61CE595EACA42B6ACB8C47B1417F1E88391C0CE35415C9FB29106F8EFF96 -82843119AF94F798D7079D40F21B94BB3061C2155A87075846A62B1E1292B465E946AE00 -A3EA7C2057244AC8C4D54A8618AD7B06A833E9C26BD2BF4A40CFC7F7D780DF4C31B0CBE7 -0657FBF4AEED88152E1FCA2956141559002CEA98E7299FD83BC9BF9CA0523697D9E188AB -2D883665C329A8A4803C8E66072DA31E615FF9254BA8CD94A5C6CA0EE7AAFF3108F48D79 -0523D58E98803CE03FC53E71DF394691240284E210C77595F292696975A206A43AA7FC7E -C0CEF778307863F56016C13EA6A26299FF417E0668692ABCD895E7CAF13A9C1BEE2B1E62 -0DF960006550CBCFCBBB006257051D7254425C49F840B8EE5A44A61E5AF465A3A831FC26 -A8A2062943955676AC4D5168EE2464067C056B1DCE6FE780108953F9FAFB6F89DC775E63 -6E3EBD3308468ED7B31CCB4D80142AE342D630B919584B2DD67E904A48C5CEEB65C1C84D -8D2964A4842E8C2A83129C91662137BE032B007A30A0A4D2B31ED3B1F44AD5275FF105BA -929ADE2B78FBE0F3F34E2E9A35568D96214AC1A347510E8E5EF0C9CCF08798C5B0C09DC7 -3FE817E2BD84AF14627A8210099509770C680C327ED697A255B28E81DF6B512060D47084 -B8AC21EF59C34AA36A9D14A093116EADC45F3F64AB297E114053081C8D6B135B36D25AF7 -7F2050648799554FE6BB50CB6E957E26A0C62788EB76901B438AA6422118463BCE7AB3F8 -C21E007C21A9434A0294650543B58F0925F664585BC875ACBFCF44F5BED0D8AFB0D8FD6E -215A03ECB350DA054FE30172E920C34E64AC011A655F5A782178DCB3F65FEFE0CAA68993 -DF30FAA2471396F6D74213C38A511773DC7E84A9831C2E8C4B51EFE3D8DD0674050B8DBC -F1E09ECA5BBCAB73780ACB37D46742594C6070EDC7F5C555FD50044208F6A26316F17B25 -1DDCC694443233702745485F3CA188CD3E1F833C99ED46EE525D31C6518A86B723E890CF -DE3A834170507C9F24F28A124DDC734BE002039E81148D73F8C86918DE78E07964001EFD -9A3EE31A0347EC258360D2CA6AEBE7EC4D5FE0A29D415DD78A13B8CB8DA84AC8E480FD48 -F4A9440EABFD6A1C4988A7D6FA7146CBC14FAEB8864C578A81D86C61C0D08AE6D50F5654 -DDCBD02D7D9D9AAA56C417D2A3C42AE47ED81350FF917E7D5D390D4BC8AB934353D902AD -98BBAE982ECABC933FD33310FEC3266BB373AF3B53D8880A8106253FA48D78899D0E6548 -A9EBCDED56B39BC0FA78BEA9A795BE60BD3D60C1DDF5375DE0800F1FD55AB46B49536F7B -5986E790A4FFAB8B81B7CEA21980D0634E7B2CC00D1D7A9A7C00A5CBAF65476A714ACE77 -99795EBC2A944A688BC40F2A23DF71B3826654EA7646D2338BF23E216A8EA59AE50DF2E1 -D6A05A86C25EDA267225592F695FFCEC993CFAE93452BB3F2C17470552564F2AB70AAC50 -D49ECC01A418903401B4BC6F3E0D3DAA9CD062AA1A8B93016BC008924F8AA7075ABDC5E0 -01A215A63EC8A8F1FF0E7F5A1102D2D5DBEEDE248904EE28590A4E48C98B4E97DCA69479 -08FEBD5BD880AA737D2A600A71D1CC35B20612F656EF4C125ECF75DC0E1BDB57BB09BB26 -332CD1B9AD52147CDD30D03EAAD4EDF4C7C2E4092C409701BBC8EC163E4C660EB018B0C3 -4D4844EBB910E0566DF844ED250624A6C8BAC481B32024FD4EABA3D4E8A67F83FA4E4927 -A15D64462B3004F5610EB847E9413CE174D64908B0464A144DB43FA1FC8356FBBC00D303 -74E22B3EBB141575D6EA036CF0B469597C57AAAC00F840EDF201E57C0D84929A34108847 -E90C97352CA858A6B1F76E1C772C1DA2A8362D02EC7C112E8755C7D720AC5A2BC528913B -37E0BDF15147DE30321647D8001FDCFA437709AF90ACF0E56196A9696C0054E67BC6630D -7D99F3092D8DFEF0C788715D9BC43788542693045A485D5231D731EA740BE448DBB72ABC -A34AA5B8B2A4EF6E91F61B0A8AD9666808888DD61A09CBF2FA30E812BF1B73EE2D387C6E -4821DA27733C60795C8EA0E806F74601EB9F3676284A37ECE9495CB87015F18DFB39B9E2 -93303261BE268AA644CC7793A6266C026A06BFDC3074E7A67C8F6B35729CE40D6C343C4B -95EB9C778F6D513CFAEBC5FBB8AC844D1982F300675B0920C098AB288D12423A3401B6BC -CE7725E619706B6241BE210CE68A5B3F068C7255C6A0959CCD3AA40627230F27057001DF -328A741F867833911AC3D24DBC1C79462012801A6E0897F2896AD1B5345F72BB639C799B -FB4C6EFCC57760C82015F6855099EF7C5DE59C5766BC6DD4F4A61110E8CD93BDD891A83F -D8DADC0AAF16032E8B02E69F1EF25EF7CA8C23815C38F7FEEC5E4A4F11BF1E0C2275FDE1 -B29CF45A585F47962E6137150F0AEAE31ABAE6DD3D66E54D8B7E6707445857348F6326A0 -9F403CAD72D93B038C91B7465347160DE4FB2F2F81B4BD24449CE03BA177C8E13B3D590E -A6F4C5CE396D238C642BAD4C5BD4C0B2EC8B935BF9D9A85F64D867799103E285264A5F53 -CBD2E0B0D69176ED284676494369C38711ABCC23E61961F6B46C576B407D273EE84E274A -E02EC5C8923ED2D5AE650450F5A1665CC148AA0FA6E26143BBAFA846E9263E49C9ABA1C9 -E4ACC9A7E6ED0865B42023F21A1F234F485C4F22B58925B336BF883906ECA1000F456773 -48250626716520CB2CA5DC9EED93F694A1CC6D7EE74CBDC660E3A033EEB0CCDADB32C5FE -9F5A4BB9BE18F13A6CC678213E631916E283D5B12DD6B9926279CAAF46A469CC3D4EF950 -D701A667C2BFE15292FC3A2ED9E1C916B90C9E25606ABF91FE44BBF18CB230EAEF6B0C30 -3E94C24F82957557840C11F4845C7F2C49337CB588FB9791EF1C40D4CA00CD5254426E84 -391C265D4B21E9FA474843065E306BF794BF3F798505285246B906CA4F343743C5539EFF -AFFF1F93CBC5DBCA989E64B2133EDC8DECB05FFE150469EC1433E3A3C0B49B7C14EF6069 -CCC488A1AC96C39203C010647ADC1BF32B69623D291608BBEEF2C5FDE603863C91029AE1 -B6287F8576F73922B5192BF1B226ADC2DD17D98B8D0558874DEBF7018C82A9E9AA9D89F7 -DE237D1DFDDE2BD43EFDCE2ADE67906EE2525A667883685DCF78BCBAE353486C96B3831F -C1E1C7DF12DDB8CF10895DABD16A1DFA87AF1FDF8F4A6DF019395D713269024BA721CA02 -C1E2E605BED8AB8C822CC84903A7E5BA090900F1A409F4B1D30F740325E4995A5C9FFDAB -1B8480D7B5B8CEE4F35206E13EC960650A2C1D0C4D7D7407A86E583EBA40267A67A8E87B -19D41649DDEBD7A73593AF94C2366CCC6F81BE9558CCC90CE95060ABA2BB508467640E6A -726ED96B571CE6F2AC68EC104D3C2D3AD54F8490DE638B77C93595E2B1A44B079F79B487 -B92C12B16B203F91DEC2E7183AE99D79DCE4BDE5B240767D52438DC5AED4ACC691683BB4 -3D2A1636C917B6E270F309D3B75D34FEBF8BA64B01FDDD848D52C30FFAEDE43EA21C9ECF -487A31ACC1B1405E615C9DB6A9B96BC45114E20FAD0CCA71B410BB14A39997E9653FB11A -666995E488B650EEA712FCA7206F5228061BD5BC385DAE9CF087449EF683F69F673F30C0 -33DDD590F086EDBC3A72F9B17F488E2B36A381141F355AA1AC81AD4C103101AF96259CE4 -30A0612CA3110A5953666DB362D982687010AB9B81A63256AF6E69AF6D8B3150FE860D29 -E0DE5D686096A3D523EB8CEB214DC73CDCF00D2E98BBC713C6D7883AFFA02188A5E8A8C1 -007EEE1B185AF14BF0D0E06BB144660A5891C8C7710B2B85CED49F14A5D5B028A8FB6464 -3CB3B42D1EC8C334D51A270A3A2D483B223C3D95C733D79A9EACD97F7BB32D28BB381D40 -399F0B9BF194521F189D37040DAFDC8723BF45FAD60D2527503894BCD4B0B746734915F4 -F5B04D4E5044631F40BC3758DCBBB2A2AB63D7B44EEED53991AFD2988E13A7A6C389641B -32819144DA32DDB3ED45873E6BA0604A9E682558C0BA2B139D29E4986037AD326BDF4079 -B6C071DC3607D52DA49F6BF8DCEF6F04C4AB860D660BC30E758518E16102642A190F89BF -D0078394DACB5052E74EFEDA5BC176A861D8C5D78C83A46B4D5230786068F12BCFE1E73E -4F7865D5B86144B26AA5490F229E6FF7CC5964AEB6631B08E2A4EBFCCEA10488CABAF2D1 -576155E6C862855CCF52C74834BE25DFABC0BC4FB7A1EA21B2AAAAE45D1455D844C6AC2C -C57D081149F6E40B1FE620B697424B85A7177F19BC63E93975A08CF009C4659EF47A3680 -488C43751FCD7D848FF55C472F02029253403CB04872EA4364DEE69934F6D049113FEBC0 -E3E5D978CB8A2423B9910E3901981DAB495C4F323C3E3036BA45B66BCEFB4DB5C7AE91B1 -7A4A956471BC552A1C109EF67D97069D3DD5663063262FF4270CEC1079BC4C4C2AF643C4 -FE0B5F3B39389C104D40B84035710A59AB041F67B5FE2E5D3CA3E720D1C7A3F104A74C05 -DAFEDF29777AD6FAFCEA4854B864DDFC878DAB7C42CE153FA01857AC1D5B1990EB73C82B -A01D3557E10D14742444761671084F1242C9D2EE9E211465F5F8F0333C77B123D6C03A92 -D0D8B91822D6E20DAD190F4D7A1FB12418D6FE63A2B1148CBE94328ACB42845E27928643 -444C3378FBBA83ADF56A3DF9ACF9C1F2A8F3F2F3814E26D9DE7494E2F709A57E373A594E -4F64FDFDA6BC3866E3F7BF58127F6337165826F3D20DCB22EE9D7DE5CC14D10DD3BEF093 -2B0D75E289E5A332700C2CC5EDC65CC61C592E19144A13A38E24B1FFF7F904CE261FB76A -31DE7360290C8B750D92E08A25DCBF3BE97529DD52F004AD59C6721FEF0EA46F1693C5D0 -992C517536B390C86F5E788995B35B6311E6EED72D15594717CF385DF042F8515455E808 -C54A0155E58D4277FFFE04CF0C16E1259F39E84292F592BF936FD50BE54ECAB54BD27CDC -4AFD246C35D901882765CFA13A381A4F888462CA5A775DBFCF37B864AADD8796ECB2E13B -4156BDA78E6E7308F3CA382B478A60C441B09483E6CCBD51E02E5664E8DEC087AAC030D1 -431A2301C1034BFE73EBB7F2744F689D09F424F22A48960C991526F7063B78EE26D0F997 -B917DBE51D7D291F54F1C22D3E9F9B8472CED7317B6E91F4BFD2E3623D6F3FD2401BA7CD -6F93918D2D629AB72C4060B6E72AAA295F0EAD79B0A7C651D5A9FE6348EFC9396664557C -0D5688F01962E8526CE7A55866CD56847F49BD43A674D6C22EA7EAC1A4D437D2A9BCFA53 -5361CD640DFE5189DEC2AF088359B13C6AE7027EA51DD1E757DFDA89A9BC23BBC1138839 -C549FEA71E42F497440214911982F115D3A9278D2119E0A17F0BB1F8A86B7A776C3EB940 -8819B2602C66C523FE07DC9AEB0E6D4AB6F39A308A6E8F755CFA0F41796159FC55B3A083 -F28494B4C0FC25322D17E6083E79394BA1F444CF84E5DD9D9721121277CAA3E0E380A7BF -93C2335695E2F34D05CC3C3FA3322A7C863A16A9A5AD4BF1C629BEBFC20FE361AA2C6CC4 -C0D3EAB00097D9D2344B8772B049CF951DCDB1C23C138B2D7DA551A22A53EA2F604D7BDE -8AB2D034ADB57A65DCA8CB55AC778F9649BBBAF8E7223096CDB9780455268FB9CD379AF1 -DDECC2F7C22A25683BA56EC7AC869150810D8A6A5B854A78DDA6C21C9FDBA227E26809CE -FD44A8E4593DFA5B9D170A19B9DC779F507FA0B28B5C8E3AC017005FDC519E8CB69B9385 -760AE1A8A111E763FB0C3B083BE1F083AA14DF9CC83142A1DFEE5312097BCD8DDD91F113 -0A3B920FEC7E9383B23F7A396BDF28BD1EBB48934BC490D133D594021C256B698BC4E93D -1E746522E485DD53C1B7980EDF066F7C7FF9F27FEC20ADDD1FEB09CFC81F2B0E0820B90F -FB40B66CEA152312DC5E7F8CF45AA0B45636859EA9DA112F76B714CD83CE2803D3BDBBC0 -A3FD5EAA7609A1E4A82DA08701A3AC0818DAD502DECE3A5C7D9B5D6DA50F8535AA1C3C91 -A9358EEBDDBDD94AAF1DDE610E9036E1D5E1F180D426A8B33B4E640BE49073C4B0C0639B -0A28D6E08D76DCFA2F4B409EA1EFF27437809073F29FED0E64506185022EB0A5F9A54BCF -ACB0F2BDD859222546338939F73C212749C36D6B0E9AF72EBD059C3838FAC738DFAA69B4 -FA87CFF491D877DFBAD90222DFE9564CDA37E5576BD66F635720F398EB6863C5143FDF5D -A4F07317547B86C5B335CE05755AAEEAA8A927933B252E82BEF3DE30DFDAC82D1354CB63 -028B03BF59AE93FF30771BC27B186C7A9F7AFA7525F719EC5EFAF2526524BAA29793D5ED -C1003A42ADC2A344D0E4210254F2DD33AC58649887FED4080AF18554646C01BF9BC54959 -D0C06E459CD818580444E37BD2852F44C8D6FA18F7DB6FC15174524EFDD0BC9867832DB2 -F837374BB8C9031A27B17A386E6D00BA61D49003665E1231D79E05EFF440E48FAEC9CCC3 -5985299B3FA94586B516C2317B1AC9C91005994A84466514D7EBD12AB998D4D99BA37C73 -EE3C723217B4D9BD5A0AAB12760886A8A99A4AAF038EE5626035CAAB42C6AD08EAD6CD2F -0FCF85C2CE2D6150A559250140D19610DDABB115D625C17455F928B55F762028E49E4769 -872B96F84031DA85ADE6F18D601F6D576C9CB68B8FF011B13DA0DDE4D6E35E5A3E6EEB73 -248161764FB3B122A4F40ACC83CFC073D4657C042248684EAC14C56615AB156BD549C964 -C8E5A5DD901BA9B583B4D176FAACDE48BA78601EC7BBDF45AC7319F7598A93B68088BC1F -B6B4F429609FDAAF3235BFEDF0AB25B6D2BC024B533E6E300165ADBE42C890F17B9FFF6E -45B5BAA3A14FB36D26E7DE60CE24F4893BE0E2CC7A780BEB1EAE0C6AA0EDCC3BF991E5B9 -A6F98F5F5428AFE21113C1D8DA34783DC47969B9669EC1F97EFD43FAAF5C02FDB722840C -108CBFEAC5E0BE99AB3E21CE4E622DFDF8C32250C10D68EB0B6788E5269479CC441B32AC -1FBFC5660164E498713F6A2809F1BFDD79E8340EBB90481932706B378FE8DE987D5BFA1C -B688817968E797903E558F8C7D0DEADA0B5F08D3D9D27C92E4DBE0F123261737DA41C264 -E59CBA14C0F60459CA59AC58D1A766EABC8E5CBCE3D94E1779099B56EBA27F5263DB950C -ECFF97261AC0BF39C4364FDE7BB1CF10DB8C3EF5763BB7976815D78C6F886ECC77F92BB4 -46D284D2948A94FA4E5E59D104858DD3ACEDD4088302B71E6A9DD709D47DF40DA7FF78EA -7A1E226F2C24E73D292B63100F1A6C98548019DE887E739A4DDB4E1D0676967C64723EF0 -F1CEDBA21FF8BA11539BA9F93E55FA54B3DA6B81C50899ADE4EF9369DADE1FA36E2A889A -A3C22215AB36718E57BC68FD115801B35CDCD592DB87FBDD9AB399896E4DF414835FCE3E -EE36D6ED5672E8113B19913958321650C8CCD69DA0D9D7E9C0607715534BA674118C8BB7 -CA7AF1A57328FA73270221F6A2D429D4424F1C13D8CD7C6FDE11B2A119C30EBBEB1DD394 -29B266261E39BDDD5F2446444A9AC581712FCA7B9073E1F4BE450445FC14EA0352D7633D -75C5C5F24DC0C99B888707A6E9DE9927EAAFF533868CC8ABF725EEB94A96699A0821DCEF -BB2A1DFD6D566446CF3CA7C80460C0772C5B7D47BA2D601D3EE74A5855AF4A35649D7DAF -0A87747B37F2B1BC2E13DA21A70EC7D78831B840EE91B89BC147C1A58DBA58FB3749F3CD -1216FF6DE2271EC85C84D07598EF77275ECECBAEC3C99F7686836A8480BA6BCC30B555A4 -0CD5506DEB52F16CC6B4F7FC8B2D8A508FE947505B6C4DE055A188D28FB639553C63D5DE -2FB330ADD822C7206651DC5E0C5259E6F3F489C0D57BCEC574BEB3E8CAD2BD4FAD239B9C -4E6C0F410805E831003F27A569B327A52A5B72446F83813FB2230FB670C2DAA0E36876E8 -82C612BA77B7C486DAB6B41AD9D41A5A8FA66E116F48F8A4573536008C9677D75EA140B2 -C11892F86AD1FC350E49C55069284311885787693154DC010F49927AAB51AD8C816BB00A -216DB9AC0739409ACEE53EFBE5429DC7FFCEB9F54909649F1CA3DAC3B450703DB8A4DD3B -170969E3381FBE10637C9E69A646C1E58EE791FA68E4350FA17BB704AC1C746591B940DE -618B5ECF8FE03DA7E6ECF7F208A004815161E7F680AA7EF1001D6E99526DCC4F9E8F7754 -A56EAF46E1E7CCA21E319FF7E44D531E4BB04B7138E6F6A522B58CCDBBF09EBB18287550 -66CC6E7D2660B9DAEE62164A62E49684BCB64D521F6062904D26D8DB101AE8733777CA16 -B20066E6E88C7BFB3C56156AECC89B449912B0C0F362C949FF0503D9C349003284CAF806 -952AE72AF962F13CAE5A87FDFCCEBB81F154487B260229A9904C44F027C776C4FA9BE776 -DD6D4FE4B8D8C9F52897F843CFD2B14BD3FDE0509659E8065F6790F2C95EC56FCFB366D4 -582422CC5011BDCD3466235BA9212F14F2FA0F377DF05784D75F45E5F863A27879B9BF1F -DDA7916CDA88995E2B52F93A7433CCA2173C1B3AFD83D736D4555A1BCDC83740E9E69A11 -9B5629B03F5A9D18047663D0A6154C4772AFBE9DB5DCC115263D91F95DF2CCA51A4A655B -FB0B99EA0BF628C0FFD5564E882303DE00B69D666F3FE93A2F2358E3BB4BF60B6F89A7F7 -9421015C3B64A82FA30A92D62B0D3564ED96AD8C228A30F4BBAEC782E3A01DF417CF9F5E -8B7BEBB8840BEC912AB7B35BE4EFF43E8891AC25F57DF8AECEFF1840C865A93FD1F6C3E5 -F0E48AFF008F52A23B5F3ED5612823AE23E084A84201F9BAAFA5C1D6670CA499BCD92FA3 -C51C0F5C2262941FFAAD5B4317068E78A1215B8F32E60E77196008D95FBE342426E61DB6 -7DF41434115C10B5E04DABD307EF04426DA652094C53EA304AE96BDD6DAC136E1B0913B4 -6874CECD3F1EC272BC4B5A3264A7C3D8881F2415165383BDAF1DCA39A1C53C3BD45E1665 -16EC26F583D1705592AA862D75CD754B66F0CC89EA5A06351BAB9FEF4A8B592D636C23A0 -7D82581D2E972AF42ECF8CFEFF5168695E998D8A756FBEA0FB03FF2FDBF1A3979767E0E2 -A15F041CF0870AC7105E8A2AF5FBB0E00F212C0430C407278400139624895C0B67AE7649 -207A1EE4A781EE6AF39E8C4A77FD75DB7992CB90D9AC239BED5A56105ADF5E224525B4EB -DE5D43734ED2BBBA28C8CDE0334C9393DF8CCA236FD8E15D5D970900F4DB12C02FA5E2A6 -837C40C097B24942820B116C7693B43F0870BEF05AEB81D73E2CC42E448712D37C22212C -280E111F738B765A74DF533182178E6CE806AAC22F5E270E1CFD406902C45BB6A58DE01A -9D75F874C698BD4A9EE40414A446B6E49C8D198583D4A0B51F8FFE1FB809B8E7EBA85242 -477A9C0AEE9DAA8F7E78A5B73DF068D38CE0A7B36D857862DC2CA4C0FAC20A0B9F7F6BCD -EEE7EC90079B59F46B7A354D1A8D6D4A71DF790E23C4E106EAEC1497DA2B5E36F3EB9E12 -4D049B5E3D92C68D388E1D9D8749E93D2AE063770EE9B9D9491E62223949D60B11AB8C97 -A87C3CD45D13D1B033272698389E80746211AC1E09ED156F7E3AAE2016B178CD4ACAB399 -0C849249133D5C2F855D55A31697C551581953F622621231DBF209EB003D04CFD33BC791 -7AA01C79C2AFCC2308263D0B886A9524FEF38FB01CC278A73A86B06A0467F6A8E57F488E -F20C22BCDDF368A4322F629D81680312B763585EADED366B810A95977066B421D630CAA9 -0A18AE200329931AF4A1F4DFA5830DB32425AB3B36A023ACD186B4F51AA3D021B44ECE3A -042C12DC54CEE0B038DA451724D8DA69CA2ECBC3C9E986263ACB791A659174BC940473FD -03CBD870A2079E225D78D7AA550A3F42FBC2F027F184F54903A1DEED269E6F2CEE48A7E0 -E9DE7018417C65A6DB9CC89A93B1297981530C330F7988161203354F17ED6184EC023C95 -584E45E8E88836C5263398540DCB7EEDDA5299BA8CDFC93E39287F425DB852EAC42A88CF -3145792AC6712403EB9BF1ADA24CC204F9757B4EFFACA94F74E5CB546569F0C21EA5DC63 -6A7C20A40C6FFF3B173D7C64DE1D6E47AAD74AEE3B27FF5E577CF3BABDAAF91BF166FE00 -65B36A224C4E83252D7820667A3D7A1EE57326683285F217FC893C374DE7F859DED7C50F -AD5A30931D50E568A12C43C746018C1C35306EAD324CB66B0F747BD24023CEBC636F21AA -B1A396FF13A2ED3321EA129F72CE2E2B9FA6E00CAB30CD5E8DBA1703962F33E9FB3CFB01 -E91BADEFD13500034B926A667F48ADC59A4CF6D07FD4E7EA96417B25B08FC1F284EF2B3A -D0A720A95E1AEB3834C453ABDB93F78CA55544597E02CFC6D818423FA15D5D7AA96D9EE7 -6FB33A9A708DF038B19E7ECF0E068B627C26E5A3C53DFDC0A9678C8AFC496078056F8902 -05A38FBA09155052F80832357B84CA86F3B9C399410FFED89BCAF4ACD808B6C7BE343571 -DD2E812C5CA964B8933141A33895804CA34F77074785B58913B2CCC2445B0D54F4D326EB -E5D8307C92E0AEBA068341A5A14D3AB5AA38D35C0C020F3AB33608BB9C7C28F7BD1022B1 -5ACAF78740EC7DB4AFA3F8917D5722CED290D5764E7FDEB6B0E9EE78A8E51F4F88FDB506 -87EAB486D0218B9DC1D29FACFB7BE25F4D85C1E8AF20B039E23F1E92C79FB13C7EEFAE44 -6567C47AAAC59487CA15B65D3D14CA2D8AC17A8F3ACD19C7B58C2BBCB22DC2F3DE7FF42C -A6EF389584E4F59CC35D84EF94F3ED5A604DF5CA83035B54817526302662BA6DB7202638 -B4BC47B6E907B0BC3FCF31D06943FF8E04C1344AE04F96583A8FE674A79615A76807E1F0 -FA1EDC93A9538ACBA48C054B4087CEED23E7B4F1750A7629C333102F38001A7A29DFA697 -A3DFAF60BB89908CD78AF393A469E54A41D31CBD35D2BD98E5C04DB8ABD7C6AF6A47F51E -2F9F4DB3CAD40A85C32ACEAD6C196981E16F90541929DFC9BDF8293ADDA1840EC116F3E1 -191AA907CC72F75FF0923BE2862199035CA1CD4C423171118BB8D250B5897EC9C2AB8C88 -D7FBB99AA99D6D194B33A9152E8C1750498EAAD12C4EB45C1604FB747BA3FCE8DA3EA4B9 -6861CAB69A1FD8D04011CDE1807BB405DFC1482CB2ED7D3AAA1F8714CC8163FD8F0B36BD -31AFCAEA934265898AA67B80877BDA58F3E701F78CF052AF02F08D3AA1FCE61EA12D53E7 -022B3824A1B700FDA87D31F3413929CC5D1D287B2B5C91F82D9F6DCBCB599D19B4220E27 -C3AAC4F0999C1723924CD7E9C06AFF56F27054FCD334BD9567217D5BB294CEDBCB77920E -A6FBA60BF77B255E5FBD2BAE7AA22D0AD45C8322A899C45D0B12B3EFEB4444B0CB284019 -33DADF209B797C0F2E77AEB82AE01F09E7897905A43ACB91D64BC3DFFA88A52F8FE2C901 -78A045A48573C28B02782D54B9BF615CB5FDD714342378CDE02AA661A18893B49723A650 -308A721D0D626460AF055C356B3503F6B4CAEA685B1495CF6AE66D14CA45996137D7E173 -7B1ADCC54A6F30E1E270F4507D9B4B10F647320ED3595D6C1B077C8DA047FE03665AE73E -68A82F78EF7C1DE60427BABED7396E6C412E44FC8D98AEA402C00A784D3A3FBC7793AA8C -C87A07101BBF6FA2C3178D93DBCF3E00C95F5C0E2ABEA7158330D7EADDECD7B5EE420BD1 -C4C40016AA88FAD7B44B6DCFD9729B136DD16F7B54470F0FBD3A671A13C5DA0A52258636 -1F2FF96985D9B5B582A1B0E51FF2A2BCB8EBB5018DE067019B6C3DE3A052440D893BE3DD -414D2FA37489D3E34FC6E97FF94D2A2CE6B460498B996D2E21E2EA92E937E68AA000BC8B -9349E5DFDA563D70EE336C181E9B12FCC65C40A2507685E03D2D4EFE013BA6D6B36D5D5F -03E7B0920B195FA23FA98993DBFC8F7DC4B7C6BC72C8280C78C150B99604C93323273001 -6078600837D5B179B1AF3FF5692963612F93A8BED3B2630E9EE9738B5F016B0D42D908F8 -9D67A5555DADA0529F1F0445FDDFB01953E264DD3AD489AC710CBDCADB39A99CFD9A0200 -2CE7F462BA691742EB31B0DBDF6F7F26FCEC9BE173A4D78CB40332EAD8A1793F70598EF7 -CDBEBC02F493DB8C654994F6150B43FB49CBB5E886A515828E25F83C8FE14E782C43E332 -B351A8E68094839AE4BE33E8D026CDCF79995EB0160FC1ED53C1835909A1F51407181A1D -82B529685DD92FE74A21862FEF7B2ED4962A360BA825B08E961380522CC75BAD11FB7F6B -15378AFC8BBE9521854926147E47A08D728CB679330AE15AB75213AE7793450108837607 -F592719EDC0420A2D9CCB8A9BD7D58D9C7E4775B753F2E928588DB470F6A23378968AE20 -380CF35131CA742AE80AB160434F7AA2A88B2FE42F54FBEDE83A99D5DDF22108250113B4 -34B8C3F8E46D57658C37E229B4791CDF9B2E2C5CB26A83F4B71739741EDF475222665072 -EEA39059AE36739F8CE47842BD9CCC13BABCF2888CB5AB13A12E83E3E1D0BB27C879D435 -684482F1ACBCA88855A0BA49E685B8EC66ADE40A153F64DD355CEFE3FA55F78E499A0303 -45CD4B0471B73FDDB5E5F3B7233F6204EEDE30D7DF03617F267636A4276F6EE6D065A405 -03081E2FD97C1738247526B2F1E374665F400980561ACA6BA65076EB0A23F4955268851A -3781AC4CE6687986945A3E0AFAC73DEDB76E2FA23BB33E094DF1FF05602E52A49E1B510B -5562EF0D58E45430AF43EEE073DDF0EC00614C0E2DF121C173E1ECE36B4D87D0FD9D13B2 -75A7C0C8F9B62B5032B77C8909097B3D4B7482A3623DD75BEF4EF27EDCD3E91F628DC448 -4E15D7D633B3415402E48B1B577EFAB6413CB65CBCA453F5EB78E778055798816D895A42 -22EBC77D51C992C56ECDB984D5DD94BFFD01E3EE1082F6D189E3A4D04D6FD2C206235A44 -2578CCBA9CF00D7D2CFC3BDB2D6CAC8AE35DD17F39E0AE8D0A84AA451789BF3C672F7F50 -CDE8F58C4AD3251B124722AC292A11FE426B0B51B2EE4EC7C65103F1128B54820C458E09 -7376F3295D30ACDD561EAD278082B7FDBF592F5261B0BA27A71B8474EC2815A8E62957FC -FEDA68BA3300AEBC9FCC1C5ED4ABFB2B91C08AAB32BBA60A669B9BAF89524FA6B3B63AA4 -6191B699D7DC81F8E21A990BBB3F906D4F93C3CADD734FE6BC866DE02D2EE1D119A71565 -752224235EB79D3668084A41D7CCB27C48595EA82BDED902BBD71818547D4E755DD372A5 -276B2EC7C66F730F79C111AB99493BF93BE7F252EDDF129D8F7B7DE6AB41E9F8861AB866 -51F4D928F6449852F6FDF2B84E2D8341D6E7CF35FFA7CFD875A02F83733D2F8EA7FD2448 -7A575976B07F5BC799DB0925F0D6967E0C18DD80906639AEB86B4098A732C969703C8DB6 -E9F1E849E75FC37714D4A745A08EA4B374CFEEEAB664116D809AC06A8B3FB1DF8F71BC8E -BB5AA0467A728A6446768BC45F128D5EE2596FA35BD65F90DBA5A78B5D02E2FA2EA43FCE -1D2987C8081EC335A63ADA5DE5F6A87020AECCF4ABE0D17D4AFFE79462708D14E3A5820B -BA2663912A5CEFBF01788B0BD19D08CA965E30C9B7FDD2B8156F23AF2653BA4D42E6AEEA -A4A812E561FC68A7316634CBDA855E683AFE67ADB8632345B8718289DA3D1F0B00234049 -08EBC15F22DEB99C37280695EAED4D3EDBC084D9FCE7214B85788B6DD81E5AC6B93B47A0 -4BD833CC79B0AA2D4FCC9707874F3C7149F5F751D1A52F59B014E604984C6B2CCF869B38 -A045E50B957DAA6EEE0A74305705DFF1D7EC14BA595E5EEFBE93903DD31B977525AFBCC5 -7C31113400041DADCB603614F882FD78B88D6931DC3FEDA881B6FE8081110CB885B8EEF4 -58DFD7D303B413024A16D40FBF7792785C2B5DBA567798CE9C99195EF294799EBA4CE802 -3D6B0B1C344C90002AB158D3617EACA713F48AB12C062E8BDD7D7C5EBCA6617547A915DA -48C5497DD8439BC2C304AA1ECB709867EAD1B4E37305A3FFB1A8E9D52462C769CE6928CD -CE5521F6C134C61F08832CD620385D38CDAD88BEB32B997D9C8EEFEA6F17135A47116412 -3EA3E64254752EAA4745350ADA708255901462AC021792ED74770B031C21C58A7F50A32F -ED93D45E5D9DCFC27891989CA4BB010E2DF384657530B1256ECFB2613F7FD59ED67E5288 -048E5994C2EB3DBE5D9E77536B967D7DFCC87376A5075C7CA33B7C36251001F0501137FB -62E0D60F991CE5E3992C3EA4DF89FE2B75048B35B95C5E6EDDC4130FEFF7586C58629AD0 -752666C8A3A1885096FB0ADA14524AAC57E72F66304EDF923F2547D6AFFC0823CB5A8EAC -CC46B4786B46D611FD42D633818CE9A23DED24AA2764AC6AE7884AFD1DE22A63AD5B105B -4042B44E44E8A5ECE975FFB6D14E1BF1924F4EFA0D0DAD4E2CA0F5B1473F6D9A7BFD42CA -966B065D46D3F97056CB9BBA064E62E6A1CE5836BE83371BA46B58BCADA103A2F0E72F68 -E361D46664551B3AD71FDCCC221DE21C3E78C33D597AF3E533EFCD4573E0C2EDE28FEB42 -6D9B7A423ED593E57D7D5FD7C5D97D0B8AA3C1B1F902E89201E28EA19D0D140F8DBB4BD1 -A62309913048A6A82494D26CBBF9DD4456109471043BEC23E4E3D52BC1A33BD7DA7CD67E -D13E738B1FCEAFF839598F54FACEA0EB1F7D3C5419C2BC588B16A1CCF8814C0AEAFE671D -DDB96353D32D1F86191490516C461A4666235CCDC5179B4324B7936E26916DA037699EE1 -622E25173E9E1286306E6034D667CF1510AD4789188F7D0772D2DB127665273683698804 -9B9EB1D8A2689D5C46B5B455492FD96281133AA54945D039BA684A89ADEDA43A9496F996 -EB442E2C020D4EABAC6750E320D8DDC7256BEADCEF54E609B20DF4A6E39CEED8B3D4CA98 -0FF47314CC3A3A3E978C4F8911D5AF92C7A0110902A8F5362DB47F19DBCFFB4789C90A34 -8CFA880D4CB23D284C57072C7880B016C2F4338288D32F641EFF0E1F2D04FBEC6D02C61E -B27A4146B19A5BCE213327C003B1DAC40740AA1E9FB73911F3777FD976F90FC42D91D5DB -7ABB08EB6A5E4D367DAB5B31347A726FE7F04854DBA180019823FDFB4A44479DC0F84952 -8BD0BFC0025117A8D6B36FA9F88A76DC36E4DF00A2E3D2BDC2FFBCFCA12E3F4CED77C1EA -B2AE53A27BE8D1E77A618343F6673CAD03754FC14543BBA5FA50E1D7A8DB2646042879E5 -0D1D259898D91048C8B8B0D421C3FAF3E875D7FA4D7EFA088B657442742D89D0923577C7 -7ACCC9D8319DE2640A2422AB011CC520245A59A1D86CCD5F9D5616A35BA2977AC7686BAA -AFE1A277F407594D6A60D5231EA34761A78C1AAED1A1A6AB100535435C615B8D89C4E078 -829B475470ADDC46331469053DA6B4DAB9F0B0344D97B744BBE1962200DA293864FD2936 -2A6F74DE71CA9A5A1A6E697CD643D33B89A7314A605E54CBE1CF0EC3AE3F11982EC3B0EB -5D9505D4BFC7402D6539038C6D5E0B27620F7FAC514CE55B230F9A7AD528ECBCFDCDCBA4 -AFBB51CBB1F892545F88C9C5AEE7D3B522ED35F53696EFA39D72B734086CF673DB0EC924 -556F1CBE7D12A8232E51F563E848D7C9170A2AB0AA5702DCF43AC2DA03403374BD85E3F0 -CBC2EC8D2A823A8ABFAD7FE39742DC1DA40DD0AA6E5E1CC84B3B80C909C2E6E01659194E -592493C1B1D39EBDA54FE9E501BC06D9F2D5B507B8A6A5A9A56DE260459DF378DB3C5348 -84C391C7BFBB36216286796C176220211850D52596BEDFF1455EB36F869D93F275BC2E02 -07CE5F8E5F07ABE7D6B59E6533462CED7C4288A61A5AA7E206986061233FFF0CCF6EF957 -D9FA5B99FB733BDBB3BA0C66508E483BAA1FD689D51B5175533DE2614ECE76F9BB8C5DE0 -DED71BB2F386E03D51CCAEAF84F0EFB290FCDF2C0219B1EC25CCCC33571E29739D8A0025 -FEDA1849B5EEE32D4DB59456B1CFCA8E8F7108003DBA2A20120DA0D7E3CE40FEA9193615 -2F1EE75A674D8C6624CB60E8A42B218AC9E41EBBB6771DB40D83262877AF2A369A20CF57 -BA61484D323FCFCAC034BBBCD8F92644830578DFA45421988048B1660C823CE8F291E099 -311CF62AE24CA332086F6C9CEE197DA96FD2EB0A8E49D2E7045AE7619916124FF5D85907 -DF15FB7951BE56AC6C10EC2A98AC525012A7A75F39B5A6DA63168608C5D1F8A4188F12B0 -F37049B2E1E70A225DCCE1432B0DC309215BC07A2D68A261664C3394CD4A800E30E77823 -E1D8D98B0002208B09873C0A3E6724B3A1A21C074232C400EFD5D526C213550F826EE84C -3FEAEADF6CCC9E7FEB9A91DE653D1F4CBAECF29E197FE8B9CE2201E39DBABB02299477F4 -791D5CBB3ABBB53077409E1C4D23E7E43B071E523414A00EB50E0A1BA6CA87896C9191EC -C6154FA8483509FCB65DB129EACF38D00481C70D5D4A1FA9A3B2E84B321222E1CEBAF617 -A8E7EDB4DF284FFC1429CDD667C52D8F2D79E97BBDEBFA0EBCD52A54C963797F9940942D -3D4D1E9962C34589D754761089F50A3BFE1F9F51C1F1F67560BBEDFD67680C61337F53D2 -7B2D18B4DE7DA691587FC93909CCC2BA2E853D4590936D3B989502BBBBD9929E370B59F5 -073D7EDA6875A191C5BBB8C0413CFF0444F16685442A6EB0F33EFFB569D3AB77151271B0 -B2C5E7078442F1568B5BEE33BDD450854289BFA1CCD81866AFA983921423678D8C9FB9A6 -D9E77A177CD5434BB12C4615DBC5A21317F9B6775EDE6E44A29AF506F119820B5197BD05 -207E0607F1083F0FA4F1E34E9EEC2AD41DF659EF2473724C7FE34AD74D33B15AC0877234 -224B88851D27BEC30033A417C61798F8C0C35123860ED2569A62BC7B2509CB0DF03E3A49 -9CA57311614D12AED1DC3FB1470726AD11CE5D420F4A94586435E7C18661CFF62BE322D9 -A395002F4DB83E37145BC240CB6E5FDCA11686656EECFB072B3422184AF75C8FAC2B6E7F -33C3BBCBBC8B894A05BE1B75BD64A3CCB485F7359C785C449AC4CA3EBF59496AAA7D0DAD -FF7BF3F8300AC6644BB4C8E7613C5A4C309EE67AF77701CC1DF39B0C01A296309FA6DF84 -3875E1A057BC7E5ECB644240AEC11AA4157F67136831E5449EDB5017C03509B78B35B016 -DB6C9DA02AFAA51337B3E6FC0091904D04B328D1D57F33CA77E5BDBD38AFA74A7444158B -20009EB4A2029AC86EF3076BFA6A97469DF182172D39D9BB16D5F15B526B61FBCA683306 -7097DF4ACCB7CFCABB675161A3EEC657E8A8DA7AB590CBB4EEE9999BD8BD3C2885E3C0DD -52E7850E680F9CC5048FE8B0BBB656CEDC82C07CB9FEF713BE8C5021CA593E445C034796 -B34DC2ACC85FD770DDBB7179F518BAC017B53293A52859A4220DFADC93FBD31F191E2467 -DEB59636682EA309C19F1C5FC8643D9D7BF9A9F928994D15BF645E83B37DDB833F0422FF -6422A9545FE2F0B2D959C8839BDA8F2D76E369AB05F324089853CE660EEFC774D714954F -EBDCD762E9490AB0B5CA9EF9B4DA51665C5CFE10AF8822C0831F80470467CF1F49B88E69 -4C75793F8BD37EEAB798D310F5115C5F5DF6D650D75981132E94140843F8440739AD7543 -82B6A4109CD818116DA0FAD8E0FB22903897A1D4C49284411F0BF018E880AEA118322543 -098F74BCA2C1EA19B2FED0C0D1D74329F4F23027D75C304C2BDC5355D5B5424F000090CE -EF554020B76DFF1EBF9EB929AC89CD76CD5D0E784207743F1C8C0B2275EF960766295992 -5C97D6D4EDFE071B4AFA15C5D9EB72A67C1FB72FC634337D827603AA7C37E62EB623F5C4 -5E23AB693ED30B6736149463A8A01AB28A087F8C80ABEDF20358899FC34F1B587B017B30 -99E8AA24D9054F66E79DDEC2AC82FBB0115923D68239EF1CCA2CE89E935EEE0C451301EE -075EE992B3183D0E149A65A12AC23DF90D4B05E79F8A0120123D972B919EC7DCA6F00711 -FAC4F842BE2B8384137E5858EC111C33348E85EBBC6C176169969F30841CE85A381EE1A5 -BAF76C017C559D955FCF8FF05A5CDB40E91AC7BD74CDCB519DCC657F3F3F54DCD402CF96 -FBB2C1EFAA5757CDEF80BC6575CE488E2DC246AE31A3E9634DF5337FAAE9259DEBB8C64B -5F190C04BED5616CADBA4C014A6290BA5D70D2619724A960D60989F52B79C09433DF6715 -54167E161E4A1455A02846FBD422E4270D03841B3B5888FB8399C1F9645B870ABD3F9199 -B8D81BEF3316A3004D07B378962BCB2A0D6531A948B59B7C46DECD179FD73C95D5EF6390 -A105F0B15BB743B0B7D0A23EB7F9065637B717840FB9A2F7FB7C5DB79DD08DD7E024BBDA -9453FCF5AE11747C590480EE6003F5330860DCB1219FA7458846C8F25B816BB245D50901 -F892E2489F34259C300EDD02B616FE650D5514AD5734B77C7BED0DC3E495C418B6A9EC0B -EC39E783C913F71D96E9B0A476CF3F2D0253F90BE85D186A823453B109C79AB859726BDF -85236314120C93F4D44B55EB5A0C11A2D4602149DC836A2F41AA9F096F4082E3B199BD2C -AA2653AE68087AA655B4113CBF54998BF44C8837E6DC8FDD599160C1B191C2B18AF7EDBC -2BCC5CEAD0E765C856E0A39E8E904A821DA88AB030ECBAF39CEB016FD34BCF6049F558B3 -EEE3C1EA53B87E7BC2CD8455209A708590ECBB9566A78262C6268FB2180C3C4825267A3F -BCAC25E204D05417C85E4C46BE30E4FC876D461967483D9ECC839024333A235C05E61545 -E52220B3E3CE601C4480A959F032244A1CF4204A36CA332EC0258A916D0E68B043F30949 -0DDBB75B000DDB359B315FC9BBDE10A42A3A7D6D506B21D1B48254F84FCA27774A98E249 -FCFCE9E96B7EB51D85A671987AD1F3B35C755667B64DA70EFAF67CE8B14A866AE04CA6E7 -EED0905E5FD17B98D75F91279E033C5FAE681AE10A17C818E79204D6AF3925D70AC627B3 -6B81D9D8D75232F308BE848BB67A87A561821201C796FDF6F39B031F5049490AE19E8DBE -A908EA44E378232A09032D368F1C22E1E7984FA82E14FE340911E786105AC959A5A52534 -C585F1A85C5DE7F78CDC5B43546C8CA3629906BC586B11DDDF157CF1031B182BA3D335A7 -A779F56FC0C037C2948DFD410B53FCDA94E73B53BB76C71B132405ECD8F0B4AB5262BA72 -230B7420F4E03F7BDA0162F59938DBE1220B5CEB12FF83C7C9606A67078C95075D827631 -1ACC893D484D548A52A547C96A30AE7A3B30FB715770CA5861556BEE0E9D8E837D385C7A -40D24B46DBB4A23A24ED5844F5ED69D58CFE897C8FB9555D41578C97234763E41E1E3062 -185FADD8A80EB9BF519D1A21C1EF6ED7D16F42F5F083046A63711E79E2B4646EFC2E656E -55355D7D3E6411B465B535043F9A6A57601D15F4B24D1AF71EB93A0C7C07C85FFC32871C -1DAF85DA374524B0554E196A18A149870C508BDC9FE22CEF54BEEDBC1820BF4B7DEFECA9 -062F3ADC6E93E560F7D37EF6AE086BFA66D02D82C8454FC5CEB362007AB53947B2A14059 -E449E45A379008271758E200F71807B3664771BFB9C46668BBE1A35AD7B208C9AE0CD84F -8ACFCCDEF782E5E6D3B21F236F004B41E7E6FDA292970F74127259DD470368EE2C17E7F3 -215DBF172A740F42F74BC74C8A5469974446122D11741EFE5CA3AC65D03154E425C85F6C -525B3CC38005CC7999643144C6BF34EE658BF922456FB08DA18CAF92332BA728EC95FAF5 -8BFF30FF9F1FF2BF14009A5E6B9536F6C5DF9CDA8C2F34842C8EC1FD510F878F1D3605F3 -47B6C95921C8700AFF9E75B7E2B404D13BF906CACB3A1B0529A3168C31C96ACC12723A00 -455229C1BAFE2DC474FC46E969F6A07CBC2D4C3D9C8C81D9BFD84A95756451670D128EBA -ED2CEF998B03950827D203804F46DD1F1CEBA6110E29A93DDD2C38E8D02769A9523842C8 -533F6EE2CA11FD585EA4FB551DED51FAC17FD30E0BAAC02D6206159911CA2BCB19CADDAA -4FA6F2911442CBE8A69FA4CF3CC4792CADFF5FB70D1A8441046F0103A36CDC7B8F82C115 -DDA815EF71DC8295D8BEE1D412DB942B2619D67A5C1F8B06DCC13BEDEC191D9E818E722B -ADE04C6C358A27D1EC9B5C0C198B9B235EB6DAE815C0561A8C29526AD3212B32A3D4FA35 -831008C5A9AD3B9A8D68903021B9513619868E2F8535DB856AFACC031B890ADE468A9903 -B716040C73E77CC57813869E1AD1FC706BC34DF7477FDFE9A0C21AD33C78AE789D829935 -51CF312B811250B8F6244A098EAABCB3A6EE2DCF7209F04AC039A4EF35867AF00F01657E -B517482EA86295127A388A8BF4B605ED4E13F03B2A3839990ACEF98156084F5BB2206344 -5941C560132D0349D52CB72C85B983DF6391B885C5C6048D5F74FBBF496C70FE021AA578 -280053474B6C1F9AEC55F6DA9DCCF3CAC7A7DEC6F743A81FA0DCF7621B484589330E3201 -8A1B7257F719BBD0161EC4ACAB731F2026B77298EFA4104EDBA6B299858184FD1D4C907D -B3A6D0192F8C7DF66D3B0C947AF0F91F7CB09320BC0D0B11CC026162450096809A8D1E8F -01A09E2D3C64E6C91E2B31AEC3F1607381714BAF0D00240FE58264BCFFDA303E87296DFF -1BF630DCF9AF3BDB5ECA30991897AED39EC4CF40070109746FBE9D6E5A24F70D8B2D050E -B63D55AC6D18153F3D5D04E10B704A2B47E7555627A84F394B3FFFB6AB7363A9DBBD11D9 -323050BE1C294A586CCBC043FF952C34582F4D4F8A9F6E71A246B47B7B87AFA9BDA0ACA3 -CC3ED5129B810A98883B1A449E5834344BCF7C09117052EC619C8512DDFC81A68CB6D179 -CB3D6F3BE24A1F29669B7C666A9A0C6148E54BAE665515F5490639C66BA808E40B615EBF -5B59D3CDEEA96951927E406F696745250F0A5A8B8850C3A3AA7F59CC3F18F3FC141DDECE -33CB43777CB6359B9015B27CCA83BB4EDA646BEBBEB1FE0BCD0E1114C0F983918DFF74B5 -57B7A614EC0FDB3D1FA926CC76D3B6F0527BADACC1C302DC6D4019E89EF7DD3195494638 -794543E29846DCA17B1724C3B2C09172B9402437E747F22F1C959AFD01C092E87ECC0CEF -C7C422538164E8E551775CB7660B90009EF7C910845385B97FFC2DD5E8DC1DD3C0B2128E -9553A042C74308F74DC7F04CA995F9B9870AD1E8F89382E9E9DE8600936F1E2180D59B2C -B8A3536BD7F2C47142C756D26411B6E5E34B03C49CFE87398C7334C786B729DA1F36028D -DD5A16009B6BCCA2DD6737C7C4C3CE7004B488B86507D095B567868A6ED59964EA34095A -DFE44C9FEB502977A1369EDBFBEDE949CF421C576859E181AE2CEABCE6C35A88F5050345 -FBAEE8E1FCD98F6DE17E66DAF5D5929046C074E8D85C4AFDC71367857E8A7B1AC3E526F1 -8B7DF5E90F2DCA4007344D0EE044E663D50BF80300A3F1F1DB03B14DF2CDA7A367F91A5D -AC834BE8E057EDCE5274252AB3FFC1D1DE90857EED51040A2FD881583184CDD2CDF4D629 -B907353B9F878AF4E46FD64C85360927664DAEB7371EEB887F5AEC4F76C6700824FC8E05 -53A785DE724528E12C1FA1A8D32059EAA3A99E6D481665DA762E6325A4310222D7DF3918 -E96FFB85B3C04D9E7CF4F3328FBC31F736E93559EEC6D60A878990E8108012A2785233E8 -2E57C735254C7B38E16C6C7E7179246054583C7299050C31496993555A1243826532B139 -71188CC8580B73C43CBFD1E8F23369F56EAE15FB0FA461BB771026722695A8F4C6BFFA3D -76BD2E85D3BBCF1F7F53D23639E39754A4D71B48F1A8C8A18C2004A05EBA0656E3E9884F -9FCC00D55514EE382FEDB40BA636BA174FE950F2B0BEBB9C926E77ED32B08ECB1F4D4499 -02387444393D3A97BD81109E56701374F13CC9774778ED60E3EAE3C78BB6E0B7ACC43B0E -5F29F3DF4610E97F86D7DE9CE585E2BC144E1193C123BDDBCFF83336625ADD90F1DEBBF9 -74CE0797BD5369D2E3C448BEF8AC728723EBF987B4F1CCCA1B3FF3C0CF8F0287E3F5430D -BC67542E10C560A28AB12B3513C1120D8975A6EE71DE0175AD8FB16C3DCE4B265DED2815 -F03C7FDD72E34A27215870758DB124A5D630723BAE250535FF92FFADB0ADA3C4D31D007F -562836EB114CB81FFE1E9F54756A3D1A8E3CE7DA8EAC4036555B6583937F6307017392F0 -FA28BE83A6C4AC9183B899DE736F86D05A91CCC5545B7AA2694841AA98ECC5712A76011C -9637D079BCD5295AE2999EC5C032F7ABEC0804E2A2510303EE071A9777E89E32804C51F6 -1458AF5736CFE2DCC50564CF3EFB629FDA6C39CCDBC5417AEAEDD0509A025B43A682B218 -8AD0D62B96ADD583B027B85C532A1F1C2CBDCCA5FD54A3ABA6EBEE74F2568BD9AC0E19BE -26C1C2436C4FF76B4F50F05A37A1A73A02D155C2DB4A849082AFDB1284F9566407CBF976 -F2D7C124BB538A0B26898CC818BFD9D34D41DA06677516C8D78B6C801B864DE2B7830E1F -868F33DA7E549639ACF55183CAEDFDEA0664AD59BBAF56FAE34AD40EAA21F539F916E41D -690419E36D2C268B7F72B86BE962AC175BED26F6411B70A92CCB9D7A27FF88929F0D13DA -90CC5948B6411F7B04586E283389D530C85CACF958D145C88A34E03781617B40171D3187 -430BB6102B6F1B2C9DE91D2D7BC2A8D5770736B9402415C966FF73EB321FE99505100C1E -47433619A68E08EBC593B85B638EFF1C484BAC03B045BE97A0E8AB48C929F3E801A3D057 -6415902C739C6F92B15E8AF8DA0DEC3450DF6AF7522ED6F316439B8C6FEF58F96BC9C096 -C6E5C9FA97C1524F6F4B84D614EA7B2217B7DFCA1AE90496066A04DDBBBEB49965526701 -3A7513B3453AD0543D475A82C2CDABEFBF7EE5FE95DF01DD6EB4E2F5B36E5AD98A5CB658 -87327AB12AB875E4D9D7CFD34C4F02325EC3E37553B4EE12DD5CE535B2F6C7651DC26A62 -CAED8B3A97A143029F3EF41678CAC2E5F2CC6EE9BD567FF58F32435045214B62BFB112F7 -14FD95F9BBB4F3B3FB620429E12CD2C52C55E483CCEEA72D524C4CF1D91E80F27ACAF36B -5BC7D386BFCF9D70D3CC730D5D2C9C75BAAEA9EE1FF093321AF65CCC73B6BA6F977249F6 -746D69E200645A4E40EAE0986FF0CF3F1B5572BF9536DCEA02B6925801D1C466129D45A2 -E927BDBF6D6F84C3548C78E70DAE806CAD180FC468F979685F845BB2311524539B1C7ACC -C9EF641183A100AB51C155E89961090E2349C601C6769CAC3B1C2537BE0CFD560B9B2369 -4E1B8E9083DF9261B17EF6475C0A42466B4DBC8C601CD82D6236729CB8C80FCB57E7AFA5 -D9D9B35F66E5B29251086BB760BE94831670D955DC8288817A9DBCF7A6ED48038596CD76 -BB2FA5541EF78AF5CE421CCFB286624BF3C98829323A7EE8CDDA3C5DE22044672C8D233A -C08521CA69962135FDDC8EA4139BCB13B64EC0DEA02C437BF522F41A8768ECC542D5EA8A -9F85417B598931410BC08259AF88E410B695A9A6EBD730853F2FDFE3FB00875F21E1EF5F -60D8D8F62E643A6F4D124FD84FD72FD21DCE57144CBEE5EED9C05796B3F59338903913F0 -CA0B073B074A44B1E1951353EE514CB41BF3D50DCFF683CD15836226EE9E73F55D4078F6 -5E3A288CF7F124ED183DDF2C0EDCA6C375160756DC3DC33757CBE85822FB2ADC859CA8CF -7CEAB1DF3A48E751A6604C3E4E53A9C9CB967813C3181D7E4C1DC954A26EA4B28E23E39D -C2564845970739B40AC5B267B4CC07C90E289EC9288AD379A7B684B97BFDB45F036BA95B -EEBB25A5BBFD3F0EFEE2ECDEEFADBEFE80BF2A8C01BA345B29DFA9B25B2D2234F358BB99 -2054FBDB728192CB5EAB19319257140E95B8F31E14BE579364136543A847989F4E410786 -A0A068E38A439250C3D61EBECB1AC741D529A5A74A546FF7BC9F2CEEB11CB98F4FA97BDA -C74A7EC4DE3948859D3091CE7D8992D2C094590B0AF2038429E30A6BF3C7533A900A4240 -E082BC40535E8A07E55E6FACA93FDCF4BE35823B30A2810DC991AEFE4320F927105101D8 -48A790904C823CBE8286DBC1D8E7CC50B1E5931640FBD0213B0FEB7AF7AC38CCC6B738CA -74B1FE58BF8B559A7D3AF0D2ABEF706671A977E737B5E49C4BBBE7B412FC8512C17661A8 -9827E24623F4428598A65FC5A79E77736EE2506E5A61DC3ED221F412AEF9FB3AFF6A79F2 -EF15CE24C810321A72FC6705FCFE24032801E3F61EC145D6A82C43DB8E5F9D20AE3FD7A6 -72477CEA2B6D04C24804AA1597A4A3E0B7E3E15D307D8A13D4311F4EA895199D208B23EF -DB35D975CA9D6D9A036F27FE597C41804A8B5EE10EBD4C16DD09C6228988A780CB315C53 -C2455FFAAB2D71FF87E67EE35A65AB2B8BCC351DCCD62BE2DC199B3574FCEDAD5809517B -8E3BB1B197078CD7F691B4D0474EA1F398AE3AF07263E8BD0842B8012EBE5F51CD5FF11C -35CBA2B275CAFC8D0B3D4FAD5B0931C03A3E0F79F31EED87ED8AE3C4F628FE1A1F2205B1 -55BAC7504D754C58BDC458A4B24F8A4E1401AD5B66E3547DCF9409C1C811CC2DF862062C -74A773A5B7686504B4C7396230D5F2F0A2BE098245EBA1758F20E0E5FE2C94E899AFB774 -4F29CF4D61334CDDD7C38BF479B0CC3DA8E67FB6D3150523C09A24286D86A9F4E1F5C2DC -CB18719F6087FD27EB5BBD9BEDE21B10C26BC38CD98952A128F4CF48F8651B97F6244F23 -E61EE0FBCB5D3BFD9C2E14792920066CA5E70449C4F13057DFD33A11B71C7991D29A7185 -CBDDFEDA7CFB85ABDB7F854F4342EA020DB708556762994759BBAD1E9F83E7F2961B017C -4EB56B73B37F019A8B91DF3EFEAEF75E016457A70AA33D31C9BCA76BA4B805646F8264A4 -6C15C2470F4903A99B0D0BF9B7B7D384F640FAE3DF6AC2ECB533DF89838B258D8128F5C9 -1DB7350B9BDF201455D5AAC7C08F39B643D8CCF26AF3563DBA05B5AE422388644CEC7ED2 -3EADA9060442A728F966D50989C477BD2E4BD4E206C8B014D2707DA596661CD7035B526B -61CBD0FE916D0D7B4B22ABD91B4902C44187E74D71647F7143FAC8E4E9907DBAFE15215B -6F20B82E09B29630E5F1CD15268481847192856F1BB23A00D7E6522090B3672286DCA1E3 -D2DE32FFC4C978F61180D497D9DF1C1CD48B1857CBD40EA172DA1438862A7A28F570B5B1 -73B53E1E81C6EC11A269001C6E6070CDD0156DE95E320F3B496036C1136F15EE35D79F2C -962280292A3678BC4DE5D1C2535F09571A5EFF5379BA71C9996B7003F27BE9C810C68D9E -8D55287AD3D1B570C57CCAFB53109C3EB5674920E6FE3AD170F783B1AF3BAC0BA5CA1598 -6218777F4EE1FD7738963D6DE1D8E1BF1353D5D96DE89C2DE3AD2015265D9077AEA8F26A -9A391A61A27CB0F9E8CE16A12D1C2128E8CB7AE0E861E3CB56769A07E812F1169A283C65 -A22F19881485367B098EF3B97BB9E41775BBE13F4E1560F2AA0FEBE4A31118F55142E590 -B51D5A0867B89F00D9D461D74DACADA920DB5452D80982761B357AFD2F613113854673B1 -3F0F1EAA566427323E2B35F2FED6339DC28170D90EF4F8E4E77506115BFB2FC891AAFAA6 -59611E9FC6F5384DC5096D54E09567BA8379C7D058CE8A3E203EA28DB122519E483A46D5 -F527919C4AA0F635F6F29C4AC9363EA96B0802002BD547E0C248AEFB8DAA0A75DAE5B8B2 -7C7B4716769521B4F3A8B68B0251CA46BA9B7FCD00B3D4A59002B249860669961FE8F4B6 -B594B68D781B24DEE41869F320C0CA419B596F3AE725B4089A388AC4F84A201392C1AE79 -D6AD6F13023E6412BF29DFBF33F00D8966E8C87FB883F97B1430DDD9EE0D0E8ECE00DACC -CDDE43F90351DC64D38EB3013CFCAC2792F613EB56CCF8553C3D9A4B2E9544058BCA3B86 -6F2E33A68CB60097D017252DF367F584DD224D38163B6BB1F5E8154C9590B8E3425FD89F -4575B5150F2C674CE5421E4930766BE7A55D1A01044D2FDA079E1E5CAD18F5F0B7897741 -EE1F4FAD109E503F44526746BB3B5C803047AAB46B1D2CE31F3E026853F52528C3CF6BBB -6BD36DFB524170B10BC85C070459CDD84D25C0EC712B5E8C8D1E6A736993351DA8261CA2 -81F4013542CB6BF8168AE8F04C55BD7EBFAE0EA6C3B45CD9698C7CD576793A1007E2B391 -0310CC96F4D2C5C0565CFF92468AAD585185BF6A19CA9D27D6E1440CD56CA0AD46F4D1DF -0DAD5F2A2C1D2B1ADD80030E38080DC4CCD773B7E7A74EE7F9A964BFAD960B2542E6EFB4 -64FFA0ED1C8828B8C266897C0F7AED40851746A573DBF08F602BCF9E1B339BE24BF35D0F -AE254E6D6170A224FB5225D8859F5C440F96359783D21940DE8553275485D0287DC71919 -A3D81FA8D8167DDA0F42E1CB15A19D673B896729B2A492531E9FB8811837318C24546170 -9F428D0E7B0A6C416FCA1B5B8849B86EB6ACB1B901E2D90E0939F3856934894315E3BDB8 -1DEEFF69B45C8C7871E73E6A20B64362FECA450D8BEA3878AAA0676BC8F9DFF37AFECA0C -C1096900829EF7DE769DCFA7FF9DF38C9C313829A5B9A7FF7707BC554F1B4FE54214371C -6681D624954BBBB90BA5AAA44175DC50C6BF1E8A618471C3D1D58471F2567084E503EFF8 -F4083B75F03B7848069ED9AD01AF51BC5A9C3F34E0EF36FFDD3D3DB350740A56231E8323 -60E8327F218D6E7F2490258F03B904CBC4763871F37E1B8C88D592876E0648184954B702 -CA5FF4851485BE6501DE9AF291D2D4A55CE425E405833285358EFB271ECA61CB37942EC9 -9D53EED6939D6E828C6B2E013E0ECE1A60736726F77775C299D6784E51B1863D304A9069 -F217C825FF94E4982C8B3CC30242232FA59A8274011712957B3F1DDF558CAF79DE460A9F -B15A2D1A3999EBCB3501BE97E719138CBFB37242A4883B3300E20CD21EDBBE0F0D8EDE3A -D6940338657BE43C6C04EA6C48BD51CE3D064B55EFC5DD632E1084BD01ADDF53C114D329 -438792E470EFAEEA5DFD2FC40553C736BF612A8AB8B0FFE6F16DE99FCA0A0B5026B2A50C -C15F0886047EBA1F115984B30050C579C1CA97D31BF4167448D89B3BC66EB4A099E4DE4A -89F186334430655C7A2709930DCF66404322FE8C1AEB3C7952A4DD19CB35C3F50802FD7E -E82D233FAE8EE5377A6211C0D55E5C188CC858D2A38990ED8B2E804FFD60DA6C477D90DE -24A93AE87BBA8558770C427EE99A8623F26EA053C077837CB691CD6BA6A22EE8C584594F -B5A8F2C75D5ADF7EBD927BD53B6F5809A0D6088C094EE056EAB006CB8C4BB2C035D57A55 -57C3BB319E4F0F9BA89129924EB53F7D349C0435A1ACFAABBFF97E9FEF3DB3DF03C21E47 -C5FBC852A8DD098CEA2C335CCDA04F2D2C9E7E38A327C7D78CCA84B96C432EA51C9A3CE2 -37BDEED3EA86D69716E5D60DAA77F31CADE9BB9FA1CFFB8A3A293A5B3FF9FEF03CF96BB7 -F259C3FC6EFC422FC55673819F3F4272A675B2ABCF8A4DB411090346889715D49FB199B9 -6AC6C2981257EA9211FA518AA5E582E35E0034AC42F607F587787EF3A6EA75C1C396FC99 -331D4DE3A906906D334CE8DCACAD9D6880B84BE0068ED1F365B9E7DF9D35E79412BAA94A -BDF0274B01E64B865E7D4532CD08516C8649BCFD7EE65685B27BD947156ECBBB358C110A -5D5767808E8D924F31464FD3BFBEB53FDE41411840C1B689963B2A5781467C9E44E681C3 -5CB292DFF210C75FB4014107B364F2D3B8D3394AFC8B14BA28585E1238DCD8395E05852F -C813E23F7A278E72C7463995EAB78999388E9F093C84F3FE3A164FACC9A0890FBE7CEAFB -0C988CC963B228D9939928E886095F772F12F8B05F4D66ABD8F3332BF5426002B905A049 -886BD5D9EBA35960612E1DFFC74FB5479E37A19A17BCB600E200FBD9437F1FF156028386 -FA46C79694EF0EDF059E63EEB766646DFFBF7385C0893EA15B3A1C982C051C49F4AF465C -A9E6E837C463F580B883A93C1E8BDD68EFE50FE6616A831DF101F184D2ACB6112A10720C -6D173FA6E5C494A271FE20AB7959234BA355301BF8276B34BD198A6F6415C094936BB323 -322CD5957A5BDF76EEC4EBAD015276DEF92868B49CA04FAB36BF6670CA237B4530BF5DE0 -B5774A3E67AAE1EFC2653CF7ACE86FDEB7C8D78B29D1B92170D47EAD57AC140DCB44DC34 -AF59FEBC88B667842227BAE500E6A1DBEBAB7750429B00703863C2D3B3BD0420D3660EBD -6C14592216F03A404E4E46458A9370BE3A92618924313DE6453AED7361D34CFB4369C789 -770D33E94993EDD582C6140423189EAF3CDD7A672D0DD00207B86A4D8FACE9976D83D81E -CECF00CE22D20B441038D424E3958FFFB7FF68D6214BFDA59085FA022DBA5C94071A3F72 -1221CE61C19B19542C3321030BF5CE4D8022B49573793EB824E9CB243D0E9EB6B89A34DC -744450FCDD335E607B45DDF26A57C7DBF83A8C0136ED272D908A0A469C9E61F3CE9EA255 -3D81B9E0B98F323928B0F44D62FF942276A4BF297FE225EDAE82A20680A011229F58DEA6 -9FCE234B22B2AEC35A208E23EC809A5F790F09E11FD738CF62168B1BC2F7DA9564B8D576 -11AAE9CA0094FBAA861B6114A66A4692291D5F4EDF5E230CA8E6526C55B62C8FCD46D435 -6407C7082BCA46845FB9A2865EE0CE8F860278152F0A849BDB8B85E481132797F49DD35B -247BBE4369FCB4A20FF77D6F791568CFD158CC1319F17868CEF028224D2AF3243EC6740C -93FE35E7372CF7E68F06DECC8160B7C04F7086F4A4FA66DB58100D6513000C4CC90BB363 -6BC1B6ADE24EA559EE3245CB74502FE440D7ED58AE19B182E0EB645D7BCC5D8CF1EC26BF -D8BAA713B6215595BF42FC097D5DAB7C030C522A694E027CF558BA7EBD711EA18249BDC3 -DF346537E5FF50755BF03D38A338EDF1974B21FD6E75548FB8E2CACD173F40EB5A9F15B2 -FFC720F0190ACEE2B6E5B040F7B89AB214DD89E1E8AA859BF436EE19C5DE800ABBEA049C -9B6FA77C93A833C02A11CE4E502D174403B582F617D388CD71407FA8C7060B9F3AE414B6 -63F4B524051CAEEFE1C919346B60DD19E9FEC14191B72DC49CF0FA248E568F6AD137EC5F -73BC3F3F79CFF305D88447E05B4BC7B25D20B5916787EB38D2BBA64411FE911BAF1C69F0 -FECE979BA0267D3A297E80FE07FB6F6330C3D4E9777C095B74DB138EA9BE483655FDC269 -A8759203B594DB7C9F6AB5909651C4A27B18E51CE5F695C2ACEE18DA6AE89A3BCFF95D65 -365BF11C14A5FB2BD261CF6ABA383FC467C81FFFD366672895BA37633C3A89739B397604 -0734CF9218B3710863906ED0002D0E756F66DDA0B38F40882E388DDAF61AA9EBCC87B0DB -E04F06F6CD3CA3F24EBC695C1CA0DFDE7DDA8864EDA643FB93E0AD976D5C1F36F65E7A0B -2B1767B0C302AC325B83FB1BB658381C387FBA199CD1C3EC7602CF0E19C96C10890DCEC5 -6166BD141F3061BB7A0654BEDC8DB922337942873A2F6E8E11FC291F8C16AF1A0C8221E9 -62106D02C4F575F4A9F61287E4C20D948E9E4CC7E74B99776EF3A27A0C2ADF127E60174E -4BFEA136B745DCA205A07EFBA484F7E0F76E5FA389DBEDDE4557C73C6B8BD6CFE9D0EF6E -E197EB8A5EB0468F5A80F6E71F9D65382067B3216C740744E671A533F046B48D61845500 -488CF8202A1E91176F97E50970BC00D58CFC9B1BAEC3435DE567CC6B5C601ED7BD437C25 -86E02997F7AFE95F1AD71CCEC4E9C2B9D8D17BDCB66A128122AC0E0CA37CE810AEBB216D -C4AB46AE69CB2AA97CAC99C1C6A5B112A1BC553658BFA93E931B4F28ECC6C0C43E18FCDA -5972FCB8882A86CA41349630542DAF536846B01DD5ADCC84FA4AE1CC58EC5B325C4EFFD4 -E32EC77120141D233E5C02CF7A52399AF39D64F4B9000B881F13070D85E8DB91DBD38A42 -08D5C6D8ED42A48272851DE276E5ACF698E6088343F852E0B139E724BBAE48A44EDD7A63 -B5772F61E178C2CBC38F728DC708FD792737E5A495FAA3335133C45CC887FCC94889DB5E -2DD34C1DC8B2901EF49320B2B8E7708A778A54A540CDF310ECAFE13653DAA2D6C9CAAA00 -7AAAC4D9CBD01F61F0E1D8F35C06019B1D6CCCEC5CD9A1A263CA630C8C14EC325F8E5718 -D4CC035FE652C2A2DCC53B7EB5AB33B43C7D1EDACA8F589C5966BD92DF8B62D56523BD33 -501CBFE506B9061B096C184C5504A61CD6B5E03A8338F5B16ECB0324A8785DF1EE193710 -B76D5301448B0C664F565ED0538257FCFBCB051683FC200D4AD675FC4CABAACBEF11BC38 -E95F474AF3FA7FB187E5876B1F04A26DAD7904E39F3D53A1D5FED70E523867C3E1A5B65D -BE0B1D6CA84EDEF3D0A24D042CA491D6BC39647EF390BA25E2F998ACE7386F8424E3E03D -6EAA815E717F835E3528069BC3A65CE58FDC49B602E0418A3972D9E5F6192AF89397AED8 -32CB25A607DDE31B69FB61164EA5633C019B3E4BC93078739879A2364CF42633C07D1BE2 -57AF2B07A1E5ED68B06BFB81CAC77F6D2EA4750266E8919E8911391688D4EADAB19B3E54 -4460DA693474250CA9A864C17B7BB5059C0D08B32400A51339C4ED7385D9C1DD1839D96C -8C0A6BE1CECD38544854E9698401E33EBF50C1DAAD1652D0EB978D8025D86E07C3DD64FC -92D362A13E173F1A5D015A43AC3CB57732C6A2A204B990635B607938D99422B450E54B7B -4CF6D22BE2F6B9E936611A0132538CD1D8AF62A260501B3696EFBB0EE006F658EFD8AFB4 -19C3C8957B3D9DA5F8758CCBD17734D80E2E207A58E8E97B2B9B78012FAA2C73CBE0061B -EB3F30CC034F7FE5D3251DA71BD8372BCC7F271B5DDF11167AB166C59F63B9923F043611 -52240DAC4CE6B15DD8FF9ED6F74FAB00A4D2D9F89BED255126AEC97ABE2D0C7D3947907B -0AF2FF6A641A43BFDE3126F54E213C03C54E01BE7DBA01F71E523FCAA4C02970BAFC51DE -EA7A8530D73D62B5F3F457AFB500C5734AF579603D2CAB9AE49281EED2CC8FF7101B4F45 -F619FE5FD48A83D934F6A0D394B07B1235AC8FA8F3DC3CCD9479D87398074DA6AFC3402F -21B31DE8621AAD29EFD4F9CAF0A9FA9D9A0D097625412B4FD723E1363E5729F40D8C02DF -8D222A48C23B2E25CDF4F69D283E006E0679F1BD904A9075FB0A8094C1BBC3400A2BEE5F -736CDCFE47991E539406DFC399BD0B76D3A5C8F91BC2BCD841E4AFBB521D46B8E0558F4F -A800637D47167FD2EF79F5251095FFA2F3BDB915015010FA689E4E87F921298735A30EAD -938B6BA40D4E58042A3065AB059C598A96DEE3AF09237FE8A6BE9CEF014AF36D91508C93 -F7A18393BC321C3A4110B160261477F6D9B6771DC8738D8259BC4FF1F2C1A657638CF4F5 -08AA9400D4AEF4ED4508BB30F35E38D968E008230DFE501A9612966F7E35B6D8DF26338D -B63BD1B88885992D8D3BC7EFCCD89622689192CF14C328C4E4DED3025E56F3E73FE2472A -144AF139106A197E00EDC57C2443686A234D214FEE4AA2E3EF978444D4A2BD1373423CE4 -E5F82099974FE66D53972F774F2BCE9003538CC59003D0DDAF9889FBF2519EA31F3A515F -8D2C0091937DCAD3FC757E18FBA1C37F8FCC69685E95932B3DE60F80837EAE690DCE306A -EB060698E560BD148CCCB42240665ABD523CB02FE18214AE45C44756E9D3A8183DED7506 -E560EDB4D43E3971712C3D23714B0F83D3BF19C7320FFEFD07E9E8CC573D97FED37FD3DA -5EE98331C70CEFDB6F6564D8EA0B985F1206239822A4644CF2D7ECDC63FC5D2014359891 -5916E41FB338545CECC1B9E37DBEFCED4A55DB485C86C56EA97DA572A2B74D2650C8C839 -1C57A1FC4F75913C8446846F26614E8C72080DE0FBC3FCF92864DF37F8A3C66109AA56BB -3CDD02BF5330C38BD39B081AFE90F775FA6C78BBFC51DC0FF37B9CAB4058888CB3D4DB26 -40D7224C0DBF9467C720CBB5F684B2A1CA8951B29182A3913EE398B8E77CB27868A439CF -9DD03BAA0B60DEF70FF776096D86E71394968B7D64CE289373BFC8BB2CC0BDF78E1178E3 -D6F5473427E7AB841223F963FBB2A5743A823367D9AC4A5ACD8BA483F5BB5AEA19B1E882 -670B74FF997E3321BE8A96D7C0435EB77A36F7AD6AD0C7B21F5C74895090908FCDDFA655 -628898D8FD6218A60C301D959265B430369C564E01CDCB05F42B520625FC0FA93F9736AC -7D5ABC70D1A25F6A6A95C1CF4A584B51E9CA9FBFC9F24EC4F2257B2AEBBD9581438668A9 -F84CE7E9919C84227D76B11B1BFB61788C69603F0106CE5FA226129EBAC295709495748D -7E1856EF2F1D5F19458B977506F64AA7E433E4E62662F10FFF43701F2A726C3F8CEB19CF -D467C3B4E835A99941C7E46101CE2C97683A17530F32808DE665326D6605984689241CD4 -5DDDBB5C964F3FCF7FD89D8B580D941B856613EB1A8E59052B296E8CAB02B561863B3671 -E0E73789B112F7DB5F0B2313B083D17166D05B65DCEE648210AB9D3F3DFFE60EC4649552 -2F101001B3FBAFE7BF2F0EDB70A95C572767FC1880F84A70DBEE39648A176BA8C7C87EDC -D424245F6F66C910AAC0C60E5078260A698AD823965D83268AC7A98EA0E7A23A7599470F -F6B2E6C6F32FD3714B210C775DFF039590A0A159BCD248E95CDE7A234CD8F64CCD5ED383 -D2E49F9FF4DB2BC7E7F8E1F45643BBA556CC2A8C7C0D32CCE2D17CE77C6C8B021AF086B5 -1F0649C7E2081705B2C0C57B205E8C6985C849B01EF956BD97F8862BE1B061733C8DECB3 -47F4AA8CCF7FADCC4C335D3917604DBA283DBC054C76199749C7748A48417624EAB6C930 -B403FCF33E8A48AE4D064E70CAF24F68AAF18D1F87E4A920E2796BAEEA34BD4F208C90AB -87D599E2A4A2427715819D7FD510ECBEA421E32FA9C3B672BB5329FF756B0E4B31C2B16C -ADB8ED6D90BF002B29D4B4F9AB7DB03B83EC9A165A3F1148A9C1958B8071F279440A019E -743A624CFD4166857D8DA38C230DBC91DEDCE97E006B242E14CF25EACDE17E7E2A6621F5 -662820DD295589E5BCFEBA6E737C3DEF3D3482D7737CDE224E3509858B999B66F6F365B7 -34C207A58FB6C0DCC099E1A50D95A7BA53E0E51EB4D6B55B681B37FDAC9543F143EE5B57 -292DE45AECC7F8528F70642A9ED6A987748EB0FCF8E4964131787205AAAE1D84B18E2736 -911C20659F9813B7F90F69F2B93360E2983CC40A3122DEA8263FAFD8DDCA7CDF12908042 -F5B2045B3AA8BB0336816C80F1C89F7141CB3C64C08E8879145B10696164E0872635D06C -186444A971B188D84C0B908CAA9D14DE8E69A758841AD6FA932A648E9694E399F234D090 -D365A315CEF4F66DB8E959A56FBEC35DF6A4E969A49FCAA95FA2797D401DC1B42BD82BE6 -5BDF85A7B8A3FDE93B698F10F675E8E0B7D2AB4B3DB8E0FA5D21184C9487BCDE17AB44BD -DDC9278A72C83EC2896B02DA5D91F2BF9FD44D56CB65B65DBE0D325427E6456E4046DB1C -5229F513A4EEEFC319A58334835FA5DDFB73D4C8E92C4A3A2F449939939E07BF9B3B2200 -1488481193B08870E0F077E47E7946186ACAEB9FA732474E2DA080AB573A4DD27BD99894 -F2EED2C80BC44C46596FB47502649BBD83744562DEC7224B1CC54CF28192D3C23956A7EA -96DBF54D85353CBBA1770E0FB58B6F1852409BCB1BDB61313C3C7C3A349591AEC393EAC1 -BD80E7CCB94C3604C5BA8B0828AF45182C683FF51D2D2C00570F6A172E2F9DEE877B03BB -45E866CD7E5A99E63B4141C4B12A21F62CFDD331137CD027F94DDF9F054C162D74FA1CC3 -94F404C707DA1F4BD2A8C1C762F243F14FC71E546EBB5733C43AB43FF23BA9C2CB9058CE -3F3808A129A03B6E13BF8DFFD23A1D02C839FB6ACDE2BAD2474EE64FF7AF05FB40E30A23 -6BE270B787D6FB1FFCC0C4D7625B13217071FE46C2DC56DA79F278C69E85D7856927D0FB -108EFF1E3AFBCB9CE54BE2F76DD439BB182D3DF1F2796DF6B5733959A950ECCFFE7E0B7C -6BDF71CCC7DA4FEB31D6FD79C506250FEDE21414A1A842747F350664CF53E6710808AD08 -A6FD26ABD8CC592F693BA372A5C0D0A6F4277A92553CC72CD6212865DA7D032D1904F1BF -668B0B37511CFBE3AAF595EFE422FB3007AE3022CEB6C87058941DDD0DBF6F9ABC5E8CC2 -6AF7BEFBC1F4B1A03636965919D070FAE1F7F9BF42FF16E9778708478A279DB9DDA512CD -B372E39B9C5C87CC7A6E55BAE1626E8AA3ED7BAB198149D33D8E79960DEE846CBD2ABA76 -1979C57754955E90D7533C0B38CE5851C926F0738CF4EF1BB2951DCEBAA0A0704870DD80 -FFDF92D2136C1F470FF5345C7A93F4DB72360B4DAE833E2614154FA43A2347FAF4ADEB0B -73C8FB0AE22A42F80B03C7207F75851AA036C76934BF67B10ED6A5B2000A2F300A9E1552 -FF9F4C66ED0FB34900CB8649CA50BE457B967184D0AE2BAAFFA2AF24881761BA01759D8B -EA601F2C09E5A15B1289A9BEB266392CF5CFF78EDDE664F3FD6B77A6C10BDAB1E57E4ADC -2EEA4F2897D2ECA99DBEDB2046C7E889EE2FB30F172EF290BD4E16FB68C14E88A58E3F70 -9895FC431776EC963284E03B6975ADB155128913F0A3C910E6D3F0AA11A1D6D67C0EF96C -145D63F6E629C61C934BE19A0EC8D5ECB08AB1305C5C53F41628E7AA2945D72A18F5CD78 -3DAEDA17DBC867BD813F81E2D828B09EE77EC5BD7943FAA62E9682214C65735152E0AFBC -E7808699369C181FAA4977771FD8D716DB2BEA0FA4CFDB606A2EE243E0F4B576A3C5FAE3 -8F67C4E29DC0D86EAEDBBA90803E2AB710F16BBE42748967150D969C2E07115A9B2A2507 -A87F7EBAC946F7178505BD9FB0E08D86DAAF88D8A5EDB321FC2E7915CB80E6C0C2B125EE -0FC6124990A00E685E157EC94D72CCE6169F852E0D19DDAFAD022C4DA4D19B979D33790A -E763E04F78D6449C7D3674A12D1C01BD73872284A3D7CE4B551CB80602FA4145DD2E4360 -1CDCF3D6567887A6B0A73B7E1B6BA01DC93C51E9FDA181B20835A75541320F1BA53EE871 -16D938FC03B909D4FC6558223DF057E3E6195C1E26D33B28AE7156B88D7B5A6A85ED8498 -48EF890A5402467A8B11E2DA4719C395D6F40E91535F1DE6C7FE1FA57705A8F1321E2D74 -69593D7E6FD067E07B51E7BCCB382B1B00B655116F3F382D990AFAF26347CC6FDA803727 -C1E13C6429D1F5D5E5D9D56EACCDB32E30AA10DDF5E0294E59123E4C2E020AF1D13A0F89 -99F30A49D8049E7D9B8676D2C13DD896FF4CB82995F6517462886B4D6DC37BE8B13D07BD -23CC78524F835DB22AAB29A1E6468E8607FE3C9E1B1CDA29B98623C87EF39A2DE0BE849C -438EEA208FAD0DF05BB478D8E54501EAB704ED405598D38D6A58628BFF784EE969725A1E -8BF897007D0D6F53025453714BE52FB6A5E4FFADE5563846F778B71FB0D225F8C9AE9985 -9CE14DF67AACCBFAC3AFACF1CC6FFB6BB517C87A382D1AC1615DFD97E52D3020E531B8D5 -C6318FB90D30C2CE9EB7EC0D2DD8FBC83A48BE41F22EFAB7B5CB7262E8BFC1196C69AA92 -EF1AA1D59DE9B1C55D5B7C0019D68F23323CEB4FA767550B090439C2D1867631A97CEF5E -7871494CBCD1EE56C0EBD4B2EC412EAFFD1783CF073E9B6575CE9642F704486C6CB319BB -19CD270D1EF9B63FE25255F6CD5D3B77B64FFF7B562742593E6DAB5EDC5E9E9467A1A478 -8BFE80F892B3DD660B1765B757CDF91B61E5AC7C7FA68857656473C32CDBCC21C3A0E812 -FBB939809D552C9394686F8CE36CFC3FE8994D26CF4917CF0F11E0DF8B806B5AC7B092A9 -255EA0364A9DF03B85D67BD2B4B4FABBC8161542814E432486F103F2DF6097DED715E2DB -B130A753D35EC68126DB76A2952575BAC3FABE2BE9FF73D18E60BA667575FE3327769770 -925F00FE13573F5050DE00CF24CD231CF619B2351371433DB15B1E97AFB39FDC4E07F1B8 -45449EF4CD86B3F0C0BA12D52A81D5386A9B3DDC62E588FA80D5A1E31FF503945EE0FCC6 -841AD3D4E56F9C801E84B01FE978E7684F451822423122221FDCF6702D48CD226DB839A0 -E095A31975298CF2FD71E6423F0FA5191D8BF7E27E6963A23F31131E68278485BBC5208B -6C5D2765BD053C47566A65DC4B173E1580183763326010D54652BCF7BF68FADE1E3B8B28 -E5C601E241431E665178E56C36AA1125B07D8E4E9627027D73CD5A664B40D82199E3622B -EB76FC104B2E5A6E009B4AEB180ADE287F763B73A6F8636C0CBAB936F79859941ADBA525 -72CC725A8834FB6247ACFDED0131BD5032ED40A04AB7C655AD7E954E4CEAB74524582D7C -142FEAEC28F549E36135C085A35DE07E782E72CA53BF7B2C8EE8C3D8346E2C2BA619924F -FD9E5FDF9564723BC0FBC215BA0F785532DEF5AE95939F027A62A402A7FECD77F064AF12 -9472A23D2118B569DE04888A8ACCFD6DA14E928A7C2FCE35531FF112F93202859771381D -6D161E6BCF5C6DE9B375DE8E983A64AE6AB75FD52D590B78C13885B46FBEFCABED5BAD69 -04C4624E71B29C4EF6B6C2564485210616C08A3C41C83BD947940BE454185EEB33B0F0D3 -680F9BEC8417063BF03100F3484678BD0F51869F3244EB71775D0397B8DB029D13A2A318 -2320FAC3561E7C994DF8F94EA306736B7059857552CBDA0E2DB4689A1572B509DC658E6F -5C7FDD812DBBFDDE644F980A58E05F14454F916D4458DB067719254EF77A887D71FA3385 -3D6A8D1FD29885E3F52C6E424EE0AC4E1E64180999A7266C896CC3140A3C59DE77DD941D -376EBFA09D7F3761704BAA2C738610F39E7FCA335BE7B36F9306795D5B2056C57FC42C84 -66BB9141ADE2ECD7A4ED5BF9251C3091D8B950B95CF07303B165A65A4CD198BFFA8DDB46 -1032A70916E66838CF2A76CF444ECBCB9ED23B3B32143C9A98A395E51CFC281106A7DAF3 -74AD4BDF3089EBE727C93E58025BD6C8D917065C4873A5DB3E90084716C5082F6CBAA4FC -E60176DA9B75DBC2DC5BEFDEAB261C915A7F68CD5F3296FA854324B661BE571A9CB98157 -9C6FE6A5EFFE43C9933EC292550619B794FEDB97CA0FBDADC4FC665D7955B43BD3B23A0F -1B76D78F7A1CED8FE598074469135890FE8789FADA3CFD4FB965A1FA62E55328EC450B3F -1E6B00FE274A494D25E94A2A95131D5E6C8DC6E27B65BEAFCE6095420696940A282C5AA5 -B9E66F243FA307C989352A1D557B83C5855C004D86A4BBEB11BE9F152693A77925B014E1 -6AD084959F78B2A136EA406231AB1509E43176B268B8EE14FBC281CE832FDC2475447A21 -49CD45645A78E4A0027060CAB18394DD5A3E7721B27AEB22C9E98AD563BB5FB2B0A0A759 -93F090DC2249F1CD8ED869E0316A2AD4EDB4C24B18B758AD2C746AA9E7544299C8170211 -6D591080B15C376BA8386FACF02BF9E84AB8C7470483A4D6921CA9A2F191A42BA49928BD -BA244CF5918E55F59E27D9CE90517F9485D91F1D5B02EC941BEB6AC9C7CE3E684E882D18 -7C9B3EC948A745932BBE4DAF8FA61A84FD7D1BE556891F8C339E63457FB447024A3EF140 -99E8FD37DB2AD623BA1476C883F62395E98C1B99F981F3FCE92A9DEE9D99627F5DA6753A -F46B1B69666048C981DE59BA35C0481FA33A17D511EEDD45D90AA7576573625F167C3BA4 -35B8FFEFBED92F368B92A0DC32975BB2C9C8B1A121CFC44075474B78B496E953D45B9762 -B2ECD85E0CE52B15510E80AE563235E400CBEAC6EDB602386FE1237ECF4D3C14C92280CF -F9768E60748AF4865981EDE419204FD2F18FC50E49245260BE2319DC1E624C2E59BFE1FB -CD04A3F5FAFD8D159E42B8E52E0B2279FA442E613AAE3DB6A1016579D3170F8F489E3793 -12A6E32F45128B15E01373AD0C1449D0E5F31D5DC50EED3EB856629EC2E51616F40C9DB2 -F4EB8BFC519F473A02BBF02FE0E8F86D0EBBDE611081C24B3ABE09239A9682D8D573580E -86D5FB31227823CABCA34D9BC918F38D9B3273223408871EE2D29133367C6048E0FCD93D -22144710814CEF24D9680041F020EC73546ABD22B6F521DADB8E1F6AD20AA8F33FDEDDAF -273CB366CC1F7FE33927075C911FC4D9D8175A7AA4E483C2F4AB658EBD523405F83F5CC7 -E328F3FFA5A66900508DE0682F4B4632880A3C807D606A2038F796B3A150F2202C538F3B -92DEAAE46528E1BA68E19E6FEB80CBF5155A91C16AA6FF5CA472B4444D0981D1D9F7C9E9 -FCCFF9E67FDFDD78AA2AB765E34C7BC29B2D8BB138AFFC8351FA98DA41C552F6C1479229 -5909A4EF7F4865E16BBE81EA742178C3E86B9D2B957DABD2D6A558921D4FC3429A30BA66 -13783DD39563547E9CD1FBAE6257DA11204DC8130C89C5B80541E0668752872C050A4320 -92BEE57ECC95266FB612532DD8D5465C938AE4979559CBFA8F2D7903E48CF9DEB397EA6F -31F274D48E8956D337310359199708CEA05DDD64CA417300ABA7EBE4CCB70DB7BB31FB45 -E2B9E0F15423FBB2EE5964278A536790F16ED4F9CE31F6DACE8C0FC489CA73D2457CF3CE -BB9BEBD0CFD2D1F11816BACCA5D4F9A84EDF8D7F09190C16F1B6D1766AF98A34E5A28693 -B555E507017C1B9A1B9D8D2F52E2899ECEBB6A341BDB98DB0885D97C5BB9D35EB6D18099 -594DA2A6257D5E4806D45CCA23CE2545697E3DF34B6E7558D080B030268AC56A576AEA44 -B4DA78A686340EA9B2249C58381347DE308439CBCB5988DB881340139156FFCA9A8961C6 -2004EB36FB0C77F8B762B388EAE846531CC38B75AEF785311A6F8AD5C0FDE8A61D89292D -AC55E1920923E91BBDBB40675A3D956163323406F2EAD0BC79E4E31C2C2B22B46D266657 -FD150611305CE08885360A76FF28F3DC837ACA58CAC71443120508A80F9F7086DAAC40A2 -9082706907B9751B19D67567FA243BB6595E1DF225DA36FC4F8D86712B1BEAA0D297AFB6 -D20AB0ECC8CAF709E991604552ADAD7F22F8F229527B60BCD4DD9786AA36A13328881677 -7E00F57F9E562B2CCF2D1F6F6968054D8C9B08FCA9E0DFA07C11BCDA281DE484968626FB -52B677BCAEF983444B24B0D959B66FBB9631AD4796C435888E09D90B1FE97274D8459A07 -9863D3DF6856A45BF8555999FD430FF9AF50FA060364A727503362129D627BCDDE83F679 -549FBE4258B08DF47BDC2BC161D5E61804588615C5CCC3CA6948C25DC854EDEF94A2315E -A89ADD8163BFEA9D72B430ADE3D9C17D69C9362D2827EEB15BFE3B8806A8CE373469DCA9 -13FE773C8B9DB720538BCC4D8D5481CA29661C00D1F5CAD55799F363AD2CD563EAAA70F0 -6E250629F63A0ACCD3AB2F89F579557B8299F1642663399DF9DEF3BEBE9F9FB3505E9581 -4D58D1335C9AB341F1928FB7553474865191AD7D8A89C8505B88C1C22BA7E3A88A512AEE -41B79569560C45B67497A6AED27FBBE40C8B2310157AED1078B9F352B79BCC93DDDE7803 -F479CAF0EB48AC801A0BB9EE972A258F110446154E8DF88DDC10523E8CA22A62285B6285 -E7B3A4AD23216701310C4152DCD1E39F771BF8305D35E0BD42432A0C03AF965756F25CE7 -0869B6DAFAFC69C8DB3631C918A7CB0A1A6E3248C5E1E665E926DAAFC9BED400CD4584AE -03DAEA56407CFFE84729215EEE16B10BF164B5AD7303A77423679FE14F6626C934A14587 -97A4ECA95603E5F4023CFA4262EA9E949CFF449EF9A82005B23631255E615B060E4BE2F5 -526E06676500DB126EA3D38E3562E1819BB68624010F5A984D446790AC8EBE11C5137500 -1814CCFDB10A27EB87382CF5788150D66B803F0833CD73063F2CDB1C2A56E12F8DF75310 -EDE85042D615FE028F68C668017A2A32594B89C428059DDE3FCDB18F9906C7E813DEA4EC -C3296C1A21BD4BD3C373E91E0D6B6582D99DF35F5091C09602547B864DFE966532EE4669 -49DEA26C0F7B42D8023F8EDA050D8482361EA43C52FFF4F54335284BEAC3F427B6C59058 -912C233525631F113FB15B888D5112759466A337C37A22346C6A4963E3CB53ACB141A59B -3BAF30349CA7D8827C2CEEB62EDBD851C2AD9BB8083DFBBF305ACE6868046BD93B59C2AC -75D6F3B1C243C6EF66533D2DADF52D81DF1397ADC532CE86363BAFD043F9B1B8E6B83547 -4E3BC3018912BE08A570BB4000BB13F249F38DF8C73906EE9ADC7D5630F04BECA0A86EB4 -52ABFECF46D03CBAF4BE02061EA50576A984FEDE9DE35DEDE1988DAF0A6308EC4B6BDFE2 -CB0C7198122C19F73CA7436955379985DDE2ECF851D83A425B4427A4A17AAC64D9E68691 -2645FEEA0A8A0F7A7C1CC0B3E96C519386EC14626AEF3E9E8718877DBDF45C9B8984F81C -99980A8F8F3C9618F34407CA7916D2C4741AB9B4F916763E1592BA2C2D5979E2256E2D17 -A77905EC38606C3645F1348E77ED501DCB783B8BF677E55415DF7373C47212BC59CB71A5 -4425410E29A19F74A9EA8AA508B19464BD0BD1958931B135DB014C6F358ACB880C189070 -E27188EDAA43009B515994E8F3481A9DFF6DB2D5D474F0957603B0A45A7E6ABA97640576 -11054B1ED7C692263C1B2BC424FC68615E9973A230849E771175432E48746AD8E3A15746 -1622190775BAF10F8BB66D2DF99170760B26DF8714BDF178334D0F90A615939C95DF51FF -D90B28F5BB67FA593ED31E035342E6F187DFAC21FEB26107E4ABC7F484AE11CAF85543EB -6FA887B4FEC65A760FA33E6AD078F420D4828B526B37B4AFCDF396459B6338896D7EE8DE -FA3E10C6087DD4E3F56CA302D955FABDF1EC04A5FE4F12CD40535879AF0AA992D40E53BE -2EFC1FD35E3DFA33EAFBBA4E851434334BD4551B4228BEB88C5F8D259864132E2B893C98 -2A9560ADB25C06487A75809CE201F001E426EAFDA88F9C7AC36F57B06B212F03AB8FD9D9 -6EB6122E968F3536977ABEF5E75AF5C9C30684D3D7833E3495F7F9BA021B5C4A1F76408F -B42837E068F91D9D2FB467802873702AF6216CFE60C42B1C8F70E7555AEFAE95B6D44C9B -967E68064CEED38C09BC1A3FC447FEA9902A26B6D5FCC8A42F47AD2FB2C4DAC61AA0ABFA -58515C45C912BACA7D3D32EB79DC14A4D8DAD9EC0CF8F4F213D3E109127FB7047D2DC47C -0DA7A5B790318A1E13163DB7DA71AD64BEC58BCF31A596DC90163B1C46C9175059B27DB2 -D858EB1AD055891E58C34233140240EDA5AD13695EC1FA606EC0CA9CD84293A75829B1DA -2DBB20D97F96D626D7E6D2332B664BF543849554B07ADAD02CF6DFA3BBA2D8D707810B0D -20BC441FCAD69B8D986480B1E191FF390FA02B76787CE41E3F779936A2EA8CC0167BA167 -E4E08204BB8F4D0CE908AFF57F1E9CEB3F00C1B863BF65443684BA425888ECA909B2A6AC -5436D996810370BE779C30D21941A101B2EBFD4F38DE2295CA0FD39AFEFC997377EFE1EA -C62A9347DE13284235061173CDBD0C97A06045EE97A193E79350B8762ADDDC2494A68628 -173A30563595266EE3AEAE1179EE7CCF47A7F9A84DA4B4120FF6B12FD8784BBB674404C9 -973DB36020A9A7EC459F263213846A56FB52BE79B8D1F52FD8EB086A761C665D94D01336 -D5029A5C9C7D7C1234BB170E90CBCF1AF8E5F5B21CCF7C11F9F2A28384B844B1F8F1E543 -393EA9DFDF15ABB11520408BA5242CE5B5AA7EDA7DD72D3D9B939AB2AA4257764929C8CF -5F6806A21D524DDBABA96FC46B942AA00F9485C1F071BC6C94E65A153045F88BACB20D69 -6EC1405D8880ED1456162625EF0EDA8ED6022F4E6BCB8800A23F762EA3853E45B4ADE7AD -4620E7CB83EB1CDBD40ABA6234EBE853B3378EBD4F077AF9E12E692995EE06D45CD4CAD5 -ECED7947A89DCE4A66F1B265BE66BCFAE487B41AC623ACDC6667018626CA450FA2E60512 -23B86144AC9A5169C29FFBAEEB9E1D65CDEF2A5BBD29DDA5021AB9F435C459A3809A5DD3 -6EDDD773C0530A1BE54910B014A6AFCC1D95E36A5C8C7D8DD1DD091D7B14E811D864B1E9 -41122A7867ADB016F949DFAE0BA06FBBBCE87C833C6B244AC48A7481C54FE756C2438B00 -9ABD319AF57D0F69874D274F96A12BD417E8CBA7E20FE608A73A88A935EFB77DBC198005 -1CFB9CBA94E196A412C45CAA4F890DD9334611CA1D8D6F6DFC3C180180F22683BB00B8B1 -0D78BF4D64DE288D2ECA95878C2BF266880E547D3826C5D1F3C6B4B0A3EF0345D8FA66C7 -EC77180BB59A6CA349687F18FF5FB5B10AFDD7A440E20F55650F258A10899BD9467DE2B2 -086D32150FF9242346A6546F9A1548436BEDD02049983A46A2CDB4BBA8BFA5F04D7BCD4D -35DEBB30496780236DBE224DA28218DF58037509FAAF6BE46DFE5A93C1F072F37D80FD97 -33FDCA1345C468C85CF501D4EE30D36EF5FD87837DDFBD703B8F6AC4AB3DCAAD7E7C5E54 -B6383A74F4533EB9FBA0BD8D1D1703590CE24FC3DA5E5BC929BB6EFAD09F02BBA5E30315 -2AB1CE32A6A2F61448A765D912A8DCD8A8E0003CC2BF739F4DBDB388320D990B9F00E04E -05AD6B650435F44CA9570D878D89CE782E06C68BA9024EB887C6FA18223F587338BDA034 -893624FB950E74209BBD763A9677FCDE1236B74CBCFDDBEDECB58DB1DC445BE8672ACEBB -05F0E677D133DDAD4607720462C63FD9409C29C75039A9EC34EF0BD89B3AC6045389A3E2 -136C9A6D502D335789CB74B7F369A6877C01CBA68278828D17C5B7C0DA4F385FA21DD8C4 -C68B9E17A35905DC4006DDD3D35186E31CFD74C26E7FDC450E6729F81FA36000E7EF2AE3 -9C4D80D9A94429DBBCCFC44A7044F424E90C5D156CE1696CFA2EA4742338359287297CAA -5D616C1F7C7E7E71CE9099028D6516FFAE321143EEA343250553B3249C2937C1797ABCEB -BFBBA9BDCCD5A15DFB20E3772660DBE2C410BAB6F4B1BBDC61AF96F88BF830C23564D4F8 -2FE22F6B22B63D06D1B40DDD976E19C8B361239546890888FAC5E7ACB15C4762C4871DEE -EF368A59B6BF8A359E29967FDC8A59E03E357D3B84843B20EAE12741CD9E2F2A3A32CFF9 -1DA33E881008CC686D03A1D55651986C00F7796559D4D8825AA811EE8810B921FE485D43 -1873E682B76E96ADF5A586B9C1C5A876AD507C51545009F09E2241835ABE9C6CBC76D88B -7BCA368487A11BD7654EA0B1EC5F8EFC9B587718C732037B875ABE9F5D44C82B29FEF550 -B80FC0FF7AF43A6CDDAD7A3E8024A09C04CC5570C1E91B97E7829AE7402C870E5496E8F4 -B12B0D9DD500DB6F8546F7C2F965387C37A701F2B43D236AFDD777537967741E88F7BEFC -9D9B3C7D6A86B1AB92919A48589CF276BB9F00DA2D7BE38F46C9E5B2365948E32A30D830 -0FA8980D7D7C6ED2252D9465EFF276856698108122833A0B3E774EFDF55A69070FBC7E53 -E955C4E02CA71323261353E8F5D1A4948ED41F4AD7E25585E6DFCF5553C9187632617F3F -9D2230A478E4BB63497500A3CD8AF78C780E700B14272AB399D2D2FD9979A9F422DD2B92 -8CDDFEED37A40A77F93A1BFB9ED9297B2BFCBF9FD40A44D2227F4C7EEE3066F1020EA335 -91BCB47A260B744919F0359E2AE3C619592C325474063675E5D85DAD5A00CC879EFE071E -68CA2CBD108FAB3849D312DDB823BBD18D7C3D61DE7A5E4AFEDB203D4056B43EE1D93CA5 -0BCC10AECAA08799E0888B637B6D122EFEDF40DEF30CA93485F424928F3CD6AC66D85035 -F8BEB418C560E00331294B1F57831C33F8ECBB2561837A5A0B0E5E2EA2DC3F72A1C09990 -11BD2F0A0916AD62A8DBA859AE63FD73491390CDE70B0C0B7D36354BAA08BD6014B790FB -33FB26BF6C2215E16379072959ACBEC5485642A7C7ADB0B826DF3390C36C9B28E724D2A5 -7F57EF0B1846B358669EDBBDA569EA1B28E9AFF2DB2A8DEFECDC073D954F3879175289ED -9F159376F3D1301EF514B47D3EDD5092C4618A80D20ED37D4EDFC8621CB7E4683AD8B2F5 -51D666B8F39C0CA193BE383B0DD31BD540408314871CDEB6117ECADF8E187D1D5ACF5239 -1F8B2B1C6E6F89A35022D0A2B8CE22B79B200AE116A4E9E097872CFCE5BFF8CE9DDE2E85 -087649207EBEEA22E07187C24404533EEDDDA851CA5E7C18657BAB75029DED2D381CF4AD -2D5D52A310EF4B8477008C11393D74B34F0FCA4026ED3C12C71941A6D77F501A649C8823 -2D9A1EA080561578DC7A1D591B8E922BA280977ACF3549A24125FBE9049C30CB9DC547E0 -766EEDD5C0210C248C4E7E435C81AF15B187F84C216BD842380436BC3467225938AAC1E1 -FF7CBC6E6C59BBD50767D3BCFE93564F1905AA38F1DDAE4A783E857D148289304F8DF194 -CCE5CFE440CEEDDC5F3CD1E1587F67DBC41DF3CB4F08AD19178CC4B77B1DA3CA02B6F40E -36984E0439E53877225B9F8576A9A2B57286D6F759A060956CD30B6E37473CBB55D76FA0 -2F4588E66305A1F40DACA56CBCD42883B960B6DE2F91DE519C80D8FBEDBE38024EC6F6FB -B6FBDD5323235130771153124CB95ABDF622F737A42078D8E81C9965B7324F231A072739 -5129FB30006987B2BB806D414672310FAAD37F3FD005EC54D6BD2170AAB9A21E52A9A7C8 -C6AF03F51488D34B06F22D93E72FA5BF7097918FF67DEF79A6D62CB216ADB114A01CDFF7 -DD387A0CC150E852D4D267187F6A6DD6B78C9E283C9D547DC6373A36F3252CC683CDE9D8 -EB7221146E8C54D1A90DE57003A0CA78440EBFBF35028112B431C508298BAB97DC45875C -D002FBC1E47BE8096D13D485E2604EEF44B0324B0F494D874A723D080A9A32B9668605E0 -18BDA773FFFE5566DDA289972B087D9E69268B2CC04CC1F22DEA738A2248F370328C7FE6 -D50DCC267BF736C8C3418626BACC805DC44F60A862413D4C76104D6AA64F813ED9766563 -3236CC8EB519A9C3A2D53D20658BD68463BFBB0B97A795A78280B0C05DFA3FAA5EC6E6E2 -879ED3817C5FFD07949528C3C60DC6A8F1C73B7B87975A101AD9097F694B7D3140B2EED4 -52E98F073ED4648992EE76954A712C1804DE95D1C1C98048E5ED790B3269BE49C7653292 -E69CB482E19611F24773F00E483B8541F7D1EF3CB9730F527FF6309EC105CDDC9BE9F9D9 -4C28B3520719E5AB1EACB85BFC4CA92ECE780476DFB3BA759550A261B675ED4E1C1325C2 -EAC510BCF993FA03281FFF75833EFDB168EAF8B2AB92AAB82B389E7086822363A74829F9 -FA36C1703081E55EAC5E6358866EAE8BC04C37770DC97392713F110C143B7CEEFFCDD84C -A6713C01B4AF3732DE935DCDC2223015E57FBF98DCC32ABA1A989176963124CD353DB3E1 -8998F5F322EBB591528544A4A4E0618076FB07540DADD6D00F8B66A60ED5496CBB703E59 -45EE138D7CD77C301CBF0814A7AEAC93127862431265081273C1E04B6C2B4DD0936D8F34 -98B2EDBF2E2E09397169EC99FB85AF23E929F4871EB8FED7AA77B2E22AD7AE6C86F15B07 -A01B8A1E3F8381CF2A7AA25FD49876DF2E0DB253DED331F7CC0A545BDFF42CACED8946D7 -9661F3A340952AE1CAC541F0F6E66682A22AEE604941AAFE270C3C2AF132C9925A01B35E -D770156A0AF4EF33B00DE099330D5A874F84A23621C6352DE80952305BF501442710DED6 -97682CB92BFFB645C2A48C49D47F8664BFDA17F5ED7A0F64CA28A05CA58F06A9296E6BFA -858B5A728B28E12C75D947DBDF779F738D67BE839FC0D80F3DECCF255898CB916E2BCFAD -74FE85DB8AA036791DEB28487B368F14F1FC79E54D4D94074F8FB530036B09CA8C44468A -A199990933422C6AAAD716F03358E8FCDE9DF706F0590037971AF1D705DCDB45085D8940 -31468CB922E90E44AAABFE7DB1D6D4BD37081491EF89F46FF4F7FEE501495112CF757202 -448FA93DCDA89464D7AABDDB7BEEFC9671BE5A929DE84677636F12F4BC22A59E22F57BE1 -E680B67FAA2F00FB39B6FC7A48E43DDAB93FE9DD75869375A874B7CD49D22C314D617848 -139D61022A79D94AE1FF9E07C7A7C3437709E09B92A8F33AEC386DD37374051F0387BBD5 -F366C3EA12F5AEA0569D15B22729E006748E900A17E5D4EDD52FCF4561925C7ECEE84B3C -F29BA83B03EC7ADE70040D898BD3EADCA66DF42045C795ADFCEDE3DFCDAFCC68391DF6BF -C9CF4A49A45550F6301B581D19B8A8F7CD9E06BE7A3C5358D6A319188A803E8A5CBF9877 -B8E53CBD98E3CF270330BE2BE853E5BEEC128633EBD5471D9E5AE1D67D28E17C752C5443 -E16B6E1AE341E83ED9B6CFCE88A12A7329525C0A3BD2D8AFEF72D727B3104F12BC874446 -FF1E5204DCFC9CE7F772855D63A2A8DE36D382346F8C43D7153B9BDA92AA04600267E704 -E9F43F3D625EE0EE228617C7ECFF39AE97806096BD66B914A43EEF2917100C2F0E1B2554 -C891D50C3A0037190C9AD8BB6563E004696DCE62881C1F6F8F05A96DDAF3F89CDBB780CF -6B7196124DC1730D05CF821CA85156F7EA996C7E3A44BE8D4EA29ECEB2E49CA7D676EA3C -874594DA4B8ED45B1568EACD8FF68963E24F2E05EAE0908D1E81165B872F3C6284181CD9 -A06996A7D247A1661D65DC5558E0CBFE14724BE1D44B08A1E06D880D87905E889AEB0ECE -71E3A9037621470305B423EE63C2BCB5B227B264A4CD5CF8573D8B320004D212B65A44E9 -A856A3631BA02C46868994BC9985F219C9DFCAD9591F2B76B34904DD221E7C9BD2DF06EA -B632E6CA2A24699AE6C9C6B4937A8293CA61D36F3193D888D5081E4CCB837D93438602EE -DB2D197BDBCD0A00534B493E250ADEBB1D79238C8F8076801EBE4A282C98750ED7BA28C5 -9B903A26553E03E5B1B99A2B1D13BB6624717357E3F368B65C8B2AB2606577E45345C971 -CE54702D072593814090A9EE9559DBB28B3A3F44328C33F652FF066F87F1B251EA5098F1 -1E970A3505B982A023147D7D8B077E626727B1AEFF6277BB306423D55070829D73895B67 -3E2E6F9A1F954B6EF69507E1BE86D6C594AE270D54C39B1645FDA847DC3D3267AC9E3190 -9A509C03DBFC0A063FE9FA2BDCF21199FF1397A93F13522702B339AF7E6CD121FC2E3D4A -22132ED26FB31F2EAB17B8DA9AEFD61386EA3EBB771A43B60EFFF3CA55238BE1A0852F8E -5B78DE572FF42616F1D4A64E40C722AF8E194464F506FB9A6F52E52ECDC7D31287373EDE -F46C5DEDA0CDAE20AD6C88D6315714304D8589D6A24DCD9A0491598AC69638C04A19C07D -CEEC1F8325317431B3892F270779A55F293085402C4B4085268AD69995186470A2E2A106 -44AEE77DBC20926ADA20F91B5BDCC0181BB34C18D1FB68A32808ACD569EA71E627FB5419 -EA3228DAE56414EA93250EA395BA750C60084D2BEDF6144E970B0C5C7CF40B05EDB70452 -7775F2D0A55E33BECD54B9F91807B097575929FA313EEA4B8EBA80F9499BE28AF2A3BF03 -CDFA19AFB30DAC150756F90B432083DF21C79616A054384D91F913520EC45133A30C84B1 -C1EFA0D1AA9B4FB33908CD93F76F6A8CD03F8714EB0E688DD3A5931BA940C68DA296B217 -BB6E1BA16FCC974E3E9F45A30B47EBC5CDCC6E2FC6AFDD826A1BB6851F68BB88C2879B21 -81BA06EB195D8775B8CA20B436B664BDEF465309FBFFAA48B0736069FD790DBA0047E4BE -7591F6B5849B2A1B891895EC40234269370FF1E66AF3D391300E07F7987D3B168C9F4770 -9AEA1367B53613F52EEAA64D8D296396EE3B6338B8479022B19A9992964200413F29C3C9 -9DDC50C2C61B92465E339B9A585CF0BD532B2F2F3B7BC3597AE2B89C686781AB7C1A2A44 -A6A897F1CEB49F63DB43D9DAC45F92880661E79D2C292CF910A3E75013D4D3EE05CC1A7F -7EFF6810E89660F47D06DF62507A067B1F37A100CA620992848EF811D2B0FFE0FB8A85AF -D58086E2BF8ABA3FF4435FCEFA66F460BB9919A7EF73B5FC511BB3D4C91BE3E90DDDF6B4 -4A2521451B568A167D4CAA98A2BC114B77B2184D15F98943660EC92BD6D0B5D79449FAE3 -089A4709F68872DCA3AC59ECC84A66EA19DB2FDFEDF7F8E57D90F6FB0E856931EE8EA3BE -8F3D692E4CBA21BFF24CC7DD3366D5F7E57A190F61502CBA9C274DEAED962E5EE3CE7B16 -2E34BA08806B7358D820009CB348B10F225EA9DCB92B0C0CCA4192C3437043132CA73E96 -6527062BA32227B2DA597C8E3E75436467F2D6895B5AAF1BCF55A02267E5FC21AAD0E8E7 -F2459C0B6EF0C372D72F697DD46475075C4172E50405703CD18C23A6D3E7ED6F526C3EDA -DC5AF40507AA9A76C86E8136CD695C955D7942553361E63FAAE9C23BF3A24F35F8F9B659 -90D7A6656AE186B1C596A8E3F69748427F0C09F5641F284B674F46CF3D0E2708419C1689 -F40A35DFACD95F8C6A1EE07E7AC8E9FAB58FEE8D52E81D486F5950685CD4EB36EBC16FA7 -C0F420D6ADE912042CD2AA3C60B2468A59DE0A5CDAD889180BF05405064ADE97876CE977 -D6F665803C8BE866AB0F1B08452A478408095AA3B8EB0FE8490AA682DD00CD3AD3592FBB -54CC977B46E3CE307E7D8EFBA586000BB17EB0F2EFD0B0EE61CE18ECD565DEE97E37CCFA -323BABB4D6354DA19CD9080C96D13A5E6AA1888B17970D7DA8D1B461822CD70CCCAB9F30 -D48F924C91DE9F3243FEABDE5C3C620CD32A5AEECD6BD20EF890F1457285ECFDBBD22BA3 -FAF661BA18BBC1E6EF81DAA2E2A7CBD7A058ADFF961B5A103D967C610530EB58E2D78DAA -17BEC7C9176EFE8EE633FC227BDA64E54A6533B6D56B787F5098C47824ACEECD50CF4C3F -172C3C7DAF7B6EC9FA8775C52609D08B073B784951D66C8AC33222604C634E99E99D28C8 -B45846715733EB3446CDDF659D1BE4B439CF32FC2841AD3DEC81A95B20B04790A669EE4A -A9B40DCB3BB6F0A68E5A2763A8CE7B72586CB6006FCB68C3EED89E54698EE5928F10F5D5 -616EDBF01C349C20E99261495735C1CAFF99E2B1FC986A36552A37D7B57C1D4EF460ED45 -FEF6967FAEDE8AE1B2C7AD835D31AC8160B760E7A36333B83843EE3F55BA19E2F6CD7D33 -9FF0657577CA58BAFA3AC0B7302E88871974DC65218E856338C81F00E4FB35F8DCCE6208 -D7F1BD45C3792D21C308A3CB7B50AFAD17EDFA027545355991E99C1EE99D85BBE5BBBCED -4E9C6334ACE88F82894B4B1F81F51DC6BBFB2621CF7ED7FAB3170A5DBF6F5E82BA316172 -60223D7049D20ECFED36DD022307D5ECEC358D4A8E7DE800F7D7C048FB265C96108B6D56 -EFBA19A79D37CA7DF37EA1F778B74CD5BE98A2B13BA7E69DE56365CAC9456A3C248D6828 -6BBAC51CFD6D73BED3BD7A7A7B9800B63D1A94882A52F322CC329F1BD691574732DCC32A -3425E83B88EEF053240D7C7C643A7FCB0DC7B452E1AF9131CB776D450EBEAC8F282B218F -D1540E4816E53C488F026A6934CD059DD5A09DB1DD8016815D066551BCFCD503CAE5FC7E -996E67351A6D681EB67D78F1174B3041096687912F43F6ABD7078C7792EC69A42ADB3F40 -95F326C049344123D0F93EF2D79DA7E77875AE9110F3E87FD87AD187B566DBB723E06877 -462C366B15BCBC0D244C2DA7D033E0BE800D3DEB29B295B6326AF0E5F151D50D6E1AFADA -88A3E0B990C1660004FE5B25F2BD607AC5A141ADCF984FD2EE49871B9BF5D5A1B3D96780 -B4E0AEEF7B4400AFBBDA0350A1586294FCFB5EC075978ECC7F6222AFBC50C6A0CA10DBD7 -8615D8128DE67FE07F2E3869900367476DA42C78AE359894BF443298166E7C935B310FF5 -E1BB2FA0677A947A7ECF0A89C3FBBD60D4D8104F220360D505EFA6AB9CE111C3137F6E51 -0616EA60ED8D1ADBB1B058BA22A6A76CCF8F0FBC04AAB81C6439F44D5659E937118995D9 -C299BC02E354FD4E62E10AE9D2D80CCC72780909F49E6732A61B131E7AAB8EC3D7EFC725 -A153D69D3204AD5F6A3AD6728C2B9E26D337E846A797A13CDB160D740D11FC38CCA2DB5D -E33074C7E5601C8573641E40BCEDD6B84CA7D15C1B86F42D4EC74C2CDAF65D5E22929717 -C6237AF09A0461AD9237F71C011BF36C00CC630E0C55D1B04D7D989EA011D282B77A4BC3 -C54B5440557303C245FAEC70FD1945A8556B8033269E6EA1C1DAAD39CF5A1BA9F6448684 -EC60E9809ED363B0134FD6F19F208FDB26A4A828EA42322550BD312044EAD339FD8DF100 -0E9F64428FF8C72C51FDAE3E7A69B6D0BFC9B2664D7864163ADF48D2F3EC3629063A39E0 -0B8B4DF52D2B855AC448BCFC2A3BED94D0CFC4A66FC6CB22D158C9B1FF632CE71DF9E1DB -CDDCB6AD62101DD1A776CA2A111B283E25D1CFD8B5F238E0FCB2008FC1DDA4EF6CC11C85 -96E38D6DC1CC624C11EFFF6DE5AD410B7773BA0C9C8B9E5F3B7C601222D810E921D55DF1 -575F452CEE78BAC9E306B0801234709349F8C7D603AA39CA94E878781D5355B6A534D5CA -06B774BA53AF73D36F60705629854BB39552ED6A4508A20633D2FDE04ADC59EFB86BCC91 -AABFC0BC1CC136BBD43D8934C54D3062D129F4AA3A37AAB7E870C6272D32D2E56D0F260A -75F6037AA30AE59A3A5C3417021026BA3DF9E6E55765F5B0933AECF62E28C342CE6C6687 -6FE4231A5AB35F194D7029849D8169BC54B94F34DCA13AFE4F5261102648C1FF98212831 -D76A892CB55AB502AAF52AD08635464A7C65AA6947F6CE69BE3C7984CD36057A31B2D8B1 -935122CC567A10025B6F4E305D40B600D3147961F914DFF15C07E6971A4B58E2D8F02F4D -54F50947094617BBDC1811AF2FFD72F5376BD65059737BE960D52C9B41F2FFFD1927F3CF -750FF71292AFE92B978F1A89EDB201F71D014FBC8D2758687039EEBF1ACFAB367C555381 -EA24C44F1E0EE7FAE39EBA4413FA3DE14F947FF5B3909323BD35193B6E2BEAB668B94A12 -40E61DC39EFB28634214B3A46CC0E00BD66D5B2D92B14A708098207C092B45351778E984 -E75DCC4AF44F9774821AE9FD16F44B733C611D708BA56895FD42150EC39E3A86E7253C70 -480114E55C14AB9F448CDE802540B710B1B22C0BF0CF557FE300A2BA25A0D841084A0178 -338EAE9D3DD9B19B062C76015CD0CE257D80DFDDF86C52FD7BDC4648EDF57FE1DD48C1C9 -AE6A3D17FC3CA05716E302BDF2F219B52E16CA97E63ACF67D27EBEC25BED0450B057D378 -9545B823DDCB91E9162D0B8BA526A918BA140A99E32287165394D51499E3CE10F75C9881 -BB3E3E6734B5380623496697FF66123076CAD8648A11D710988ABE094F9A11F4645E399B -91444EF95F0317E07B38A3D6FDA2241425A175F8495D25FA347425E419A78BFC62D17F92 -888986182D3DD448C236B84F46C7100EC23F321E73BF1839EF3500A0B147DA4B93CAB290 -CDEA0EC5567AD07078D426A98601D292966C172EEBCF61258B805CE42DEDCBF73995B8E1 -6580EE97FF610B938FCBC6D2DCC05D59E5D9F3BB90981F92C4545DEE34794CBD60FDCDFD -80449225D216246049948AF7B161D509D34F457F210116D1BDB10AFF53AEA6B51A49FB22 -FDF56471F610550D3133616E184B7D06539032DD560C4B5B54859C4232781326ADDF91C0 -98BFDC7B24A57BC4E69E97707CEA01F58D0E5B72919B202EB8852561D37FA219DE667986 -23D6CD0535C2CD0F642238D80452DF1482B1197076EA7CCDFC3C336B0FC883DE2FABB5DD -C80041A4104E575BFD65B4EED3BF9CDBDD4B83BCFC7295392850F8EB50C4D85DCF6AECB5 -C88F6EA597966AC63872251EDBF270A94512187EE6483D272D50B5E4B7F4556EB9B474E3 -85DC8A6152FEAB40CA34CCA515302C6FF2E66C42E731673962D2FE5320D577A67AF1B02C -A3697EA85E771565B97A476E388A5DA358B8A1D30DF2EF680288F20E3F5BAF340B44B7EB -5E531E569896FDD63DA9AE424B0CC244D99A0256488922A394F2E31FAAA47D95D90BCB0E -83429ED543041F2B8635F3033122F4E114096D497F6D993541A6CD7A6747232B88A3593A -71DDC13689EBB077B3552C366A4685B48DB7E9A0102F02A1C1A31662568DD1D4D3D95D9D -B2C491A04534833CA789145A6570F4B6E8FEEB77A9E9240FA9820695380C4A231D61A58E -F20C07FB1CE230170387CFA28C408D3251ACE1216FF77CA0D54A35591822489C0CF393B2 -4C26623EBC3A3A9C8DBCC5779A2EB09A8EE6F1EF3D97C107F9BF10252698367A16D05E84 -E0B41817D06814D26FF79AA87661C7C2D5487DE11BE2E4DDD7C926834DF8532652AC8DC4 -43FDD086A256005BFCD9C4D9F05D0EE9650FCA24327400BB5FD44F183227F62720787691 -75AF9CF033C19D7B4D2D52FEF89DC3BA145A1CF750AC8AA71EB65FA16FCB377F0492736F -33A408D699FA3A9472D422751E333B368FAB32C05E959591C3977F0A9B94E0EAC792E1DB -BC609E1315D59901672AE9A5ED9381FFB2864EDBF657D8EC8FE580409B0C8AF08892C00D -DA1D2D32CB52611060BFBDADCC73B272936A150A03EC52B4AB5A196C28394154DDBB879F -627E656510322DAF03F018E917A40C6C70371658095B7A9CA96575E976DE9D2E3719BE63 -33CE53FA1B970455CC734181CBDF92969555C42909B590908F43C81FBE180F043FF8EE57 -965D3B28C0FEBEEB075B2DE3444B117F6836E12234670651230446DFD71133C169B9D743 -1B26A1E5B251B4E7A170133FF9B403D3F345213A67C80EA3F48E12A2B564B97E5E570651 -070EA250C155D9F7F50D95BF852F1A337B152A2167BBA4F2E1FD348DEA9AC2B2DB341B06 -07422BAE29EFE1F7E1CC7EF9EB9C1CE879C0BC2B4D3E3BB126879C4BCC0F9219D89064CB -BB943487ADAD2E7A5E6A72FAC3C2002226C24462D7CAE7ABD0687F785028CC6E3C4F1026 -A994669C2320444BC35BC6CF8239FD0A4B4C663EEADF9FE60ED2E4ADD276680C5C84488E -2956D72DDD2A49BBC3367EB742CC9D69AE615CE4693636373743DE1FC06429C5D5F19E42 -A6285DF5394041362F5F43F219977A7B4101E8A3EF45502DD8E702D677423271333664ED -727310F0A2F12CB90332228BDA42FF040CA6359948EBBFEA768FE2E85F344E38A48A21DB -04C8C47CFC95B14DB8ADEA6A4994A366E8D46A4A1453880390130A157DA8B5D14B250893 -C3DDE306C62E466968F1EBFF0AB0224AC7F87B8746B816EC02F7FB710176EC2104662591 -4D2E5083ED6DDD42EB82AE75EFCA4B4017E00B80CF11CF347CF1D9A1F43C5A7E16A47CE1 -CF113A4ED121F109F763DE14B756E396C59E9412CB166FDED494706C7B9BB806387921A4 -C4A1FA6556D82F252E69C479D4314252A146F14A310B0D3861FAA13FBAEDABDE8B238342 -897C50E88A951A7C63670040DC49BEEC93CE42819BC79A5C974E968E523CDFF701B6A0C2 -C1E00D0A2C889BC270C0A94A58B8F44AE45AE3ACF02357A1A78AFE2E09755E0E48BE6221 -A06C91800234AE2E2687049E0372C8B0B2573BA6F044FB9827C1D6DD90234D91CC1BF4CC -FBF14E163DA400E2BE334A4D806B3A934CB6ED7674DE6267B3BA9BF4820C4D41FF661E7D -10E0EB3F7358BAD6C01B7E1EB1DEF5996678548E589A2FB993126E55BCD6BC1BB1F0D4C8 -1B1088A7688BF682E63D54F55CAF1C2EFA84B79974439C4F90B8D05DC7C300D450BFCA2C -240CE0D01156FF5EEA35C9542374BEEFFBFFB332E14526213ECF605DA61DDDE45AEED1B5 -C29217566ABCD452A266C8668369B6C4871FED4D830735A947A15BF41F0210235476E83B -EE843F80375DC95FD0D3D0480202033BCD2D83DEA1B0DBECB3D55EA6AFB96F5B6FC48B6A -7C1308346583BADC3B7AA668DD819F81E82747226FB67162B8F921790663FD7C0F7DBE63 -BFA878DA1434AE325EC02D786FECEC94696863A3235D048E80BD57857B7F0E6B84C2067D -F04AD7AF6AF06195B4FCD01D3257480979D79740D4A5EF82D2D5F6359890B1BDA818B8B7 -43620F6844689B7005B608ACC102444067FC7752EE4FCCCF24321872ED9437AF8D263AB4 -123213968A9801D2F9E902D540FBB430BFDE25C15A8185B42BBE510DF4E9F456286F28AD -DBEA5596EBDD910C7E375DD40500995C867C2E5BF9AAF54E57E730C3C1F199E78ADEA406 -8AF853A645C0DEDEC05C825DF25511FD40B0B6761547BB986AF1E878F905723580D7490D -026D2D7A49A2E553010593189A0980DFDB18122405110422806CE79E7088487F7FC5C80D -33217362356D42CCFFC9F51FC103A68A60E4CBFEEF0852C998FDF4A3CEED447A2D77A9D1 -16F88B6ED092FA4D25C59E731A03ECE98247E96B055EB4176B8BA5F795E6EE92F8DB0446 -540207D9FD913E00D20683128E3B99F3EFA0ABBB945606B30E0CAB0EB6B91D30EC381184 -E5046DD2DAD0A4B5D3C6ECCCFF402C1BF5B42E7AC1EB818BC76B92BDE97DB485A9E4660C -DC3F409129B5BD00E573E2B4DFE2E0113E288974DBF9AC6BEFE9CA8DD0F73C8443C906CC -4D21BC9ADFF2E9ACEFEF101A1087EC168EB9EDD54D55CF072F4DAADA363C28D9E2FE52EB -2A58F4BE72A494F370575246965A4C4670A7F4B47F118FE5BC17ADF7DDAA469EFD6A13D9 -8A148B02700D4D374EFA01E2C6502E6BE36F2FC25CFF1D6A4695110595BD358705674162 -54D33C3DDCBC891265EC7F0FC06BD7BDF70D7000328062F889C4BE68F4FAF0D2C2F5D8B5 -C61C40A3134433C222071270F466D9EEFAC22119C67A9EB2F626DF8CF62F028ED74CF733 -1181D642532801BFB127A1946362F2F8BC33B8651A565ABA0226943CA88FAA9F0D8CAD31 -7B7D2B0B0A5D10907355FEBAA4BFC717BBC99A604178B897CC8CD98A14531E9742FDF11F -8D17D2ED67DE68CF3E2DBC0FF6A23C876F3101DF942314DF0D06160643C4096C65B90E15 -4E2D0CC44AE46932068856CE3EBD03D8A74EE5BBFF74CCC54F0E1D3EB0756C29923686DA -2410B414A5CD43855C82BDAB7AE111E284FA77BACBCD412A438F59FA4006C11F4B45C502 -24F939A12289F846A43E1A5EF39DED94922AF63537D12EAE8E4641D5434BFD058FBF163E -586556CB1E13D15A5487091D9BD004C556CD533A25E40F97AEFB4AFA5A2079C87701E65C -96405AF89D0D7BB41FEC6C4AE2834F99B1426B47EEA08FF81B13AD5738DCF2013E45FF93 -38652EA8A36B8690ACF0997A1CC2501219AFBFCEEB79ADF018B5A55C8734924D5F6EA575 -F0DE17E3BB3AB11F8930DA1A8F3CACD9A0452145BA4F00BCBF072826F1B6F1B9FFEA2736 -7319B85F39FFA7EBA15305A338452211E2D011E566B2B5A822E478BE2852853A1A8D1270 -C9E5E6B80959DC2C1FA70F62765CB50154AE0FAABAF9BC997BFC4C54F63D4D2B948FAA26 -0ABAC11CF0677CA044B1783FB87D31B1960CB0B21024AD08580B0CD6BC4BE22BF8A144D9 -88063037F1D2F17552A15D47D21CFE1B88298BC7F715555783299A9FDD4D131F1645D195 -E6AC8EC0BBD1827548A0F971080AF1DC214CC3720969B735EB0858DEB89821FCBD047BEA -1F1F8B5F27C98785342D56C145D03A0469D92E932ADBF560D35D555893B0D2F795918DDB -D65386906E232A3545C916A9AA57403E5244686BD99006CBDA3E93BF9A22A2F172B58147 -4480A90190018CE07634573D67C93211A9577AAC8799CFE6FED8F9274D45ADA841A66CE1 -EB00BB0330615CF756DDF0D6B9DA2B59480E63F0A40DC2E635EBAE9C5ED7283188B89551 -96C155259DB91835ED78A3D3BF07EAF6CB3B3CF6F4C0633C764D8B76592FDE07B62D7DF6 -F5D16F26EAC7DD91E4296442225A5A02A2990B222BB8A1239B38F83A807F828683935682 -51A567B9F68558885FD32E58C4B22D467DC494F20A3428F68A18F0037E8CF4837FDD62D6 -EA3CB73E8ECDA81132256DD09F7CDE0CDCDBA85DF239F2671E0295031A3184F7A31F5F05 -A29A40534BB0E02C99089977172A469A12D331448D690EFA0E05099A960ECC3D9DCC4BE3 -1447F5D77CF9F59078307213D6666E6D9567AD8A341A10C93A6EE3C726FA3A730835E134 -C83E47BBFFB68A5B8ACA88414800FA1971F0B7162DF5EA90BCBDEC7B2C2916F4EB39FED7 -98DCE6D49E8D36A188A18596C02FA8F8B5B1C9C67BB8BB1369EC2FE51BD0E554F52517BD -5736CB8B581C4B083F891903EEC740B3F52F404BE51F26FBB90739620719C528DC56AA6F -185DE3A0145225AAF56C7B8B510F0B6C5BCE56F69DFC3AB39C5A9A6110C54B0C014BFED6 -06808B965E8B4CE61BC3CBE66BCB6AB0C53457E2EF94EAA1B05A3B9C459542579FC7FD69 -043E9A4A79E6688CF835BD981FF5935E7111EC2B4FFDFE1E05825BC54C55A06D737E1BF0 -5F332D6B958078B4F3BB7FB1952960F35C28AC9DE3B8A5443650A22DBD69F43F1008543F -AD0ADAFE7A2D4CC1158F6DFE38D5ED78CEA0E8B742D86AF575C3DD05E07339D95A52E7D0 -8F28B53F42E0EF55E488782D6DAC953C2B46C759D7AB0FD9D521B996B4F492C762250AEA -0371EDF1A6C892CC2AAE5E8CF85C9532294A7598152455F1229296BA051DD83CDC08920A -E0CDCD29814EFBFCD435FB171DC21C75B6765E2FEE6EBC57941C984E05C107F0B696839C -E94FF8D337BF520AB53FCA1CA456E5404EC1F05F71725E8545FE4DF3E612FC6C14403108 -2EDD3E5150943EF21E845230ED91BB60C95CA91F1389F299667673221A8680DE65D12BDB -1AFB6C7BE73520179FEAB41FF62A57B14FDE16CDE460F4FEFA016A555445C78CE88DD0EE -A01D49F22F4516E316BB4EB03E5C012291EA5A5314ADD2D16645075E84E50A11F7ADE384 -592EA0A2AFD06BF19D2AC55F9C7EF98FFE32747DBB496FE6A61F01BBF83E0AB9CAACBBA3 -3598EC42C422EE412EF1B1F1704E7E59F28C354F9F6F5B64E780EEE47370607120870DE6 -2623F01C4F8A46059E4DCDF4CCF5775F157DD756D45AE5AA6BD5EB415B04559796AB1270 -3CBAC585D4DE40AA03CF8DA7BA33D863EFAA0F7B990316A7351D9A533E2AB6576024DE45 -176D6823F31DC55A0CC29B5BDCFEC6C75F5D11D67BDFF15D083CA9CB9DF28DF02AE258EC -5611ED8D721FE60910CA5484A9F5DF3449F85D7F9900C61F4FB43617446E5E74E1849977 -0A0B686EBE371582B0F8B9D811F40D7B01296DD6D3DADFEB2FCE5DA4D93F97B38251626E -D3C9350AA320EB926688474DBBA786DF88FE9BB502AC65937890DF9BF4E1F20197F3CD40 -9B2F7766078FABDA9C535FE03BE36DF70FF23BA71CB322A9A18A88CE6ED79AB299A0B707 -6E180B8F282CEDE8551094B7D2AD13360CDD68E0F4B8488324C0ACE44BB04EF246B02BED -49DFA83A9C5219E88FF327CC0599177FCB71819B2EF4758D1D95911FEA16A6C50ED66FC4 -6B478A4DA493651F59A1F637C656AA6F8B11102EE41C33730E4BF7F400E6947A4F1E153E -2460624E874EB6BA5FDE3C2026964483783E1767F6E8AA12F646F3C47410F0040DD1207C -56F29EE16D2DD32C0FD73894A44E87E656D3582E3D615C6053E1B7B70E64279D617A958C -265B6BD1DE5F706ADF911D83972D46F929331C5BDAB2DCC47D10BA4D62D5B246F99A19F1 -E884117F99304249E8A87C6E6FA5083DC0F9E97626DA3E16AE4ED909D1B7E3A911B99E7D -9808528039AB0641948F10D793A2AEBC4686BD895773F143559DCFDCD6C09D4C1630E454 -0F112093F70B4C76C5D97D28E6FC8DFE2B2322E000404218CE03458E9196B95E63CD625E -61C03D7A4271A6A4AD5CB055F113D7F10C69E4F282B9D6EC5A60A901ED1EE9BAB97FD40D -33184163AA17A3F8EE9CADB38F047772FC8D39E3BFC7C9F5D0A3A277F7BB73C27516363C -BB23E8B0224234F7FC63206B19687CE91EE596D7F8921A5C7FB1CB746511BC9AEF5B6B74 -45CE95D7B58443C4FB4DCAB1F6819B94336058A708F936D38860AED70500373A4CC6A1CE -10F2BEF120E18CB10EF236457BD1529A5C6C2DBCBFB85F70F7DBDFCF25B9485E92C02108 -88CD2DD84215188B778BF35BF1381779ECC36974BCCBBC37D7999EDB9EC98C92D7C8BB3F -798BBEBDD852E320E3540C46C0371AF1CCC1F59D9C78A92F710C28A2B9707C8567A9AAE1 -1642EB8BFF1E9CE99B30A784DEAF11210C44EA275F137EBE69C197039E9D35A8E76C799A -E73B0D65EE4D1FD59E0E8B32030B6B4CE02E698F7090205E7B466C985ADEADB18CBCE64E -5074D90C4764823413CDA39DC16CE421D60F485FACA831FDC4EF6204894EB5B108734F3B -48E6AF64C0BF82E71AEC055DBD588D62AB4585555FCCF3982204397FB4BB4602B313EDB0 -B746734B8E6AF4FB59CA0457D45F6CA15966C3ADB050F7B83D75D43B2D54E8CF9604494B -7C712E0263E7154B31C205F51F1EFAE4FFBFCD5F522FD9E85AD6C6DEC091D7CD445F56F4 -A6D087280B252E7901A34EB4BA00206E4EDFD63FBDA45A17DFB1873BF8B6E82B4FCF7AB3 -CC1099EDE08FAE748854C9E468C9C8B8FFF239E366B4E8FC76048B0638F7FBB9DB80E711 -91F51D4CA50ABB65E361BE32D12605B10C8ACDCF2101D66928C9D95099C296B33651B44A -BF0EC9C0B7A6B686AC630264897CD3274A1E87AA8FD7182A124ACCE7CAFE4887E06A7B34 -FC7DF7973AEE69B8381047E2D254375C46BEBA1730FCC6FE4D6564DA9EA963D0B7D45475 -FBBB54BB12F389AE979D1F36E4FAE0EC7A1B2B7B86ECA42C85268E0953A461C8EE02C407 -FC387141C52866DB49D8BFCC065FD264E5F57423E3DBDF1270D2BB7DA6A860D22722E052 -3489A3A0B5F0E7E46DCBABBD89D3E4112A031B37576D35B95452B25B5CD04E18EF24FB0B -98A00B549599F3E924EBFC4FAEFCE504A1877F69375FFE7E9E7D2EE82CB2C80A87630A98 -88F13C26E568F5AF98F6D30A7C3E20695AFA9B2809FD646A8334AAC86B1020FE968085A5 -70ABD597C472F693F3EDCD5E88767D23293C1F64BA94029DA5921C251FBECA22F1BA47DA -142810A60CC9090E7996F3B09423D4D850C83F47B497E4C17718020B0DB9915933FD016A -D32B50CD62E6E20BC09646093ED3BA9F9D0AB09F5B6B01F69CC8F706B3CC3828B7794A67 -3F2C3CAD3A2EF13171C65111A9D34F0FBEA00FCD22C509FDD913C7DC144618BD743B3639 -1E4694442AA86AECC639CB1A857DEBB2D5DBBAC329C4E1AE4F095EBD6259D0EDC896A818 -829311503650962679D627D060C51C4A78E80BF764C7DF2121896E0B02E74B9E65CA2CD5 -5A6ABA7884C961B474FD4AB32172A6E070B29FBFBB424417D6D1F89F6A8BFCC880C82C9B -7C4F23739259076A57B3BEA79878839E3C0DA5FBC47A52B81724DBD303C58B027F1F1D43 -2DFE420EA7C773BC0884909AD03F7793F40878A46813EA207D855FD8D397DAE056F89394 -602DCB1174532DEDAA96C5907FB020BDB735AFEF6896EB193CB16A56A3274398A20A503D -B1B66729D094A21DD45E12511715FC962E0F3238630954BA513374FBCE28737B80CEF5B9 -802097BA8D3BF8BF5315838C014B08D9BBF849EB92459D04D0B735E487858E333E140CDF -71A6B463EBEFF3A86A5E1AB29902A14DB4C72DD9FDECB05F2EECDCC4314A600D6724FE39 -7478CFCC6478622A8441B88BBFF9AACE6FE02E7B96B09BAC4B90A65F04AA6126304339D7 -E450C24922FF6F3027FB0F6AE9C19BF3C633708255E1E9F06B8245485273A72DB47FF9F5 -E5AB05B1D8518691885AFB8DD3350D9305C4DB91FB120F666DEAC0AE0C64EB19106F386E -E8A848CBCC9091EC8FA9004353981D5C214D920A07B439E78EF98628E1C0CF014D54F271 -349676D7BB0E41418A67DB24F36B3D8953A73D18E95DA0645666B485DA0061B2D49480BD -C081AE8CE6C696BB8A7224E933FAECAEA2C09551F961556F7D1314A869D1E698DC887BFD -F0E57FE8459FB5B1EABC88F50FB6B3BE5B6DEED96854201D97A6A199F4C5E0929762832B -E47A897217131F32718E2FE87A2A5CAF8594242C504CF3C86C73B68C09B05DC02F428941 -F441110CEC6283 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -{restore}if diff --git a/fonts/Monospace-BoldOblique b/fonts/Monospace-BoldOblique deleted file mode 100644 index 880b52fb0..000000000 --- a/fonts/Monospace-BoldOblique +++ /dev/null @@ -1,2445 +0,0 @@ -%!PS-AdobeFont-1.0: Monospace-BoldOblique 1.15 -%%DocumentSuppliedResources: font Monospace-BoldOblique -%%Title: Monospace-BoldOblique -%Version: 1.15 -%%CreationDate: Thu Oct 27 10:50:21 2005 -%%Creator: mike -%Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. -%Copyright: DejaVu changes are in public domain - -% Generated by FontForge 20051018 (http://fontforge.sf.net/) -%%EndComments - -FontDirectory/Monospace-BoldOblique known{/Monospace-BoldOblique findfont dup/UniqueID known{dup -/UniqueID get 4092906 eq exch/FontType get 1 eq and}{pop false}ifelse -{save true}{false}ifelse}{false}ifelse -11 dict begin -/FontType 1 def -/FontMatrix [0.000488281 0 0 0.000488281 0 0 ]readonly def -/FontName /Monospace-BoldOblique def -/FontBBox {-173 -1034 1654 2157 }readonly def -/UniqueID 4092906 def -/PaintType 0 def -/FontInfo 11 dict dup begin - /version (1.15) readonly def - /Notice (Copyright \050c\051 2003 by Bitstream, Inc. All Rights Reserved.\012DejaVu changes are in public domain\012) readonly def -% Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. -% DejaVu changes are in public domain - /FullName (Monospace Bold Oblique) readonly def - /FamilyName (Monospace) readonly def - /Weight (Bold) readonly def - /FSType 0 def - /ItalicAngle -11 def - /isFixedPitch true def - /UnderlinePosition -221 def - /UnderlineThickness 246 def - /ascent 1556 def -end readonly def -/Encoding 256 array - 0 1 255 { 1 index exch /.notdef put} for -dup 32/space put -dup 33/exclam put -dup 34/quotedbl put -dup 35/numbersign put -dup 36/dollar put -dup 37/percent put -dup 38/ampersand put -dup 39/quotesingle put -dup 40/parenleft put -dup 41/parenright put -dup 42/asterisk put -dup 43/plus put -dup 44/comma put -dup 45/hyphen put -dup 46/period put -dup 47/slash put -dup 48/zero put -dup 49/one put -dup 50/two put -dup 51/three put -dup 52/four put -dup 53/five put -dup 54/six put -dup 55/seven put -dup 56/eight put -dup 57/nine put -dup 58/colon put -dup 59/semicolon put -dup 60/less put -dup 61/equal put -dup 62/greater put -dup 63/question put -dup 64/at put -dup 65/A put -dup 66/B put -dup 67/C put -dup 68/D put -dup 69/E put -dup 70/F put -dup 71/G put -dup 72/H put -dup 73/I put -dup 74/J put -dup 75/K put -dup 76/L put -dup 77/M put -dup 78/N put -dup 79/O put -dup 80/P put -dup 81/Q put -dup 82/R put -dup 83/S put -dup 84/T put -dup 85/U put -dup 86/V put -dup 87/W put -dup 88/X put -dup 89/Y put -dup 90/Z put -dup 91/bracketleft put -dup 92/backslash put -dup 93/bracketright put -dup 94/asciicircum put -dup 95/underscore put -dup 96/grave put -dup 97/a put -dup 98/b put -dup 99/c put -dup 100/d put -dup 101/e put -dup 102/f put -dup 103/g put -dup 104/h put -dup 105/i put -dup 106/j put -dup 107/k put -dup 108/l put -dup 109/m put -dup 110/n put -dup 111/o put -dup 112/p put -dup 113/q put -dup 114/r put -dup 115/s put -dup 116/t put -dup 117/u put -dup 118/v put -dup 119/w put -dup 120/x put -dup 121/y put -dup 122/z put -dup 123/braceleft put -dup 124/bar put -dup 125/braceright put -dup 126/asciitilde put -dup 160/nonbreakingspace put -dup 161/exclamdown put -dup 162/cent put -dup 163/sterling put -dup 164/currency put -dup 165/yen put -dup 166/brokenbar put -dup 167/section put -dup 168/dieresis put -dup 169/copyright put -dup 170/ordfeminine put -dup 171/guillemotleft put -dup 172/logicalnot put -dup 173/sfthyphen put -dup 174/registered put -dup 175/macron put -dup 176/degree put -dup 177/plusminus put -dup 178/twosuperior put -dup 179/threesuperior put -dup 180/acute put -dup 181/mu put -dup 182/paragraph put -dup 183/periodcentered put -dup 184/cedilla put -dup 185/onesuperior put -dup 186/ordmasculine put -dup 187/guillemotright put -dup 188/onequarter put -dup 189/onehalf put -dup 190/threequarters put -dup 191/questiondown put -dup 192/Agrave put -dup 193/Aacute put -dup 194/Acircumflex put -dup 195/Atilde put -dup 196/Adieresis put -dup 197/Aring put -dup 198/AE put -dup 199/Ccedilla put -dup 200/Egrave put -dup 201/Eacute put -dup 202/Ecircumflex put -dup 203/Edieresis put -dup 204/Igrave put -dup 205/Iacute put -dup 206/Icircumflex put -dup 207/Idieresis put -dup 208/Eth put -dup 209/Ntilde put -dup 210/Ograve put -dup 211/Oacute put -dup 212/Ocircumflex put -dup 213/Otilde put -dup 214/Odieresis put -dup 215/multiply put -dup 216/Oslash put -dup 217/Ugrave put -dup 218/Uacute put -dup 219/Ucircumflex put -dup 220/Udieresis put -dup 221/Yacute put -dup 222/Thorn put -dup 223/germandbls put -dup 224/agrave put -dup 225/aacute put -dup 226/acircumflex put -dup 227/atilde put -dup 228/adieresis put -dup 229/aring put -dup 230/ae put -dup 231/ccedilla put -dup 232/egrave put -dup 233/eacute put -dup 234/ecircumflex put -dup 235/edieresis put -dup 236/igrave put -dup 237/iacute put -dup 238/icircumflex put -dup 239/idieresis put -dup 240/eth put -dup 241/ntilde put -dup 242/ograve put -dup 243/oacute put -dup 244/ocircumflex put -dup 245/otilde put -dup 246/odieresis put -dup 247/divide put -dup 248/oslash put -dup 249/ugrave put -dup 250/uacute put -dup 251/ucircumflex put -dup 252/udieresis put -dup 253/yacute put -dup 254/thorn put -dup 255/ydieresis put -readonly def -currentdict end -currentfile eexec -1CED864D422F76FD8FAEF6132F502482A3D8B4A45438351BEF76DE83DDF4E51528714B6A -2E0891A07E6A4C4AF06631204074926585455A5677B5DB36647E8D4B74F135293000FE37 -CEAC7E5D7112AD08238B10F0A7E8C6B22250EC0C3AE0CEC1B5D58D6CE79A5C9E8AA78533 -80CBA7928F215BFBAB9974AFFD4EAE72E2F13FA51DBB826B3345FF4EFECC42059C923D3D -744770EB5214390157686984CE97B7A323A282FB3942AC23170668648757127D1F629DE9 -F47CC4D8B96EB65B46A5F601947908C6623ED3C619000369C9E67729C539451F62FC5580 -9EE2C0DEDB3928CC0FDD6D955E88BDD03D1ACF344F28493FCB53D4FC1B863FA25220FE1A -1481C7750500555A9BD2D8D14147C9F8D44BF71EF40F09B0A188725D6B400C688671D7B5 -547DF767FF1075536B17074CB44E973ABC27A9494A2D5880537C8D53A2C7262E53EB25FF -C4C00E380FF2F8B0A0D33A03BD016174D197257B13A27D23E9EFE76CC0F6D8975A0015DA -DA093AA1B08F2BD290040DBD6674FF79F4718DA59796045B4D8091C39F6B407D5F2715C4 -E5CCF1F7A8909DC995C81CB305B02836E96488ABED0835D20FBD3507AEA8C9B51EB85BC7 -148CB611417A4A894FEB958C0CFC59F6359567D6A13A0D01A7AC80E9918450DE949D19BE -31C7FFE9CCB6A9980AC3CFE03409367CCF926A75F8CAF8C2BCE07AE51FA505E0EAEDB20C -4B530DFF7DABB79822CCAB90A5366E32840749B94EF996104D44B3E13E3EDA856C4CFD10 -3CE65A33CE8A22AFF27E081A93AEC929F7766C0F1F8C8A5414D3BB4C46F8E791D02C1710 -95FFE94019D62F166E3EDBD88B350E8211CFC504E546F14016DA01DFF478C25015A6530B -8D38CA3F7AF4DB3B8959EACC030207E8239C17E351E737F58960875256AE6BF5094C042B -F753341EDA79F533F602F673B803394FA140B5F9E0768413A9EA96961CA0002036751C33 -FEFB66DC4FF30585349AF7C9924B9C94E20DD44381028847816BE17FA4D554B30A78AF24 -11318819B1553C659F9866EAE2C775A9E06BB5E90AF8B32B1A7BB290EFFA41F5B5033C85 -401D3B85F125D61EE0B245E0FF52B1F46CA409A86A88A8E40CF38BB9940168BF936734B1 -F45EF8AFE5BDA9F613972D9F61EF5FE3F8D4D19690C2AFC60C3FC4681906BD2570945EC1 -8B6161A8A960546C23964E2B005EB85B4146C5EA93313E99557B8820C6690E945AE88661 -AAB10C0D47BD67CC00C03BA82A04407CD9B692351FBA25E75E4486A21D9A0542762D5A64 -F8B1B879A11EBFBCE426F221372C7DA133D7CC2B2C0F9E6F269B3DDD14A4167F184F76BB -F0A6AE68F88340051B93CCAC09BBCE3A674F684ADC4F2F5D121A3CDA013FD031637EADC3 -36D6EFF295A86B54867FCFE1F05BF5A73C737040BD3B1A0E924193B83B6BB378B2453D9A -A3D53B864E1EFA1822D4D2EAE2B310A42389ABF90F4D439E0DC7CF34E8B90439EE25C677 -00F9DD5CBFC6DD5681E3C79F26089F6D569E0F07CDBA2881D812766439FFC0894C0E191E -054AFA67FC1B1AAC7ACDC5B6D710F1D0D7D6EA32937FBD67CA71A1D5C5EF59A3C0D833C4 -5F78B126A88A81E73971B7E12AF16C4B23086F282FB309755696851DB9685FA9564AD878 -BB22CCFFF759CA65A594FFC2FAD61F774BB8450A09B08631B1E808E267E855F003A5B951 -D8B4BB325401E199F57345709782E2959757EAB5BE7AD6B5BFF17014E3A1A8382819CE75 -EAC4C68377FC032EC0D74603F25A2B1386F7FEEE876467D0DDEE2B2B9D03E25F32137D1B -4A8F90BBA322636C8571B6E215111579F95C346171C8BFE6777B081660877518D1B44917 -ECAEE307B68D51DF094AAD59DDA212747661AB31A9F31392C4EEDE462668675988A83172 -AD88BAFEEBBE500AFB2A4D9CDC985494CDB271AA0741C0709A2A4991B5EEC213F3BCF107 -E6EC214DEE85916ADD3440AA2A7D24F0645E254639EFD1AA093BAE93015A7FCCADE66817 -F4AFF9E5A10DC390AC33D707D8A8401F93D0318626FB23F8E6226B5C5230FAA6323C32AD -9F73A91ACC682BEF7AB3A99347316812A926E30DA8AD7CA702E52C73CC37D8A2F8D3D679 -D2F4F17419B85D061833B63DDCA501DB6E5FE81B5F8E601C59057D912CF9163D1DDB4237 -6D4CFAEDCF4E4F66600F71D7C31061A9846A0F153536DAD78AFC80AC89DFBB1CECE4D89A -DCC95F5E7E03A41A6BBDEAFB3372ACF32ED1D5DA6CF8A768812D69620806585686FF6658 -81AD1D1AB17E7282E6150A3EB40B400ECD78E202FA63A5508EC4D6FD78EC3998991D3829 -B4CAF3B7714AADF0AA04D5239F5BB40A7678938E493E6E58BA9AADAC797A8A7AFAF594E5 -82CE777C987C6E9B4EE421FD1E44B7C3DB349621789B8142C2773C049CD999E3BD26B634 -BC86CDCC6F930EAC04C71A25E8A2D1DE3539C8981723ABBFAF835B9615FA36A3D89E1502 -F46C09FE21AD93811C447461729A4283E1C865419A5437973C07F830FB3645906DE1EF79 -5A4D0DA6079B77C3D0CC1D1581EB24BD9644CBE0FF57D58295D3C1529F95B61F21B4480C -9B1FDD14B20A776EE20F18FDB5A595778724CD68D237057519E58622DB09E9F86D8FDC28 -1F5FC5BDA84BBB46836244A7510737F6FC411F39FC9A6EB3FCB5D9541C7B3410F60AA52E -FF65CD9C4D20B21CC0E16A7DF3800DABF3475105AFAF14D2CBFE8C4A0CB98910441699B4 -B7419F0F91E4E7E68F6AE3640B4E82A52856FEC5D51863D14CC9A7E54DFC3F18EA6FE05B -DDA764A8FFB62408BA412567BCD78692A562E309C2DBCD900AC231610AB97A7701B98440 -5EAB031BD3922A9B29AA0A38BA410AC99CCA246E324FA59BF265924EB41343043C2D8CCB -FFE1F6EE81437B8C256179A5A69D7C0BAE4F13C59D7356B0FC9878D14CC9F1882E68EFB5 -0B324F590A76A19F01520AFE617A6ED645A9BBB0D4AEF69A01099C2F7F93382700E3C7C1 -2862E5289B66EAAB1DBE13802C29D11452A82968592995686EB09AC67B64CAC41E9177B1 -1A21741097ED55CB5F383DCE927C5EE5FCC13B261589586DCB03ACF7E74C67606A71E235 -A335469B97FDB6DA8613437685ECE63BED792266DB50ECAFBF082DEFE04803CCCAC08B1F -47D3EEE82D635A9F97975EFD80A316371ADF86031250077B1CC0F403845FAA306ECCAC14 -A194E85663252D9FAEA449B2A2AC2C76EF828F9EEA8556CA4057EE0BEF356C1DCC76308F -05CD254A737EAFDF2912E74C38C3617EDAE3969A03B01AB3254C909B93979E6226E20D48 -69B44FE0F9D8002A02ED206544DD099567DDA0489BD957DC14818C7CC1264D405BCC9E9D -A31BA99C5A695E106794694B7FF847497FC8A7E961C57CE3959D71253007B8C2A6733FCC -B6E43863F782DC8D37C60A226D46AFB6176C9507C7837C1DD2E23559FA1377794CC32079 -90FD6E0EAB77096F8C4896081B5203495207EE8CFCE63AF48840778C1DE08A449953DF83 -D5EC0B82593EF1D059D2C5B9350F21AE58BAB03F57A4CCDD4D4CD8CAF475E0315CA8612A -C3E66CC597DFD5F4F53BC6788B84C1E2E8A8AD02FEE9D9D5F7471508D7E3F447F55EB1D9 -D54EE8207131F8FB5B2A394C0C08F35E8F93AC9E0D0F93A77C28F9FDE8990CAB8E3908FF -EB8DC0EFCC98F88315E0DA33B6C6B4B50B17661DE788C1A874BCD2407C3047DC79DD6650 -B6908207965CB5BF7E7B83A7030D30D3799F406C9875E3CFA9A42401CA2C7115B1446472 -4D38382EAD16C042B8F2B352F6A9FC7FBC2E488BE6A2D97FBC1E643FE4CDA2097253798A -D26DDBD706E4CBC5661BD87E5E488960F643A960E9DE3891163276B377FF96D9D2E93B81 -17DEC91E5D3BA80B14A699C56E8F48DA2EE0A8DFC2C981B106C70E0766CC379D97653EE5 -465EED2B6FEE0C1CD2F4776D30E08EEAFCC427D6420F516F9F0CB3C060659C4CADAAAD94 -40B3FF65406F49F4174C2B0C606A3B03A8BE0F7767139539BDC38B93965ED44BE4E2A53A -149EE0D512D37958A9BC369452B6A121DFA0BAAEC6E9F6E00533AD6EF857E662C7FF4AF4 -5B7732E3C5A037E3A752682EBA6976330FF3FC1CC6271EB7B2024D2B00386A8A5737F052 -F98A223E309E457645E4D1C91B59E827C451D0CF32DC3B3D725BF5E325F9D2CC1994C319 -2B4C1D05BDCB87122F41D6F72A762FA45509074D76A32974ED953C5257F9EA335152E96C -1EAD2DFC8B7A85B5DDA1975EA400EF5DEA8F43C82EF663D3E5E122D4EB1C67E7E16CEA46 -F12D63DFECB85A84C7B77637FD330F89503DB4B342124ADE972AA14D81F492A5695225D4 -39A6EDB80209D1A49A7B393D00C1B5429DEE9D81EE2E7570A5E244E6457612C61E3869BD -772FB5CCCE59811D7CF516105765ACE6B68061B1B411FE664C84A767F66238231C96159A -21C3CBFEDF73F3B56A25264CD5FCFE91C36977A683B369716D6525FDC97E5D2828F26961 -292D8D5F7279E6C0C87F89827B1ED97187E3EB9E3ED021F23DF98790F5095C6063E144B5 -34FB190D15B1DED675CF8CF5C8FDA3434844ED1BB8E1D93F43D5829E6603AB001D423EA8 -279972CCF3AFB4BF776483A41C607AF581B1031E6DA4D716B7876D7785FA7DA4C74DE445 -33EE4B832B5B27154617AE7C5E32F4CDBEFA77290FE45D80011C0E7BF5BDE91A63708F0A -FAC6D6AFF5FE1EEB23C187EF486BE3E8EB042616A4763634BE5B4CF31417D6B7A807A3F3 -C3A6F6C285A7C7BD46AB63CA1F9BBE01A4E8E98E4CB44D2F26CCB99A85402F0A474E531D -9675475FA6F06A7347FD8FA30BFA67ADACCECA881CF703E2E15D8585A9EFE607E311922B -D9F0F8B7715021C9A90986D4C0E681F024CD13CD38A34DC8415FB96E6DEBA849D1CFD157 -181439E3C004ACF2D5E7C40F2366A89977662CC8D0C0CE03E77F77696871B7BCF85DEF44 -9F1DFD9A9B4F68B870A1ACEAB20CD407A27C5B75533A08CDDF6D0C97650EC5FD4AC0208E -07C59FA798DFD38FB86AF3E71503F76634DFB15F6323927C87AFDFA9178D71391DC51E76 -75BC787B749BB53926B0BA5FDCFFB241AE27B036C586CCCCFA0896D78A63578A986E329B -DA9F0E5EB0C5C1DEF06FD3667910600941AA707EF6EA9ACCF721C8DCF7760BFA32E3D5CB -86E79CF66DE28D80CFF83950238BA7EAF551FC3A8E4EE0302C840E7FA11D2F1BBBEA8EEE -94C313EB4B47975CFDB214B3134711BCD1F2E3ABDF11E591E9EABFF57C226CA83B3DBAE9 -DD3FC6F2C3C4777E9B5479A7E904D0E1F7D36CDFF6B32323E4218F8CFD5EF467865B2636 -81FFD990E58EA69595D4D86F2122C52BBFB43650FA8145B1B6AF095541123E31E99B3981 -A701C47091FA0C752499D2754E3D6A2E3322730CFA4EABB60807FC81AB82D6A4C81949EE -75B45A30EFAD61F1984993AB44AE604BB045120D01CCC85B0EB54302E05AF8B5FAAEF675 -62057457ED730857620073F014DB40BDA7E41941A3FCB28A9EB2DA319C3193A90030F0CC -0DE63B94B68E7548B709AE50267036A770646EF39C64B31DB865D12A60E502DB4EB11C5F -F784708E3F670FEBB1888296C3753D690EB6D9ED17216471CD3C4D5FB8F3F6DA866E326C -58E8E892A3E6BF60ACD586D6CC8A0C984EB030E4C5E1883B78C4A04ABACD295FA292830F -2884504E35363BF69D7B2F16E43F5B94CF2CA934185C684B1F87108B58C0FA15F75F48AA -A03892283FD1FAB239D5A09BFA310E59F2244FEF8481E1494A263EC2E3D4CC5ABAE4E37B -D73F74559FF9B32EC960E5689C3E86033F1D20210FC448143FEF0C77809CF789F6B8A55C -F383BE3D85B82DEDFE4DC4480C508325A5D28216C097BEF9893103004E551D0516E05B33 -1408028C881732A82151E3572C279972EE0DA66503B2A7A7E450F1A4866B9FD0215B7BA4 -84C0E5B95276E6FCC43896D4222EC7ED7CA5A4D873D0E80523DA60CFED59C07C7704072B -8D988611AB4CE42D6F85CF336CD7FBDB4FD1B13BEF8D97BE6355EFBFC2F53E7D59E257B0 -F71B620746A03C7D7C5B2CCE57177F16490074171B8DC509297CD5E43B498F86C2BCB119 -8C408DC0DDC294DD2253FFC5B03DA71DBF93E8BF8E2AB316D852369AF766C92CB2C82CFF -4F9247BF252C7712AE3978F76F78AD8C9002426B3736257E92CED2337961A693797AD3A7 -3138CA2489CC0E2AF826E4DDEBBB1C1C2F07C6B98C721A0519A2CA6DBF7AA6CC5C1184AA -E5A05AD35274696A805327F95544D71747E356D5C1B83431FD8CE05F0378CA6BAA36E7F6 -8CCDA7246655D8866D21E21E63B23440457B8863118B7080AA83318B32D45756D17AAF29 -20A7DCA29679F76FEF9C33D543E54460506CF9254E16656E033D7558A09FE3BDAB6A283F -0A881A67E3FF025A92F37748527EC24A7337AAA5B6254A5F95FEE2380125D05A25A9BA64 -4E60FBC4C25C2AAC69CDAC16ED0D79188DEFF61692D56DD91481D11F6B6AF7C86CE24BA3 -761E2380974ED69FEBECB22EED4C4E244C635C52E0B162A79C948592CC6BFDDBCA26C8AD -D9A35E6EDC3D659EAFDE4C4F430133C337461E97D2460BB6C8C2550A500433C5F96EC312 -3044426764FD9EA134359F414F59105A3705DB72BB3199B0CF9240979119D7E0FC27BC13 -849501B45F654ED63F93B6D74590BDA5A019A93A397A59E9B8A41E5F61219F5884390F12 -321281D125799406F9E234F1133BEECAF2EA304AB4C313C902214FB7D7993723772C39CB -0127B4E82830DE0B9A7D60FB452F70F90ED4CD2D2628A132816ADED99B9F355D20313F71 -1B0586F2A20C90705BBE628F2C9720534FE780FF3EC15DE762EDFC86ECE91A1A9E530C54 -56A887921523806EFAB6E9E397838087921945D0EFDAD8EAD7D27E3C24B4BCEF2C8B92C9 -06A725065BB42F0DE1653DF32C802EE2EC33EBE5FFB0470AE8AEAEF3119ECA6FA4728AF2 -CEED07C5F5024A27EB62475A8254E8DD444685EBC545BCEFF63FBC285208350AF5065CDB -466FBAB8540D8679430793A202CDB44EEA4082A36797F4308F037F64739247389189E303 -F31A1AF0C1780FD9AADC74528533AC6EEACE64E043E09EC5BE365D706FBCB09338597286 -30962CBE409AEBA4142B80C11603B4276DF35E15E62CD9478711D2CC8454561B687C2463 -9F68BBE2659168C72BF87743E758D33649ABDF6A7A4F42F625B2F83A4F141CFFF14A661C -9DA1E1D045F6891F82EF2E548E11497164235049BD3E3CE707E99874DFCF2E912DC431F3 -7F9894E3C7BA894BF1677FA0F392BA9FB652BC93D898501C5E6B4E20FA8AC7CE6FDC9AC1 -D86723440BF06D420E78F5B32BEE9BE5DCAE455DF6EF63128622CD90C39B46CB9EE4F45D -72A5EB1512EDCB4DB7220E561160941421D6860979A039B9E5D5706126A3D65BB8F46740 -2332E34E1709298538D20F5BFD178A2AF0391E93672D1BDACAA87CAD9C13873C98B3BFE1 -D28D783690420FC7A88F50241EDF64BCAC2B64E2B0BEF2B5C646318674EAEB1A15D431D2 -1678A73D2165F9A356E648D47FB6B7B5A889391E194BF80550962C1E996DDE28AEBB2529 -6508102B534332948DE46D92DEA56C8D19A08FAD37A646BE88C0B6178F72FFA422F33D81 -D5C4F69504B96A0CC6FF3F4525E0F78BF4F1B27D7970FF1B2F9703952C823C0E99BBA0E6 -63E413EDA3C4ED453176723D3B91683DA70365774570A5E36C40CEFAF29BB91948820395 -B60D780E7EFF9BF0C7496905628CD5084A34D852EC665C81497DDAE2D38594C8556937E3 -FC505A281C3B582A9288EBC36E39B8A1148AE6B29B265016DBBEE8DDA7B0E9C7EFF37B87 -2E95507CCD7FEF306906F05B7FF2387A2AD253178616AFC3BE56667A9B1875C81D960245 -54B5B785D210EB8285BCA0D3462CB40CC8A7310567AB5C1ACFCF279EDC74DFC8863A0441 -897C6FC2C12B875832FC9CEAEF57543C65AE75987834B1C2ED9FCB266A9B8703C2F53E69 -3375F4BAC0C609D464FC164426B01930746D0C66516E02FA50A95B742A7117DD03D67414 -D40A0E37D0C9340181B3D689A09898DA6B4EBF8B9D022DEF18DCBB58D2AAE351488A28DF -8C01110345C31A7CCF136CAC367B7609DDF27B64326B1A93D69677314EB62E1603C7E522 -420000203B5A9014148875FFB716CDA3B0EE8558AB8A864DF11BD863A640FFE835E0D469 -F1587F32E5F329C2BAD5B2604B58204B7667397F349D4A5EC7D40F53AC32B5D493F8128C -295165B31A382D32383E1B45C12992EA246D677319AF5C09E2F540411404949A9825F62B -5A306FDE4A93720B5067B3433353F3473E078A92F433D8A3E7CDB486131A4EFBA06065A2 -97C4706E1C0049557496AAB1BEA12A9B7BC411608EF41ED6F3EF7288494B9B5B9728066A -F99B7AFDCF6C245C06FAB5FC1175D9816EB90FF3116A4040CD614F18ED3339C5828BC121 -550D55A8595E4E679F37A744926179453C7E27190D64F3284656CE7C0D334A7420275903 -F9C0889248ACDA0D646C1885FE98F4E2E9DA8353852DCDDC9A36DD4359723FBDD1FC3334 -E4F49C07F30DED223A031BB54AC966DA65C9979D32FA1F3E9B2F46EE773891A4CD8A9BD4 -EF1AF2763F1BB5A3F9067317D9B5BAB7C622F974A3DA0934EBA78E353E220C29FECF3541 -528AC86A4EE2F73AC9D38FEE530D517C00CF43377D607942F881613C9BE20B59D48AE852 -31E81B23EC531003D7505E6584FF64CE940DBF2DB3742B142A20B1C8B6AA07D9538D4E16 -B70AD1D7C07EE5BA566876C92F548A643A158096AE000A8C6E1948D46AF2FE91AA3587D9 -F39E0315C506F739461E8B73ADFD18B15285A15A6161491B7CD85F80C1C7240E35BA7FFA -40876F878B468DF1B50EC980FBC4C8C62BB16DC81A38A21ED69CD2AEA4A56B093BA9FC57 -1EEF14D429176852D4CB3762BA789C741EFC39C26606E93BD525C2850E99822BE0DA5CA8 -CB749B6A650ABE24C3667428E8DB1C790ACF96E0D4B48441B019D29D85AAD46F3FC6BB14 -8DC9DFFA73A5C6B041C48A60616850C31D1F648757E4ADD8AC4B6EACAA801A88D3043842 -6352AC493AD6D01C83BAA2B645217F62E167B30964B8493EBE3D5370EDECA3F75193416A -C763EC9318BB4A8651D858AFD090692FE0F3114698F8F7E729C5F0C20BE9EEF9E12AFA46 -8B77608629D6E5D5269898206BD5BB4D6BB72D97A959E793984D26012E4C5BF4B3D70C7F -43AB875FBC17E8CD19E0E56EE012782E73DC04B62B806142265938B4FB9B366B109921E5 -353E29F046F530734E2E312E953708B41884E50A0B4A7D2BA9A8132BE0FCF7FF5E37F0AE -7FB48513B73D346FCD60996A2ABC8659A8E93CF9A0E1135BBC4A438E71813F2C217744EA -4D42E3DB03AE3038CD53F8FEDDCDEDBAE5C69D7EBF6DD4A41A1510A12358D5DA5F98AC07 -DFB9C648B5A72AC100480E34D38B897E9390E223C1E057FC09AA828D2524CFEB0B36E2F4 -794FF8D66E9734AF0559123BB70725C1B466E5230C8BEDB01B073C10F4011D7C0F6F2814 -60A76371335A96AD7469C7C7012A3AF9E1BF900B64384B1FB1804CEA27DC37DCBB64B8EF -98BC8179AF176295DAE271D686E87D3B9DC68C138FB4F7E2FDD5962B35DC6FD46DD24242 -CC30107200FE6F7730D33F274B6E532FE791EBA9AA79E4049D3E406C74CE152AE8FD1BAA -96920AB1EB2CCEF4D3E3F58DD499C8458CAEC9FE7F1E91DFB25BEFB7EC37E53EA6A524F0 -6D22F8403643F13063D750BFE2CC05C32380A92172F9071F5B526764B3B98EA9246387A6 -09DB489CCAC4B35B07FCF17955B42ACEE5656DD90B6746EB8D11A8C43AAD98AE1EFF5751 -F313B455A66D646D83D4055FEF177C96DDB064BB5E6F880935CF01D146A8C792757F0CCC -25F3FF24869BA74D81DD1572901F099C6FEEC45992B8DBB77043A0527F628ABEE2DAEE4B -EAE37E89071761307BFE39AFF657DAC83DBAD2C5F602917213DB0C5D4A9604F37DF37C3C -49FF2FF5CB143505FCCB025002F292789FA6690B573DF46E2DD0DCCAF4F5E4369075E359 -5B999C19872053E9930701583E88627BCA93A11BF22CC6F45F440CE2FD768CD93B64ECD5 -4916B0764C459A2689A72E147AE9E66995BF88E4EB0DE2B9067D0FBAAA1658620F4B8F3C -5B469F5543F02D4DCFFBA5071BBA25C7D025C1635C5F5E2F72A850C3E5F63978689C3D55 -4F139D38F8F28E79D6C96AD77F03BB29A928F5C81FCAB3406BB16B427E26DD0394634FB1 -1134F07F316FAAEC79F04BAA0F2CC7D8BE3E76805500A40DB647A3AB774DD011C6D2D65F -03B4F2A45079ECE8831C28A4EB68F462561CF76650BD8000FB8971FF4ABD066FFA0C1E74 -6D21E35ACDE42E376A6C6488602674C537CDCF5F163101D4AEE68F0688E16337454C4CC6 -07D2BF89342B8F38438B6E4F142BC7496E17F12F7D241FE0653E8F1AA12BF5E2F91F6886 -20870CC5794A56888CC248E076DBC743CAB5B43D784D9C576755750C79F3116BAF053ED6 -659D9F02375AF7D017CE1DD368481271F3959A5F84F49B1D0C796F547A5DF8551908E48B -65E05E8DA081C69CFC95FD9889148A5594C1C839EC62D9D12A20B39D4163C193843F829E -6FA88926D80FBA23988EE8A69544A3B6D72D7B87716A963B4A9498E11893F19395D7DC37 -83FBE1AEDCB3ED86AFF660A4D3E25FA7F21848C1A8815334D443269EB21DBD8794A744B9 -7C9BA089AE6D1F3AC68615EC11DC1A6FDE19B1D732BE963890C6DE995CB4184614B3741B -A64842BA7486D4774D90FF43CAD4A6D8AB1BA46E0EB7A8812BB1D973F13DB24A043124FE -60C9C97151A8B582BDA433FFA3B9F734EEA35F1B86674150A50F75543D3BA208743F0978 -C6532B70CF70FD58BAE0B3EF4157279C6E9CA885CD1CEB3694A286993A238AFD737D34E0 -585C5396C21991883B928672AF8E7060F41EB9D955C2F3BBF7378E52964BB318920778EF -A1EF42EA6D8C53508A79C1DE7D85E0C9A292B820EF3FCF714BB533423A60BA1D5A084A35 -CE918A6867A12FD0C3B3BFD50BB025AA2B304EA290544A2758FACF6BC401A0391B070F24 -C3777E8D5DD438F24CCC919DA93C2D548A2279FAD56A845F4CE6A9912A77B202DCC77F45 -4A3B3BA11741E32D2D1C4F824978A078FEE972A6646FCB3843C655DB8FC065D66434DF6E -F46BBA42413CA88FAA9F0B2FFD2D753D6B891D8A6B75AE8189123A0DB91B971C00300F5B -CFC2387EAF61C367C981BFF3F0BFB148227E9A7DE7299DE595B027970CCBB78B0C524CC1 -DA29C98A769081FF8B2EAD1D01A97FB975C084784F33109CE38732F4B7BC2E89E38F7C22 -7E295B9D644CCDF0C3F899203C33DEEA916EE508679BC12117140BF786E118733EF50B94 -E8547E486E9BEEA26D42565201E05B4F7354989423115D89BEB2F1596F2458D7F248483D -7E1B4E359D679B0F4E1B2C73EC3C37373AEDC75723340A07B4BB35C820D69B0550BFE3B4 -24B44BF1C627C21EA62F4D81E59AE4FF9EE17315064544BA9908A49492439F5F4CA58F3B -82923CD1045F2A43449ED3BC3FE872A89A470857B1B0FFEB942D08B41E80EA5CD66FACE9 -94559A4A143270F8CCC95D2880C2206E0BA08216A85966E084F061B13887EEE5D335DEF2 -B872D0816C8923B106A629E90ABBC2016A819DB95E63CD4C7B56FE64A917915FB3E9E16A -E1E74DC608F123DC565D6AA5839F8FCEDCA33258DD1F2471C787E8DEF9FB417D33225428 -874680419E9DBB9479530B26C4385F3FBA517222155729798049856C640C8745A7212A4B -E7473EEF586E548BDD5ABFB34EFABE513FF7EC3E28CBD7521C8AB00FC7162D85E7D9515D -E56C53B4BC1FF18CAD6DCDF28317F32F5DC5A2D9F3B15616165F15D7757A05C4A7187384 -1261A65046B57EEFDB367EE48468EB4BEBD7A67368DF534C217E3CFB16F15CA97B986922 -B078C7B76E634EAC55BC29D2376AE295D49C9916F562ADD7823E23EC90CBE7395919DBB4 -6B5E21E56F9A5B204BF0662F68C49E9303623D847763A1AC888D00D7ABCF34C3401D2EE1 -59005343EE15EFB9D5A5A1D330A8D5EB442A1BB47C523A18F4733B76373FA37AF4234363 -03EC4BED56C72AB6316966E2FCB2363FF2D4CA597E68BCC3FE3F139C272C7454B85E9FD9 -E23D8B6A38159E91B587C2B5F01D75817B75315B989E85D71E52CA4F13497F8A11C207D0 -89FD55A01D3251D7553AF6BD067A65158DAA766E24AF513B5711A0AB231087315A3D97C1 -2B5E790F4488FDA7EDCD02DBC2FCE692DB6D56F16BBA576687769642F0169DC57DFD04F2 -FF63861E7C03F841F84AD6C096A57520694E536A26A19D977AF1DA8793C7434764FC12B5 -16BBCB418F59C91ED4BE658224960F0DB0C95879A591F94DC288FD475A32079D31E6C41E -808FA8D9968817012620E7F30F14B2C1C0A5BE47E647832CF3334F68F4CA0CF338223262 -1A0478FA29D7D90CFCF76D83F39E44A4A878000A6A252BDECE5DA448EEEF21A63695323E -9C69DAD5E67438DE4F7B20B6B0A035751A39FFBD912F4EFA1713546D0156C53BD3F3BFB3 -AD47F99BA96E0234178A7E980830ABDC6E8C5CE38CF0CC56570447291D422D9ACA5CD12D -D4444402FE14825BA95670755422399CE362805AFD38C923358F5DB8BF1078C3FC6AB6CA -E3B057B7760CD16F2EFADE9EA0D40D6296E4BDEB33AD023109148BAEB6307D20AD3F8A77 -F5063C8319ECF4E56586C12982AB630890FFB2158AD97B5AFDEC586DE615E8304FCA1C52 -0369FEBC2C9EEE9068A6DEAC05706FE7E024E8254C4CE5C7404DE853DAEA209E7D067F88 -571FEF20076CF19D6CACD0D29B43E04E132D40C0FEC8FD4FA9A7621BD18215BE346A0F5F -C6DC05175753865A2D987B947FEDE67B23FE2D3635C357633D57C90C41923F889541D703 -9399785BAA6EF2ADBFA1940227CFEF4448BA652201223FAC24CF955B98087C4CA2664263 -BE8746DFC29FA5DEA877AF83897FE2B068B061B5C05871FA675C449654E6AEAD3A8F896A -A3588948271FB7F9CD953144CD070DEF9F6CF516C8AD51B47B87766087329889670AB278 -9CF4A2552225A1C997BEE8C3D9FE338609022837E306282A21867ADCD56FA9763D34A547 -8C7C7570B19D04D6164EADCE146E617C85A122E9265746EF9A929CD2A9E341095C7E646D -95D437FD5BE233E352B27BD9A19D0FAE0FF524257DCDA23C6D5AADF460EE7358D4490D7B -9DBD68A72EBDF1D266BC974D7F56D3C89850C024CEE759D09214108D6916D34B407E62AD -89B402AC74F74EF4C0E96569977627C9BB63B6C6F536D1A9CB279B636EDE90A804F32254 -DC167ACDEAF8778B164E36ED23DB890438AEB44487E3355E536835BE443021621DCA9E4C -8C39A54F4B7C28716329997C1B0BE5CB5FFFC7E99724D5D8C829783D156155639D79DBF1 -FDBF3082B62BCD5A3A04BDD2D94BAFB7BB997ED0A6524DBB227EFB29BD49A240CBF7644B -AFA665795211AA5735F435336C88EEE7972E94505873F66EA6657AE8A1480119EC9896EC -EB6C9250F5BE682193B4CF0C9CBAF146D2A61C895BE6518CDEEA1E460EA8119433685E51 -87CC18A77BAFB8C8C411EEE0CC655631E7ECFDCE6C59B397C9D568D0EAF9C6C540E508AD -3CEC230FFC326F1D9570218D51591C335D89BED38711EDDACE3FDB2F667B1107EB410283 -61F09D4082975C1EC481504D446B0284D017F96B94FA8875B08B11CE175C1CDE5D0CC9BC -93202FF57BACADCAE11ED701021E7720B88A78AFDDD6D71409E4DE4EB766970C87E3D900 -76EAD2457BD9D819B99CC7B0AE137CC3E018F0EC1450E91D2ED5BDB94D86BB77BA4F291D -8DC1443FDD001C7EB25B09208B92FA8EA31CD9D0A6DB0059C0B4643D898CD15CDDCB211B -885155CCF420E1C62B867A923C1071D1B4495FC4914D957D3208D4C0EE082C898D74A063 -2B60AB2D9657B9F510BBE6A2B9AC95D1192350183541E598FCD52B811F4543A1CF25A85C -12F9B4E51CDBB6067286D7B6919EE8BEE3B3B6C55BA28AF9E7604D13148000CC0C1F2619 -DA17AFD8CE1DFE099B7039FE71D8F6439F0E046C72F76E2CE69E7D787C9AD548563517CB -72B57FBE712261D00FEC755C108E9020548F4B49D805FF248370459EB32985DFF1BFAA2C -E0EE93D945744965FD6945525C176FD953B5394E521DA5CE283F147FE0A538C74F326BA6 -60D9721EC2A777B3F9047EEE5535159EDA109AB7CD240520DB61BD088FC45F4A0EB42614 -4AFFD87C7C1DF28DA381BA980D2B144708F7E471230DE98BB691D78F4D8A72B8CB519474 -9D392D4CCD79A03DDFB93F8A8163BD07FECD4851EAF615A49607385852857FCE90F3E499 -3056B7E80244FA21F488EFB3341095E684F428574DDAF149AA105863626B4952129CC819 -06D28957E534DDB5C030E718CE15C9561A04BF18A0F3785CA6ADBB5E2CA74C9166D95FC5 -8537624A9B0663B9D4684E64D1C17BA9DE128EBE66E057FD3CE3B5C7AD929640C7B26B71 -48E82F21A36B86664317A1412DA80BDF4C867852BE5E650B772F6DA9919F32B96860783A -AB469C9C88A0BA958D3986121F396C4D2183D104DB5D0382A846DF7D40E195182CD24C79 -01C1A9E556EB8CCDE58C61E44E7E80F37568AB5858AB86FBFD0711552F0CEBC1F4A4FB1A -0D55986B73B49D49911008851EFB478C9E93BE7A1AD4E10FE0222432F64329B0B1577D3C -E603C0B50AEF8FDB39804ECF0B566C2757DF12F65F3AEFEDCAD98A6B9DE485E0E96F3974 -FC7B196065C86992DE0BA6D4CF123A0CDCB94CEEFB8420916000F18B643DCD6A48FA32D9 -F5FA37D93CDFAA1BE4D95FB3D597CAF2EE196814A3B2E30A494C70EA193DF6647D96DF61 -BFCE1C5043899E5D33176B746ED3F555AA0AC6A6057C0D1B2D283C33142114CE60DE0811 -A8816D22DDE6BC1854B6C8930A5FA6496769388FCF338446838C3FD937C391CE06946181 -83051E106A440443F143CCD973B24B9E5D27E384853212CA4AE98C16B49A4A311A7759D3 -41B4497DCE2627B7D6E4FFF124EDC45B2573371C034707AAC8CD3A3F9547534422428B11 -6F840382D0D36802DB6386A9E73B4E3E4D3BBC0FD636A9F21967B1D550D727CB401598DE -144B1E04B617FBBDE509F475F0F2181C0F0C6C3F49228D0859269839C52FC2018CDEBA3B -51108199DDC78BD12E55B48B557E07797FC27BD87D41FE591E26F284B3E80C3B6B4C227F -25562C846B64143CA3864C1974777D33EB196C29B3391D658208C62B8D0679C5A2380B4C -95CC97B4192EECE50BB950FA8387505E858D309FB172A852DE81ADE4F7B7D1AACEBFE2AD -6F0106EDED3D7EED9F3827929B54C17364D62141CF95137DBC1EE377FAEC39147CB344B0 -94AFBA1B7A0A82D41E1FC63DAB168534255D02890B465F496A2625CB78E683DF3B64060F -255876747A24DDC01E0074211C23F8E28DBD6A6A0FE90C42A35983A92EC58F0383124C88 -9FB29494FE686DA32A5140BFB5E34941EE0A436BC5777AC41D188069BAC81E7E5A76CD21 -3D5312E317771DBE5EC3A6A3DDE1BF1176C051E8949CD8AEA5B12D67B8EF50C3ACB62E11 -73B9C04AAD76EF38A14E2974394080439A18C0194676434BF803672E115B12401E2DB0AC -7DB89D1D784AECCCE8B0B1541D3494A3DD019EEE3600C839B16070F7373244891AA199D4 -5AE86ECC513C403991885AFB8DFE85B21C3290DE9277B6BE583EDF324C3DEDE193B1D568 -9977EF532122FE8592BE4B649B773685A6BB1EEB7C9A7B00F123A4DD784F52A0D0A88FC1 -292AAC4EED21D1669C7BF24448A28405A6D958F702620DF8DEDCD899B7D88D9E8FA886E3 -87E91ED91318B7C0FB7353FBA22DB282D8AE1EDE64EFE64DD31D2CEC0712454C66502976 -2944EEDCB22AE9D3ADA5D9AA6D49004F5FB72CD0C6594D7D51F56FD7DD5FEF94B0CF6CBA -C823B03E69EB1F5A067C384EEE3021A4EC292CE7A87CE3A068B51DA6C9BC7A5293553DF3 -21226509A3F95ABC67B047D344BA7595A2D6210E748968EAB2999E24CC2041D1FEB1B7D7 -CCDB4FD8E57E1DB84C47F072CF15CB9425FEB8CEBA0C6A7B807CCD6A640C2DA23990BACF -69E414FDE169EE9DCF25B85463CFB6B1212A980DF38301DD90961CA8B53AC3E6EE9FF9E1 -54A3DCA66C6644F75164B3DEF201C66BE4D54F108A27689C79B0384070151567A306DC4F -61E6A5400E74429CA8F6CD35DE63EE5D81D30EB252BC34D99255BBDD7333A73531B4176F -104318299AE0FC04EE26B4B3B70C39AE5D96A968229113A6C9605483A55AAE4E1B4FE4ED -C3E61E7E416F905BFC6E7B8B982919BDE420725B76E9F3D2C993DF2A9A71B62202595AB0 -A15C1DFE629AECF2BB6362843CC82646B95C88BB074CBD23361008B6A575B19E27A49D26 -CEF1C27B1DC89A9CFA5725E8C886D376166E813DFEC08ADEE5A31660B1882C4115D12B40 -2D62CB4CB1C938D07FCF89E61B352551AC0B0E37837EAF6AC464C58A79068B2C7FD4FC89 -D471C914D867EE903B948B64B0AB8E3F80CB1A70260E84418014FFDC90F20B07E7DF7751 -17432E151473F92B8D7FC93827D2A1F1A204EAB90CC4E493F962FEBD84B816359F4088D6 -3B9B33B4A2CCFCA49AE19EAD91C9A6D3079C1E0A167C874C16741F3A0243A88E45D1F144 -32B31A286B1112DDAB9E816DF3BBFAA348C75305099E610EB9CAEEE570506483383F3681 -C287B3ECC3CB25835A3594604EDC661BEB1E4EFCEDAD9E4B6B09587C4C2810550FA9CB99 -CF035064646F9DFECF48B98DB27A51B26EDBF083A7EA8BC696DE161CC10301FCEAB82E94 -FA5FB6707DA84B83D8007435F44B216B36EF71DA5E490ADE62D61DB7802070FEBEE23F42 -4BBF0521F693EA29A40ABE744C030FB428C52A4CABD3D5E43283958CF3924290884E1198 -E50DEA4BDA72BB3CF95A1FFC8508139A48AECE8FED2704BB2EB8851E3A7132DCD145203C -CA826F0453C71FC2581AAB287947A14425D928D75307080488E1A30224D933A090857214 -029F05EAC8F5724F146A5E5E6392DA33465082CF2FA942F83BDC6A6870C0585B1339679C -8619069983A6FD382142C46F2D63E4B129A62216936FFDCEB97A1C5A9575CCA5A1C421C7 -600AF4CF4640A41F6584D73B5B3AE1A8D98DCBB4F3AF7D2E7316588C1B3BD6FB3E1FA8CC -EC6C8A857374D1383B0C9D1D314A10EDECF095E3A4069E79A94DD59FE72639FB02413D68 -4FEB3ED14BA97F733516C88771DEC6C4F7AAC18160D7F1C85916ED3F69CC6181574D0C2F -AF7D3E1EFA05EB5084F4F9BF4DFC6A4DA0985918622D90860C8838C5B8EE35B059733381 -EA94BF0FFCEA70FC4EF0AF2BB2B5FC4BAEF9D0CEA3E8516323451D868F723D01E0B78749 -4A69738FB836BFEE328A0A4541A03012D44B4830F174B7E35B0A25086DF34532C428E41C -83F0814F0F0D52021F42037B4DF2A6759DAD05A346E019A0633745439D835620555BBA5E -136A950B9BB234C1B3450E58CACDD658FFFD69B8E87D4EAE015F5427452AE657736DE2E0 -D66DFF9E03E20E37B377AE912B90DF242285B89610A55386CB1BFD83652E6BA1DCA7D1AC -A79748D0C07475ACFC652460785F6D82D1EB593DCBCFF0157856D5799635FA3E129FC93C -71A23376E61DDE5014964C4554743312A14FBF83FE99739D6C9C45EA465A4B55EFE80045 -D1021AFDDA6E5E13925F3F69A19741615D56991688E0A794DB1534BB43F010A76D4E29C4 -ECD9A16A90A7588DA1C31500FD55E32B2ABA623524B1E4BD40259F5C746EA160C13416E9 -167D2A5507D8D484427C0C5153E0865241A7BE0C298ACB22E5A2BB24AC7F78DB58415206 -F1C435587D4ED941AB7335D0CFA0528409704BC8FDA106CEFD32B77F1D6A02DEE4B05FE7 -3DF87C5D95533B4983A7FD9C3FD2A3C109F9D1719C372B01073C33C5CDA6E20F91EE2F2D -AC11D4B111E070DD059698CF18553C4A9A8707046A420F9BC6A6C208906987F2F5883E1F -8EF30E5A9F78BD73AE6C563EB04FD51AC339900528D76C28AE2913FC28C4CF2F585876DA -472A01FE1934645BA0AEFD5102C2F36362DDFF6EE3B4A12B63CA06698F06A0F25487EE6A -28CEEC421948B856D0CD999682277ACB8EB94DD7D88F18FED1725C3F0A9545795ACA2B6E -9C44687395B6EF3B76806A500019CB2A70C07E571100B7FCF486E0D14340DEF49740B1E9 -65ED400EABD0F69E310CBCAE8714030F5776CFDB057AB354CC2F1053F84EB8008F455DC3 -9870CEB793F611999E33B32E64572D46CEB3E64E0881CA70C576E2FC07AC9349EBF26BC5 -6D4E84EA3C835070D0C52A41DF388C8FFC979174084133CCD6639B616A4A20DB37F2A437 -0EF7E9F11A14D28B18076E8321FA194D9070D1D8226B2911595E3567C156BB1624F63635 -24D1F3634A08E48178D1486C48243DF9156D63B32901417626676305F6ECF88998B46F1B -50AF077104C052E9A20EAE6924DE1DDBDC99FE3305F4BF802ACD8DEBAAF15A3F8879553C -B1F4B3D7839D6989775507FAC15DF1B0DC95F554B16E0DF685CBDBB41E4A852CF7DC8A96 -8DA449DD5966EED3F7802A7B12A95CEC94DAF052CADC2CA2D84D7A8FD9BD74F90F47991C -4FB5C5D9342C445E963AF1CAF3E5DF7AA4D483C9F8EF73CFE48C6A25889E3B5B71CA4E4B -0FF97995BC83939E986AD7F6B379CAD7FD04C46234D8F85A234A878939110DEBDEAE85DC -636BE2A646F64D9661844FFEF6D22FB15F5B38C129DDF372C3198992CB6C378E8C306739 -012DD4B486CC3148BA4498EA8C0149E59D4AF1E7A0C00E0F94D58CA91C0C4261F459A4B4 -2F8791E72A634D734A3F5DF66AF91FA8ECD4671C67ADDFFD2E2FD30FCC3EFBF0AEBCE786 -DC44B9316B000A73773D1C354964AA129D82722BE5C666D5DAAC7A087F1BDDEBE3FB9AA4 -CA53FB8684F87577A264E607053D5E321108EE9B8CE78600F1986C9F2510C8AE368BF871 -8C8AD6E2864E257E40602D3107ADF63FD9DA46BCDBDB77B5164C43C9F1D0A1E2A50C7C0F -7BC6B45BEC60EAF2FC74022B8F0463F39CBCCF2B38318C6EB370B7CC45AFB3C1350F2A4B -48629916CFF777829AE2904FA90C19C748BFC921ED3985BB03DFEC5E9E250321B75723CD -1AAFE40242C54B182846A979E80024A9E72029A7205F13157E57C5F40951623EF59EE581 -20E1C1F1EC93870BCDF45A74A731DC31CB5EE13F8C568E4C80C7D9ECE815610F215AE88F -7157CBCE990172AE920EBED45161194EF998C933252599CA45540855A0E4FEA0866C2D41 -8DA00464051D7C0E2E5932D7D80921BD7F6997C9FC550BDD83433D959768C0E35E8750BA -0AD159CC296B98CA650724BF9693E410AB6106B9D423AA2EE6A47DD102EAC9B74D66858E -FFA99A6422C9B5B2D466E817E8ABCD4E953A9DF9CBBFFE5748E6F47DCC8831566DCA5EB7 -26B68A5C1C575340F5D034E15209E7A6C5A3284F3720A5C197111539E4D3F4B3392D8F4F -C400E3CC89544B440BFB258003A6B7EBE045D625BB3166DF4869F2D8CF74EB7303F0AC40 -93C24843BBFCD9A617E2C7BD53572F0B61DF1BCF677B5439B97483C973AE56D0E206FAFC -1082F9B2D0D5F900F6575BD6E11FD0863577F4CB1277C1D156711DFFA1012EF22725D52D -0136939EF40B0F661853385E154C8660C3C472618E7115D705CD837DFB7C0EC85F8B0A59 -DD1564378A8CF2B03768B9CC5AD7ECA0DDDD4D405B0DACD6D13468C833DE9DC82271BC80 -E4A6357569407FB09C289458B2ED792D01A9BBC25ECADAA8F2955811145BD3D681834C23 -28C5E3760EA15AA03D3E0C4E67191EFA44E4A4928089E1224BFB0E79B5BA440E036007D5 -32CB8560DD157D60A5A690894208C9FCA54F32FBBF9C9BCB8A3A9ADCFCF2BCA1564290E9 -832C9E79304A223F60B7B58245E65D598EFC1FA06847E1AAAEC8BB3ACB454AB5EEB9265B -04589BB8FCB5F87576703AA3594B688F5001053D34F17FAE60486EA07E6CBAE2C6358DA6 -AA1E68A556A1E2B1B2DAEC2302FE04241CA53BAB74E4EF219ABB868FD624B519C70EAB34 -B5A953F17AEB07E867B4317B48B2DAC162B6A9EBFFF4910FFD8A96BDF6E501030928E380 -A6277590835C01A704FAF9C32907990804D0A1F70529C09742422B48586C8762D5E8871A -F91527187537526FA52601116969BCF7C4FF8A22446A184E9CAC17AF709489FA39D372A6 -6C3D580B183D1AFBD6A21736DE9A09F2968AE69FB587F4FBF7BF281DA926F6F55DB0430B -B45CFEBC493195A1B98F68A514C64483E30F22A7DAD69FA38ABC4B51110560DF23517214 -081F999A3F1D415D8993C940BC40C481F77402B51E7573801DBE672A8739BE239923B996 -23B97992EE35B62734095822B8331F69EEF8BD26FE6A6FCC0F6524CE9BEEFBF40D70DCAC -49BCA97837DD526C105AE9624303C120407740601B1808D28F311B42B2EC20E1FDABFF13 -2DC42A1EA01827AC85F44F4E24C9B72BC9EC17361053BFEEA913CA872A24FCAD6415C77E -59FBC9182B6E931C0580BAFE050432866D75828FBDC44889A794C63F0855E75CB056F36A -A4F5F72D64E5AC055EAC800972934F2534FBB67469E7E41FB8F5819D03ACCCDEE81EF213 -0E1A4FD88BC7074BFD5D83FEEC51C9D1AFA13EDAC699B3DE2595C88525891F2179D8A0A3 -650CC93EC86F1B79D135BCDF82E797480322E4115A5DF19F16DF7C2557D750347CBFF239 -979DBF0DD515FA7B9A12F57670103E579FE7E7A9E0608CA20D0CB3FD1862E99248035DF7 -008C5972B216D066B473085B42AE54AE3C4651E4961F412E7702535F351F4273A97414A5 -3FF91785AA3A90119E4B93B8BA0375207191A2EAF3600CBD3A2ECE12D8EAF640295AFFD8 -83A7779F6DDF812467E38DB5E6B5F1C1DF8B4A0B95BF02E5C5F896936CB4408BF19CB9F5 -58541953A868C07F1FEA9A3EE0CE28BA312C12336E4B1161A934DB4035DF951B428B0320 -5FCAF9201D34DCBA174888CA3EF9D8E708B7CCE5CC95ABA181B7D251BFD9D6B3D7358EDE -A8A32B7F85C3F2FAA6D2C8D08751CC807E719311621F76D554B7238E9BBE15F19A7102A3 -0F343CC0110F464BBE35CD3920EC3A3EAE89EEF21717ED7015359D47FD7BFD16CE001058 -0B6DCB1BBAC9FCB2EE435D6AF4284B0CFB140CFC4B7BAD83E8A5EDF7C27C3001225D1030 -0F48379F84B62D77D289B6F2CBAB0CB27B5B9F840EE86072FEE3A858A62753BB5550BE8B -A63CAA5AB5E3756451A79F6A65D6CAB3DB0FC739345392377CCA2661A58AF73837441681 -567C6E81C0C8944033A4F36D599CA915EFE4D03D95C245298D10FA0A5BC9E9569D84E13E -9653D44C827182AB29339203E578FB73FD1F1354142BF3D553A6720EA72318EE76E226D2 -AC788224721DD4522A247C18ECE489334991DCAE23D459656224ACD39B04DF5ED6A19375 -DA2C2113CB7B8696EB78522BAA320D94A6C04E9CCE17D07C833B6760173F99151D27C561 -61DFAF6BD81FC42872E3DC8BEF1472CD53E32271A997CEA4A057D8CB8DAE15FA7AB150C0 -D92A1A65CA400C436CA993854B8C18D78F1B593139F5F227ABB34E1590A37886467BB263 -14C735651C3245FBB4F620A013D98499BDCF3BFDD6F1923DD9701F295E50E4C3C74DCE02 -571B4F4CB40C06B325AE0D51CF1D9BA0892ED1DE29419E3B8D6BA907B54A96BB67C1EE59 -31E85906AD2C09A9A964401769446BBE07199EC8EA8E3947B5EC31AC7537F93C9CA4FCAD -771A110F2D3AC7CB6DBFBBC2855F2F360D8EBB53045AAB46D65D206F03E0F4C453FA6169 -1DD1171543A53B89A2353511525EA85A4A825F3BB6BBD2889CFB8696E89902EB0DDB58A2 -279D214EDD2E20E0DC1F06A02B09AE75B20DCD226D353ED6541007905383551B46C2802F -EEB4AB6DA75C2ABB220E8168268AA384B3D4F8D9CA591B6BADBC27E4CED9B4324B2C4C19 -80ED6D6F7792FFEA1BF7D9F4D5CF6E52120BBAD41C87C749C042EE247978B45A1B30DA2B -C2785D51B7E02482A095B8D8A3D2132F9C80ABA4508931AF7A99A07C0286144C4F666802 -A68D63210AD70C872F74D40F72547ABA3F4779DB29A4C86633E273B3DE4B5F52759E171F -C67D16C74D105780E2B85DAA2D13807660CAB1830AEB605CA7577743D01AB9D001A65C75 -95F576940C1D3E48C8F5FF569E6B17954E98284DAA7C062347F0C043D9B71AE0FE0554F1 -D2C8DDA86EE58CDB0D63C974812D902CA525FA81B3332E4A87A5261D6B3FF4FE11F44A1D -73804F9DEF69D93F195C05C8C16781252FB8DDE0C59687454BA4D7A3CF762DB5AD308A64 -6978CB14A6A8DC6570806D7016E3B7FC0FF01ADC1D983B8A720AA7882DC49442A7D94A6E -8F01E5DC1201D9D0747A7DE1500D7BAD256BB6992F5B5E1BEC1D88BA81C11F80F994653B -36586D1EA5B5F805B16438070875630DB4B42B0CD171B152FB6BA57E9A755F80F91AF208 -2832357ED13E723AEC166195D6D88DDDE42571059A5B8667D28F3CEEBF24002360F226B2 -9C6103C47D98A6A330FDB99A0326B702EEC1D3B8A118F98DDD07ADAF1B24470C8C465217 -172119E78D37FA0E679D3F4EB4BD103D821FD839127AF7A26042853B99C89049A7268D82 -DF8079A1D47144010BC562504310AEA3E2FE85D91CE43275B50FDA31256265A4C318E075 -2C7CC99FA1618BC3979A58399060CBD9C4C8C7D5455A63BBC4963336C5BC72ECB5245CB9 -FEB9D399E925F9C67EC1FFAF1B28A1071A58CAA3AF9ADAD934F4D1459FCCFB856644B2E6 -FA6FFE63D48676EEBFCFDC2CCD9EC64B71A30342D364A165AD365F82C9971C565291E1A4 -FB4A40806D264B5A3EA0EDD1DDD6972D5EE5A27D633D546EBD8D3B184D7740E519857AEA -F8E2108FA525B504780CA54567B09C188D5D960C2CB3AD7FF016955229DDD88BEAC3BB94 -C955A5A27029E2E76FDFCCFA2538DB7FDF8995A4A785630B22EB30AB37722535C95A432D -04B82EB054DD30227EEE30D77607A4C2BBFCB2F653CA8895DBEF75AEB36BC7A48DAAF131 -193DC36826ACB8F8F33048F223D6BB88DC9FF78BF729C07E70117D205D39EC03A0C89BDD -926E7CC6664ED8355F2EC41D9B3CA8B4B58A201BBE9535A5620FB6C100D97161F308B01F -5E9E22428400DC8F41D6CB367BA6E8CD890D0672E8506B4C6CB352AE06BAA26700E74856 -7FCBE12864C32480CA3A1CED87517146FEC7578E3DC027CF2A59A5A09A3CB76657362158 -5A1BD78D218EAC0B318D8C96F2594734AAFABDBB4C2B6927AD5299698366B1BAF03BCAB1 -E9BC91A11A33A1352BD8F7170AE64A116675C3ABB5840114D8E1208D851BA251C88A7764 -A90E769FA91AB807AC6777F777030BA02DED02C2C391B69282AAC1BD8B99F7F9BC778E98 -B2DAA85A3EF8E9DBDDB7887890B0B2310285DE0EDDB6B4628550AD5C2FCA48FEC21F1BDB -3C6384784EB6557DF3DBF585103EF3B0276C48154823C79224218011DAF0763BAB3A9CE8 -C412D7676245E96BDD47F2E79E126FFD8AD75139B3B37FB13DDEE30FFAE28F7327B859F3 -14E4514546B87FA7FD4FD545872FB0AE4F8AEAC3B882A23DAE3D98098BA60847B013CAC5 -6577FFE3D8A1FAE941DEDCCDC7101E7DFB0B17F0E11100A2947B73FD8A22341639966D6F -DAEFF59CF0508E01920C167369109507A6E7ECD9CCFC30F7AA87BA0C1C82BD959FF8C43F -234EC01C7E2B3AAF12F543FCF5C2A2077DF5E0E9E3A976F107BC8E8856427511FD5EA85A -BE944C72CBBB3DBF4C9870F2EF2FB3398449AED9E345A43E8A6B0A99EDAF4118C89A3612 -CA99B59D4BBF25800E147BCC6CC51D1B3239DBC3A15CE68ECE1F2CDD6D8732238A922C04 -AB8859F9255477B00DB497320B8017AC48BE9C10D2452A82BDCE5C37953D644D50761302 -FD40AF015C8FF79C82015EBD62EDEAF0C0AC637F54F436ACD2D0876390EF02E29A4E3B3F -59C7B3E1EDB64B75F0DAF5B401015114F226BC68E31187214A69EAE0261DD7DD59B033D9 -311A2F01E44FC47F13927C1C9921A5881F2172CAAC71B0FE038C1B6CE87B04EFA42DD4D3 -65F6249C359F8071BADA34F2BD0A2A2C7B6B8AFA6A1F765AF2A9E77942190D1929EFC2E5 -509B9066CFB90D5D2A4732088CFFCB20A56A3218B020F491688AFC95CF8240EE7B7C38AA -13CF17FDA80F40DBFD5F92D1185968B43A26D0E38D0C9F91E7226E5BDE34F083FA117E2A -EF3CA2FE14C63CF404CF833DFBC09E27D96F5A6C16FBDA79DCF00652DC6AB73C4F6548F2 -16C8B245B15D9B5B29746E53FAA0D95E4C0357A3BE36A6CD993AECB9A42828E934A36388 -FB546D8C9D3531EC7B729D44D8AB61975BC7135E5ED59FEE11F12CF5C9C59160DE698385 -778A751CC279F807DD68BD5CF994340A16FF47147F029468C24E6E7AB08C2C69E9A5C5B9 -8C62FF6197C8455BBDB7BE9D069BADCCBE86FEB495B52BF65CF17C4B1157210C98948036 -55444C22444519D8A72A2899C20138698BD646E94748B62C3CCEB35C56837BEF1BDE5B39 -AF2E40A4D73DD747F1429CB4A953F949B97D56DE8601E7F299C218FA0D367559A750802F -64DA3BC53F83A733B1379AA57CDB1D657C2EE623A9696CFB580CB63902F87B4786A55EA6 -2BDA6CF94FA9CA44F388138020463F5BEEA1E273BD5BED2E9B08B60558D6A2901929C23D -2E6A61351A5CFA65DF52819D002CF21CE650520436C9681C60D81582D5568A6A0536E236 -26A13B4CD55903D130BFD7EFF26E806768C8EEA16359FD842898B8DC539E3170D4FCF3B8 -72621BD4C65DFD9F7EDDC0B17BB478990673970D4D4A07C7170698D784360F7A6A53768E -D9B41AB73360FE08C21855615214C91BAEF2F6A5AB71CA45E4B52326EBFB99A0CD401A7E -2944424878194E14C2BF7D183EA1B4C0BF9A3B2157EDD6143E9E9B30891F1185C3E2942B -EC87C1EDE03B77FE7CE0D145C0D918D13EB28EE264DC78409D7FADFB03718C6DF7D50A71 -EB216B5735A990274C349119C8739E5505F23C7025A79F4A22FFCC532981D27A70B94A48 -CDEEDE1590A2A0FBE661ED24CEEEC4DFFADA11F6514A8D7C026D2D685B07F9DFAD07147F -C7EBD82D9A52AAB50D1B52945ADD441A5F3A6C809127457895402C1AA796582950808F4A -21BE6BD2FE25CB9576AE1640ECDE763FFCFFFDD8096C9AD89B8B2390A2275F224F2FFFEF -148E4E1F29DB6BEAE998065B0306535D588F901C3904FF47D1428DDF213BB0D9D558006B -B5F032CEC1BDF4F8997B304CE400EDB24EE46C97DA278E03B768C2A23C88878B9A79DA41 -68175815CD1336A71D57C6E07CC7B8596425C9F8214F0BC2D99400B9FD644C1F8CF0AD3B -795B074D9D9CF25C18D3847873744228A6AB058D5D213587F16740AB978CE10EC3274FB3 -DD411E0392432D67C9945091AA3D90F95C3AF2B808FFA37B6C6359EA023D1ACB7A007F4D -5AAD3D9EE2467F5FD642FF3AAB11451EDE32138525FD48DAC480E29A16561A7FAF95759D -F83FC7504396991BA3CE2072851D7B962FA387A40F62DA05B81B39CFA6123F5B2CF261B4 -C7A84DAF87238729FF71D6F3DCED7CC97CB9C373D6B150C035853167C49368F16E447A18 -0F7F9D4CC3978E3E6B5F3B4CC7FA3078883D4C8BAC0A94E9B69B7CCB94E6D5898EC61A06 -E5A960058E6A1696C0BE287F24869414CA8D16E761C120FF5116A19EBD39109B0E251664 -DB0A5722B4366151759BDBA4A74204893F585A940EB1BCC870873F6F4E08BC88A239F23F -FC51016CF6F8CA8830346363BBA0E1FF376EB66174CF31ED9AE04219301EBF61A1BB5E55 -A89EEC27A12666287AE6AEA4D45A3706FDED0A70326CB050B6D25FC56216F932C1294E54 -88E3C331627D85B34875E7B51E4E7AF724CDBABB1F14EB6F23088595F2BF26D88C04D4F2 -4B94D94DD47761AA0A9BF649B06F7A2D56D30FC432FB49B570A53280A341BAB378037DEF -7FDC3B284C83F7CEE6800CBA2E20844A4DF8F2F5400167D136F810A7A739195896E470F9 -5875E669A770691C885365FBBAD1BD8461B005DBDD60891F12D8D4C8D51C8605B3CFED8C -EFF997868478A6A9D642789127727FA231B4BADFF182AB67B8D19402633BCD4913957BE8 -8F95E11EFB60934E8F26BD79622385F5D1CC5F7F492BD69C8C4BE47D76EE6466880A1885 -F63C3F4C893032D90FA8CCAEF615340A8424B4B1752C9009DD1EE6E0A10A0BE83DCF2CF1 -E746AC5A62FB5809310D5F64A267028A7EF02493B6DF22012D036A19B4AE3A9ED9A5F9C1 -6EA82AFC6DF1DDD7E243B4464FDC28B63DF4CAB59A58949558B1C1B4DD96800A69D14E7F -9DA1E1FB6DDEF437C2D31493631E79A41AEF27721579C7B40AC30421726959CA6CFC3F65 -5B309D67F0D50DBD33DE84CCB5EEFDC4923A4200341A8B5F9541428A9B6B94CB973BE6A2 -F39DF0CC141B9CAC1D0F25FD087A176D68BF69C6D2BA5084B586B289B00346DADBB42774 -251ABF854004F12EE97092CBEC6BECA5B74F21DB1BB72C9BBD9C0E11CDB4F64F347FCBEE -AE58924610D8A5ECC6EEACAAD54B36117A2EA580B9D6FB9635EF4ECC1649D1AC8634CD74 -0D01BA7F6F2379AB2BE4425C02198E8E75FB46CC405F706C2E2CEE54582CC08A239A6DF9 -BBD208AD5AB256C5CA2230DDBBAB210FABE5D4582B22F0E66ADF21F4F755D8E16EB071A1 -3EB431CB00EBA9EE617E43AC2E0DF733151A82D3000DE349C9B9E44227CF001D50E6C62D -A792040A868EB92A635208145CF8C25F51B698BC3460273AE679D251A43D5D1ED8D5D759 -6743700F9B67ADF9E103EE9C2D1727808433DA9D16ABDAE228FB35FADED5D54816E066A1 -8EC29EF2242125D1687D60655B3EBBD8E6227D0CAEC0E0BDB7845914D063890125E568E3 -8B14160794781E8EB631115576CF5A7E9639B02A28CF363720067EB527988EA1D2DDA4DB -CD35790CD4F91A253D0A9814143492857A320088FB02B28ADE5CCB4BD7878682E2895B07 -7029BEA07B654A13EAC49FC3E9BE70BFEB73418204F9164A26E47632CB0FB20C643A3245 -4777AE40288C6942D4C0C88FAB77120BC73DEA4EF0AC703DFBBE9FE79796671938382F22 -8A9C5B45C48FA131C17BE362EBDEE57378738DBC29297A9B69A7854A6D702524A76573BF -F76434BE57EA370D43CCED36DD0223939D362102547E2B7896BEADA8F0B3243979B3B4B3 -4F43500473F7C712B5E3B25BBBCEDDD40797649305E5E7AF2B767CB21C93195FA3B2BFC1 -A5891A91CA879BDD643A4A3B384C7A55718BD872E01674336419D2B1EFCBD888FE8FE9EA -3F07C87A87BEF21E66F8B26D25841401C499B31DF68FF0491E660E40C79E5EC2312BBF1E -364F6177BDA9DA10DCB347E40C8F423B12700C4C47DA4B09A27CB14310C7EE8DBFA567DB -0BA6DF2499B5ECE65519504C42B6813E0B906ED94861EFEBD5281DC0531513893F7EBF2B -9F43022A81ACE291CA736570C6E099A8CCB59D8E7568AA5D18FBBA8986905D35E9B52D59 -1E36EC95612B25F371F2743890AA44974F54814A4BDCC23F5DC100B5584B09A746938953 -B5D519A50D3F1FCE6040918E3CA5E3DDCF5506055FF493A8AD4F8A081BC3524D88336AF1 -80888D96699045EE95F984547B4D9844C9B596CDFBAC8ADB0194B7141DAA0385470F2AD9 -F542FD1369E418C5B380CE40E2461D3B68E091021E21DDC50D96C5578D73B9E84227EA05 -8231936F4264834C133C58D71D347100684A1F3F5A5B461D669B92BD7A00745C98906EB3 -15ACF12D2E94B597940D85CA5B69506661133A6B11BC940ADB550FD9B3FC14499677212F -B6166E695839DCEA3F1442E2C9E32E28EFAD1678796946725A1C0C62A1EC5972933A8FA0 -D37AD1D8EFDCA892F53962F57906EDF22B55AAAA17562F2F876C0B5C85197FCD583E2A87 -6C28672FB7ACCB063154A1FFC37A33B104AA37C7417F46EE3D4B59BB4E4DDD58A2EFD829 -71275C35081723630CA67016C8BEB30A7441E0BC9A4973888F0A377D7A3ADDE25981BBB8 -036AA2D9B15B71D54A7BC6C8DF79E7D2D50E97F1DB6E796655F47B5E988653996F1D3885 -60BB63A3C364B5AD590A5DB33524282B3C6A7C228EFBFC222FA475FFF99E83EECDCC09C5 -406985D9B3C00199EE2A620A7F820D1DC40353E0A76B46DA672AE1CFE632FA3523C8B32E -2C0D7344DE9DEB24C7E311E981B216361C401B2C7E135028BA08D3B91D39099DEB9DBB2A -4050AD37B9B823815BC6AA107A3C7B935BF259D9FECE88232061E4796B425B5BAF4C5E8C -4E9190E159743D7F3E4AB2191B8EE8877D8936E5D324FB57E6936F8267C015CE6D04291B -200E1C964660503C96C4A4B782D09F4D3BA952B7EC7AD5B568D27E3A07B26486BC45F394 -128A011F68B0434829C59772C66A001A50FE3C5F2C4683BD81AD8C4B7F7A25127CDE5E2D -EC216243C2398A1551F8C1E37939FF94CEC8A9C1CBAC52BF6371DE25BE148EB39FCD9552 -3065F034E4F96B1C5D61120DC87D04E7DED973471C0A3FA1E1E6BE6E2F01DC0199399B87 -5EB88A3E4AA85EFC9D9F28B3DC52319D374AA64118E1383A8A577538C29859090DB65026 -4A866725524BEB3FBBBEF6AB74FE8F786D1FA8AD94BE90794AC7E72DB71DF74F577F169D -F3B310C2D69D729A2DD755AECBC0E463716BA5DCD4680D4D4F4164420F2B46DBCC60BE6D -A68DA2B2AF32608266241BDA6CF36E132D83D16092DFF4D138BED509909E250DFD9FAE30 -53BE12A825D3A91E404449013E219BC67A2B18E40D497125A2F39BD16824CA7D2A2E5173 -89D69D5D838BA27ABDA5012B426E58456B2399ECB1B4009CFDD6307F6D104647AAD6D083 -A562E7282007B3B2A0B6FB23F2EEBD0E7F643A9BC7075D893335DB246CCBD8A37DC6F1B9 -649AF15271717A769484B5531A1A7D99A43E90490F86C170193442D01EBF02842D349B7A -580D601534F1EA401D27D98455EC4A5800F4BF5893EE080441F6CD28226E4F6AEDDDB7EE -7CE77F2BB54FF006967504CCF02F4875EBA2448C00FF58DA77B50A4F4A007663B5B64B18 -702C96AA0E6F85410580F931BBF249E91AF47477EA284CD42572FEA81C462D7E0CB5F81D -EBB94225776D69B02F04D76B51BAF103B265139F85EBA00F47BACB0A1FAB9D39B648B5CF -06E58CF1CC43A431315953006CED0FF5701401B01CE4F335015EB6E41DE8D14F1B5C5757 -1371E7875B17C44B374184836C07D47F4FA44F8E49959BA63A4647F757B3837BD334D2A0 -423E620AC5E1C5B18C3A400A8CCB7119C3331812AD8863FC3A97B470293F83CFC37E8BDD -D2EEE4C5F88423740C93563603FCEC652CD447869112070497A5141CD7DC66F62EB445F2 -DAFE1378B286E730801959EC5FCED464E1BDB06D725970C08CA0ABB730C12C720E219519 -FEF20F96A1B0FA671565B45FCF41A40D5AFBAA092A09F72ED35FE94A98DCF5649F6AA3EB -FEE7ADE1E19B4429C4E1E76880C398246201CB067D8A734B23BD3118A8F5F7516E5B1452 -72CB0AD9F41ECD8FA61ED0CA87385B2B45B1BBA6CDBD7B9C9890F727BBAF5EA03273E387 -FBFE8D0143D1B215003C9EECFFC9970AD21B0A7E90F56E53B3409E102F89D95B3EC58DF1 -B1C8D48CCF22BEE22EDEDF25CA18A0461D2C582220ED664F198B93B388FD8CA9CAA6D8AC -95F10E458BE5480C767D6606675208E4C823FAD4A3B8E77915BD881C345B0A8C34F01B75 -2566AE58CF3BC97B215EAAA7189AD6BCE0A524C0998235A61713C538CBE9769E2350F670 -4BA790CF77CE5BABE376D5C2B2F9EB8D90B762BC59D9DEA5234ED14A949B002258212E36 -D5A22B4D847EA8C4171D74B78A5E225E3D956FE7F8B95FA133C50F864725C1B8F11C2D1B -3AA7D08C0745209E00B98BBE59E463D60C79122469F9ABB8A7CF777BD90999206C83F8CE -8C95C79993C20CA63CF556C821C8DD3D5124D2F293E5506D9CA515E026223D115DB59D8C -883FD825FA3EBB449524F1BE7811BE76856A063BAF9C09A3930417DB889B4DFC1563F688 -02F4AE1BA0EFE463FE884CFAFC0FECD0F4396B006B9230D9D3BBE6757318184EE7EB6FE7 -00E148C53CF3FB7DC90811F6D5CC8F9FFF975EC7DDA685B76D05C0320E7C3AB3479D00FA -927FB3E9E4363115D05E3D62AC3FD06310DFC6117117AD8BCF44233B05901E32D8A1BE67 -CA059C513BA968CA1EFE077CF8D651540EABC16EA1F61AB1D7F74F41EA52E1BAA0A19576 -5547168636187DE931C6F97C624391A212859C3A95F42DC367AACF13BBDD503FC1350FC2 -FC6259B290A18447FBF37284CE1F00DD81929B13F366C0C4FE86E834DFC7FBF5B4DE4D5A -33D014E3229A7957A112519134F0794825317A8D56EBA39ED15725CD940D974912D4A79D -C499D3B2DFD7FD67DC7E79F70A04D5AAF40FFA6A568AA4FE042FC2AE31E83F60671CAF60 -B8425E4F3959FADE3947B2DD3438C7B08D71A036B2ED959168D507274BC4C04BC9A9448C -0385531153595DF90BCCA1EDD889B3C9F3CE3FE63FC858AE51CACCA7160C3296038EDA20 -38625CE0DD5C236F6F18B3B41FB6D5953F18D5FD4F700A95B08BB10431090C652BFAD23B -D4A9211D0CF59E5C2D0AAC5708386D14F02858C820A191239D08E6121A77A83FE89BF056 -C42A6A56B55EA35DAD6696F64F3B702C21F4D97D87CB80ADF688E6F1094B00714820BA53 -65CD655C9DD5BC030FB2029972D15CA71610085A1A7CA47E290D5554413EB88B70D94881 -1BA89738DBC0C16EB47A3CB6190E191E67004BFBAB73A067501BD283CA816CAB52515721 -4CF005497DC884ED61CD5F5235EDFC207A0E8BE0696E7F93BC267C1CBD85BF4BFBDB755D -BEB88A7D4B978AC52B7D1AB8D828448F848EB6D2F839AE9F4BBF34E1BD5DE77FA93F23A9 -D111529C49A295893296D10F51BCF03327CF774BB1AC501BD8BCA58F3E82BEF79C39F434 -845435E9DADBEFA2AD5D79D8B0ADED3DAC9C1AD9E6A24B206C9DBBECD552B2E6DF97F864 -C8925A37EEF8718CD4D277949D389959D852977FCF96E2C46477CA973846DD65AF478490 -028CEF70A4290B22C4DD7514F1DB34820656EAABD1FCDB7A9BEE0C18E577D9F27CC50777 -D55B4EEA53E8F681F76D4791300A06C380E57B35FA48314BE3C4A70D1B73E743A2B264F7 -3E3C73CB25FD2D33D74064BA8803858C8353C1036E09EE4489433C92F43ACAE005051DF4 -A89628CD3B3EB9A569AE2DC5EB290715FB1028B2E32BA7BC4C48AF1FAFD94412BC7A036D -A31924EE68FEB3ED8DB8340154D5757AB86B7D5D37464D58A22B54E37FA9891FE1A54C01 -D7FA05BCED8CA937BBE67979068B177A777B2B315E6B1F77AB6930DE1372A95A0A1A01FE -C9405011F1F3AA2252EBA22A54C779661AFFD26FDFB10044D8B68277234762FA2ADF8EB6 -B53B75E663976FFBF7D43502184FA7CF047A8CDC2CF0220E542ED63EE9588C41E35496AC -39715683CED932BDAC827F5CCB9BE1D3BDDEE2D2C900AB23E2B54766DA16CC227E58E53F -788F5A8880B5FE8A7355DC73B6B26BF783F02E2CCD5F96794DCECAA0E7A603CAF330FF6B -D8D56153CB4272AACA3DCAA5932B7F754D23BE23B2282F6C2C59B2C1EE4410F342160BCA -093ED020E4EDD16C7E6E03FBDB06D510E6680A471E3B4E2C4319FC138B92A8EE4058A0D1 -8D7FCC51D9F16E9B74EC75CB482903BFD27C4A17654A6AD85D608558C6A717D47005A8DF -B52C28282EEF5B9F7DB1086D19021269438BA974CB8C34A8B85C5542519424FDA394E116 -61636091F18BA443113DB75E9FE5C5B8971E8749D15FAB20B90C10D3682102CCC30CFC3B -67DC2D519C96B9F607B6BAA01FBD8B78236BDCD6EC3536D15BB3A069272C646403BC64F6 -FD55E28988D01DBEEC75547D4D4A975761E5BDBD5E3D7601065C4F9657D3E492DB6A3558 -037943383B261335F01494978F46999DCD5584F7B5DEA427D20F20E29B1D80AEF1E279AB -F27AB8410172E203B3945F98FF87A2FEE2B89293BE2F5DBD88A200130143D79A5F8943A3 -D0895650BD6CC2FC5D5675B30B12B4E095F2475F7D8788EC9AA952FFC8DACB281EAEF931 -34A6F83920FF8E7C58441BE339ACCBBCD4C9BA4C8EB9A5F6A45614F991D9EB0A76B2C869 -944CBE0D6C0CA4C8BAD0B897328A4D354C60A31AD9EBC0F97835BF4CB7976BDB95152A1E -919144C60E884BC6E6857496C77C3C7AD9F52C53A9051238011D41F14687E5B3F666CCE4 -86D16F3CDFB9AEDE1CCB3452A68F5FD75FB96600750457E3C3FA6579BF938439AFC75386 -D1C0A1FE73AD6968DE195544F85CFC697793F1F66DE6CBD8137A918B2C24A99724C978F7 -46BF6AECA401F5D298CD1081970FA904F2E2CBB2D749526C2E14A43970B2B2CD28EE9178 -A58F60F7BE3F87967B4C1BEA2ED73DF6692862CE919E3B406480A69CAB794692D0FD1C6A -65FB1065BCB5AB47306164C0241A6177D8AD8E629C77F84A1AB5CA62B493C5C016AEA0C1 -E45AE05B54646CA6E134B776D09A11FE04953679CFF2777B01370F482CA655CBA8D1F91E -07D0106FE37E83267B5432ABB51D56C88EDC58A11D8D90FB5E82BC023C4521A6649B9388 -5BA6C0D139C3BDB8B0325CBC27AC4E8F673E53D84476E1632DD4A09E94D375B65B0FA682 -18609F5996F543A985FB6CA55D302D63F86F234F94C9A5A15B0333F722702682424DA956 -1E6614FFBF8A9293F5750E06BDBB05D3BF6F56865577FCC010643699D0AAD5633BE88939 -AE6324C36A7A5FD5F148162952C357C4FA5E8DCBAEEDD28D71A809ADFD563AB3C4CB790D -8FC41B81784B3E9C672A2F6A2230E90882EA374A579ED2BF72795E84B089635FC4F2B48C -D51C418BF26AA4939CFF22A0B37182836E70AC08C971EDFB46A31BA11480BB855D53A01F -5A0688B2CDB04B9C2CF22A63ABCDC965993AEE1DBE2BE79DA4D1BB595E24E87267FF1648 -D7F8E531B275C5499FD4202A948E2DD9FBC7CEF688566DBC53B886A2F9843F94CDECFC63 -78E6937D4CB278E11EE9E2957D8BA31145058010C98A752CF568AAD0FF5C4C67988868ED -19762F2F54D6D58A3747A6C5A052543ADAF50DE5AEC5DBFE6A2F78F08A50E5F65C328290 -B383524AD0A1A477A9815C8378DDC0CD7E8CDAF6F097E5DD40900B0DD7A7354A37B9D90E -7C4FFEBFD1DBFBE33B5EBCA7607243A53EA746FFB8CA2D88E73D2696281CB210E6D5A0D8 -46F669F24E3448DAF1DE413B6248564E718D903654ACEBCE09A7CA994306D924535F5792 -21C39D8E386B1573B9B7C26256419D8B52F4980018DCC0001DC87F590C378EC0DCBAB4B1 -8F362A7F64BD16DE2E647A4B0573D92F1300D5D8423A1FC658E708457646CA9585071B72 -E66A2D919AE292B460E816FDC8CCAD369EB90FBAF5BAC731FDE38CE2E45B755934264D8E -4EABBA7D6C0C91B4444BEC23D8FE44230223BD612D845BF57659A9594168655749D147AD -CD4182BA77EC41BA34595990446E1D093CA7264512C12DB9EDCC3A2E97B478DA4A2E7A81 -3CCE2592BB816CCED1196A40E76E4B0BD2EEEA1EA7BF331D497548FEE91A56C7C057C3CA -E25412546FAA9C1B8382F5F01004E506A0DF3BE419B38AA7196EFB6C9B469E49DD63572A -60FC9A5483CFB723FA04BAE4AD526E8C3B14E252750A79C13D07CC1A1A424B33586F7072 -F28D5C61DBE7F0EB9BF47110B4CB018190CF5BD564CE48B9775FEA3DC1FBB03206573E02 -C60969330F0DAC03A4EEF803D7F860C14C50D809EA5D5FB13001048D2CEC6B56C2423CAA -EA0FBBC4FDF550F0EA3D921F522A65CCB0E1F590106F163DE12D1410F35D72E7C6168D64 -829F8144C5B7CC9F902081954923AD742954477ADFDD4D321A593A41806C002B02D9DE03 -38DE6B6401408FB03D282489D23B6CD09A77EC31A7EBE000D54150B03A8610D0DB8BBF8B -9C7E94419C0E522521585F2B7C657CABEEEBA79F2C8FE57C86F593F805945E7DA313B826 -2DC421EFEBA8237EFCF9B054D12CBCD0A3BB32C4A5BAC3E8C105C32860E80FD83F095A20 -AA4497CB6F4A879E5F7AD6C2A8272E937A61BB95402F130A37261569D47A88D4ADB80A1B -1EE5FF03D8890B212E3508C408EF145C570FE2656ECAB9EF52657A04456B580344FD4F87 -2B5D5308DB567B1E957073892D8F83A2C8F93CCFC11D3965EA0B985B5521C997786CE86A -3D9E0A3407EC73E51BCBE2B53D11DD304F0B7469E34A5F6904F5B3807A62534D742DBD4D -3EED49B28F68BBAF5DB1E261ABD0C7739CC09A4779D5D2AB15ED9762FC6E72F78B71DFA3 -23C29D48F47E44A38D87168413E3F589B9470C79EF8A4EB6216F1F0F74FE2853E7EFF2EC -902018A4F6FAF4CFA75B646447DA90B8DD612A65ECD9504C751D331B3762DD369EB0D179 -CBB70EDADDF73E58919C65DE73497A87B4ACF06360FEE10E7593507C6663B0FD0308C95B -F21B9ADE7966A23FA4CD0648051F2CC20ADC25C8F983EC2DC97E2160BCC62CE3051273F6 -3D65913AFAC94E548B6BE0BECE2B704778A24C4348F128A4EF617A7F43AA327193B5BE44 -C2045CB1840DF5FB6CDCBE455EECA489E22F0FF715F4FD6D14A874031C58A8446730D0AE -D36887A4B33DC943FB6A9469AA781FB0E994AAE327A86408D63885662065330B6AC00AEA -FADA28C53CB4255EA1858ECD3869BD7A27EB5C9949530081E5E103DB50CB34534A4C63BB -78E91AC992D1D58F2D08E7706D25CE375CD041F049F762B4B20FA9052DB766881540D4FF -1BD7A4FB927F0A3ECD257938BE91A220D9FA4E00201CC64A1E9816E9D71E95931A5D018F -0AF2877F2737A7749BDF3C90A1694FB81EA9C970629EDEDB5EBF19A60EDA5D7419F3EC1C -A51FF1544B23800B0DDE96AD4E5E660AB20AA419182AC33ECE2A48675FB2D74770AAFDBD -6C300C6360B9B5FF14B7022BE140C05133BD0D848A605491C156D08EA88FD0C4D2334200 -B8437E6088DB32493099469000426A3CDCC627757C9DF0BFA4E9E0CD5D0C8F3E921B1E41 -48CB6D876F445CA4CB9FD7E7FFD4032B2A97EFB025B182A88CA72212186417A5C373B5A4 -3357E58EEAB3FD609C5DFDE96D4BA104C74D69AC17E20058D0B4E875A53F547DEACEBE20 -CF74242301FA39FA6FE6B0C22C5FBEF3DAE3B2727949C20CB8A1CA7A70C7A09E0BF76794 -BD67F51F3D3A1C2005E4DAA6CA87768747DB8A7ED1334F03D3C3EEBD796AF804DB774DBB -403B4B0F6820033CBC99BDDDBCCBBAF0FE7C56959608DA53BF83A56606CD524D3A80D591 -AEEA4658F0E252308551371D192F88F5D8D58D2B898C494FB23463837B8249B5EA5B1DA3 -12A1CCFDF4234C772102A6F0405227A48F6B216BEE7520409C77C77B8F962977F9DEC1FE -098EBC19A77E3B155DF2514D4E8087E0CE8D53B272735F463871AB02BEA13B9E402C2239 -73D2B968E55031BF9A929B6468599889CFC84ACC422439464277D86FC347D3681EF42838 -08CE24709A9A3ADF4621805A61E3AE1252051A00A8DE2ECE5DB8D6D415F2648E7FDF4219 -4F8A063187F64980D3216EA297178A6F87395F40DDF9DEC4D649D74736AEAFBA82E7D0C9 -05D44A8E2F02D356741C23DC37F482F54CE53DE8800BDDBCD170B8F089339C7CAFF13A4E -2D4C4EE33BAF718DAF51BDDA347FD8760F3297CC169112DFAFC9871CE42FF8C29D7A2168 -0C6E23A2FD776240694B44696F69D11454646066BD4B6ED7BF4CF3550BF0F32FCD0ED0BC -CE20286B8CB1645C308B74D0EF5CFF8927E1F2FAB0366BE55CD069AA7676E4592FD42342 -617A186D3C144D173DDF6E01F5E5E5A67A9648144BBD646BD3D76BE1AF70EEFBEF0361A0 -4BEFEB59E94AA5CE2400907C9FADCFC3633ABB62F24B0980093FEB72977CC3E44AEA7007 -B4721D8B35BA81A01C600FDFC070A29337FDD56DCBA7EF9DF7364E0230500F9B8A075625 -7B12FAA98EF15E011D6A6D02C84655D15AE62181FA4D0CE38A6FD6B2DE4F57B0B963095C -95536BD7A53D0FB7C1167F251A9C43DE263D68FAD27C6C10ADFB6D02BD1339CEE7DD6EC2 -FAA687A55AC07E279CCDD84F46A6DEEBBB380B1DE2897DC279C784A9E352683352B059B6 -15990972B53695F73097EE77081F23E15DA3B489A9B088C2D7C76B89948F31D68C3F3FC5 -0243D545C56B62CFBF55E1102D9C761E8A7B0F9A547F9B0935CD78E32AFCE9A451C2F455 -DF2DF4117955D9C9B30619FD8A9EF23827E70FF05B55511185288C06668B65BF67CD8C77 -CE1363B83499E455CDF30270842A22F23D101F7CE773BD709D2E9172B169E25C2AF2B64F -93DABC5C18CF61B30DE7ACF3B7D746EC1B725B90B767D24DB244DC37A42861250A52A287 -F2B7062AC268559A2C231F3A93E510527BDBC3DFC742B457D774C6FC8B023C02E783F2CB -C50C4D37DD81433BAE0A8A9CFA280E7008C47CD75E1A77242B5C1ADCAF70E3C0F870C126 -197091879369A7B31FEB8086E1733E377DF5AD77358D296D3C1CB2EB54B7DB9C8E5AB4E1 -005A775EFA44328FD755D84A064876CAA2E1016DA7DCC961F2101A8FCB699B73A23CB866 -51E728C07CB9EFF654EC83A5DAF21DCF2F777535680C32E4A88AA2D7D65F166B430CFE51 -9F252F51640D7443D75CCD2F5E8494D1210B3F5BEC029002C754BF6B506B5715601F5134 -B6D95060BAC8F6CFA2249FE4B5DA5B098873CCD2C5A6E983F6C62C3C0A9274899858AE7B -5364B4434187B91EFB705FAB6372E3A003D5361138EA6AC70C048E7E05E2F319AA81DE1A -8D1836CD2B049800B991CFEADF399960C02EAFA33CA1D987B161234EF3A67DC53B6FE467 -857D5897446EC2D4C5FE183320F28B74EF3900815A540EB68C325F038A564A23AE235D12 -A475030624FBEAB5A8A536D0011C89AD8557AA5307A5DD4E46AD91FA15B8D6A297DE7717 -0BC90F8C526B6B9496F1D4C83491DD2FDE4CCE06420D943C5104B0C56DC184D8293D9305 -9AD7C5F6251F7AE7C19BD13AC98FCCF587FA9A223082B43F04267535CBAF822F0DF7A642 -7370794C4CE3723238828BC3459A01D8B363A6B9342CB523A13CE1139525AF0C372F8AA9 -98A3E2962BF6728F815D33AA537B8E27ED9174ED4422ECA87BD9E0EFA86566C4314BCFCC -324D5FB4105E9A965CD258FB0A2B970FE0A21F951F3C86EDC5543B067E2CE337CDC04E30 -EE665A3725A4110E845D9025978D445DE6284A55197735A5C018D99CAAFE6597F3D58D37 -68EEAE6F5428AB3B23B5F2F9E8EFF5D6DDF1B4BEDC6D245E63F2E5DC0911E8CA2A9DB100 -CCC4EB9C54BEB0EEBB2E1027BFBD041DD39B27C151EA50EFCDA46F4273F74C85AA88B1A6 -7BA9A98C7C6D7C406D8B3F7892565B8856C77668B86A0BA9BF743C5884FB94CB729403E9 -28EA9C8ADB060911FC0E3DCB9B828FDC489FBC1F15FC2D75807EE98AFF5D841D88303A7E -4CB6DAEC1872D384214EC0E3039478DF79CBB7C12202F9F56F3206FE61B04AECBE1D7757 -0CB8A43D3E145B0ADA7CE219CBC99952BF54D734673632B68AEE6CDA8BA19BF7937100A5 -FA294B86F7439FB59E367CEED44FEA1F4CC2FBA570AC2C32FA6D9F67474BCA9318A84A31 -107CA7AE187454434340DB2F3A0B2B41E552EE49E828C20266B88BD04DBE61AC6FF59A8A -D065A704C18C315CE79A72B061A94558964300564DE5B41B0BA3A0493851A355ACB34BCE -7FA00DCDF05F3BB733C9C79BE3F83D6103171A648F81BB138B4996B606A7A8A997761548 -08F89BCC7C81BB14F916F8AECD873406778E51BB93E56C25DFEC6C3778AAD6B537E6F488 -D29898E17B5D38BE14ED70D79A62B9282DDF229114C0BF9830F2E18A4717C45BF1B29A76 -31B60D13A283C7F92EC4EA3D98D2331270030A14BF9A8E07D87E66BC034F830DEFFBB5D9 -9E95293C70571BBC4B65E1AA13DDC945815FA79746024F5751F8FFE718D97B8AF465BA54 -598EAD21B323C3CE47AF7BCBA58BCCCFFFA0FD2B463C85DE8D02378C86BA7D3F44C54165 -E00E64FDF7228570A6F94C2A1F8CC5D947A470552302D6B3850EF092D6923FFD39E01F7A -B0ACC7B6467877CC301A03136B93A57AC0949D62D3F3E63DFBAF695767877516DFA1CBAC -F68BED7E2AC83C1612F234CB12A368CEE9657C6519908C7B046494842013EF81A4986D38 -58EAAC69D84FF32CC5CCAE2E438DE88A426365EEE0FE9745DB5B7D494C3ADEE8C6C31EAC -CAEEFC174DE952E2D668BD28D621DF9C81BA0355E943BA3ADFF04721B586C659494D5A36 -985AF4AA408939371F448293A0C04CBE72C558E4DE12B36F823445A2267806836D265BC0 -8B279386DF1579512252A9CC6F69D83959FD3F1FC6057DBF5F28C644AD4862ADBF133C2D -5779D96F1EB234FE09E0FFC62EDE6D295F19F52A9A6124197CC250EBF77DECDD5F8B024A -D635E941AC0CB5CA59F6278FE2AE87F7A005A5A9FBDE7609B4DB903112DAB7B612969DF3 -F99F3D34D95467DCBA57E6755BC80C4D18EF9F440A2562DDED104A80D075F8D0C308B10C -E31B777B438DF32A77433152571170DD44AF096981632062E3F525ECB3697F3EDD316E15 -2E502A9B8B351710611DDB75B710D6CA9801ADFB57EEBE007527611D47C181C3BA7BADC3 -1210B9FAEF3608350D905791F025960862B0B06B4BFCCE7FD92EDA6D9B2FE67206ED53AD -E69BE630442EAB6BD2977E3BBFF487CB15A7127B40BFA161D8BA602AE211C8E3FCE684C0 -3E4B7E8148C2F61DD65E1D07355B37E62A6BFC70656B4C32FCDC5926EFE37AED5253F67F -DF9A556956D96848B81A6E11D005984DC36E99F1874803398FA37966B1A37B8282BF9093 -65A1B89C1E1CC37B02254B75C75D77A39F9D1DBFE7B79F70AD0DD6038D824A7DB8DBBD79 -B6A5302D5859D5925B79A210210103791C4212F579EE900CB3FAF002DB06E0ED6D5E74CB -71ED20AD85A257F1244C79A2B6E703DADBFFBFFD414C1EF6C7A7CC4B12F72811C0F0DFEA -A4DBCF715812A3E827C06AF347EE1D72F9FBE9BE3D061DB13CE123C71C8341C2F56762A4 -FD0C1CCCEF591D01E7608B097621C45DBCFA96348DA2F80839F0EB6026AF7C14E73E8506 -FC9C1F68C88CBEE385FC280F18D7817A8606FF3FDD506FABBCC72662B0DF81EE90727ED5 -90306DFE6119A9CBC84172C3D434DDE35039F91591837F903585245D0131DADCB710309C -596B7A8CF8839B2C347C2493234386F988A7066BE6B26F9EC504868915D71E1EB5E9AD4C -F2C5F71E761B50FCEB823CAD364F3E5F3B1D10BA4916D915ED0040A920C9C9ECF344E685 -2B805F4B1FC9062625BA815ABECC0EE80D708D0BD141681233E5A483FB2DE7DF9B13237B -649715BACEAB3F4BF6C6403F8460D190C77E4DAEF62F437361F6B9DA9B4787A68DEC88D4 -556111ACAB7C7BB5F2F1933291DF83425C10895A2B47330B661DDFA456F130D91EEE2A4E -F9AE28D45DCB80DB7322DD6D7E394D475AEE95D0DAC575AE569BF9D26CBA1CFEC9DF25CA -A1A701F60B297064A17CD878E101FD6A6F981905E50CD52A807B466465F0526BD502F249 -B8C4408C130D017E6238B5B5BFBFBA518BBF414E11E2D25926362F4EC5E83E6C26B19C04 -D68C4D6D891B10773EF156166D9CABB85F08A1C130D9D35351CC9E7E739460EAB51F3F8E -A011A2CB3354F759E9EB297219157F02BED05B78BCD8C73E3881C835A7D986A3877815FA -5ADB7713819D931FD05C53FC0C584C45763B6725094485EE3C48E246A1E8968C6DA8979A -2D12CF4A97A8822BA5A066F62333C313694562FBBD8ED26D32E8D09426D0AFE33BFF61CE -23F03ADFE9FFF17EC5063381102289356B1696475310DB04806487792F7EF42CCDB4B8F9 -9DE168D16AA56321F29B09EAEDAA9727CDE7DBBEB62F33EC6FF1E9A74696A7F4B15A2684 -968D5CF34F65E88601368BEA29104246000EF93B64098CBB9F26DB4EA1791C48E245109D -23F39C97F87BE05A31B4AEB6B7A8E49A4648F8A6AA3EB1B80E2A0014CC18A59B43441A81 -D78794CC162D367AC2E22C4985C0EC45B9E29F1D00EFCB898807DF65A3373208127922EE -E16DB24D335DA01050CED1BE9470624CCBBD978063F6C538F90CED1FF48A83E404FE5DD9 -2DC2DEDB2324409E78583E5C7874A9661480386FDC2FD62329D5BB33AE4B5ADE5FCB9BCD -B016857AE69032C019ACC0D16E07C92B252C2AD5E2AB2BC9A1BC074EB697D7842AC5F61F -6832A8942C6BB35E3802123DDF726304D74F10FE22E386C2AEEE158BEC56DBDD264A2321 -1A3D0B53183DB2F74A306D00758DF51ECAE68DD8944FAC719EF56190017CE10DA46066D8 -AA27F9D6B8BE4911E2FE16D77303A58EA4C184BA139F7D39C4B1BE8C72B8104D1FF671BB -DFB1C1F8E518CAD156D4ABB057B622287CEAEEB574F2C202462FE2575EA7D8CD820FB4C4 -B87F022D732D07DD009845BA831A6E2A248D5ADF9C179276905A494DD35E4F7E581141BF -AC76849B0F38B5A726049BFC2196C38B6EF6F7A0D38730CF3CF850A689553B7595070858 -97211A03A40B37BFB57363CCA5CDFB04E01759813DF0B67A693FADFD5692DBCBC543DC30 -65192915E654112AF3676DC58854D602C427315FDB2E0624D826BB60B5EBFB4CB190299F -930D0385629EAF0C0EB37F4C01C5C770BF1F0F825A2A4B6FE50D2DB566D5B7A819FAD0A0 -0E4A7E8686E9FA936C0315622C95735E251FAB0407814B0F2F848860B942A413C7F43239 -C413EFFB4B01C1CF1BB9AD882DF6A3B64B5B7C7F0EB4E707DC5012133AB2493E7C3A88DB -5D0A51394FC7D6E66ED529D16686537DE3FB1EA7116363C4F5945B344FDF031FDDECDACF -34F2458908AE0F62E2D200A9B147C1FBC1877FB41DF6979AFA02071312BEE01A786E5EE1 -FF1B4462913540CDB34B783D104BE4071888AAB52177898F5537712D8DA1B09BAA0F094E -8174BD25333D3043CEC70925961865785A6F81359B7A580D60134A293C8DF73F9896BD62 -809715A8C846915E7E636CEFD18125CDFF15E380A8901B0BD2B7CDFB80916D4839849795 -A7231BDBBFB9858A7834BAC1FF8B8365D9602985E8D8EDF33D04AF77E24525460278EF7F -03AFD42AEC3F4201F8C56C2F4885F0CE693EA5BF4F62A8CD61F3A7827A1C40FA52228ABC -8D19EE1089AB3E80336EF6070B9EB31781EB9C6F6E3BF3BAB61443BFB63C08BBADE7E842 -67C6A44128F33D7843DEBBA3BA7E723E91922C437D24A329E72547DE8ADE2C9676C2A078 -A12CAAEAE690A31FA18076FA77BCFD1EFB5762ACE44FDB97FB5219DCF9F542F87A959EA2 -F118162323B46DA8A0C116269D8301850EA28761CC0E5ED06ED48968EBBBACB891CE73FA -52B7C262C73DAE25843C00923D04893302DC2EA0EEC7A2CBBFD949A3B4135F5AEF66411D -CDE7856F7FDAA0E630C3BBD42305182E3475589B41461360EE1B72298D97825C499D9F49 -653AD3EACEDB5F9790BECB554A643AF9F1CD3455DD51E79FB0A6221C4FAF81BD822A1BE1 -AB8F8B18E4141787961546744132ECC7F19EB3E81863CB6B3FAB60D3963D6E6F106A2558 -589B07BA69CD18152F8A8B884BB24FF318A071CDC695F6D8DFF7D04E16F0AFE7BF2F03CE -F6977E0CA4B46C24E22FA22C0B9DA11EDE76B5B511B1DDB6CDE7C314EC86E2B79E1C4FE5 -357797A5EA3373FB14A212440F6CB0821AF449122D94828CC38E44AD6C7C7FA78B932192 -55ACF779D9634B75999314B31F79003E030054010133046C6CA9AF0FF33AEB9E7C63553F -F34203EEBF0E3F104453C1430A3642E79A4F5D708551C4751C9F4DF3862FA15814A10567 -69516410AA29695690A5DF3E7B407A2E5F05C8DB7AFA0132D5F43177388FCDB17B325990 -1AA479F19C138122AA2EC5674A7D41D85233345FAC3ECBEDE642BE5669128E17DDA2D86E -34088BB76C64685FF98F01D48175847E0F49E2404E9C5E9F9073F3796DC575468B53F9F7 -39F93EA3FDF18DAC9489FFBB9B18F150CED84E6A4241580023C622129B1A91A8079CA92B -1A8B26B955986833D3144BB4EA25866AD4B499247D44EF273ACB2F1637F195AE7E89541F -C6B70C8064F12B696A0C9BB09DED5F41E19914918F7F4834428A01350DDAFF763611C173 -12EB28618542E8EBF479BBF5B120E02ECCF7D3F9638979F0602194DC2512C682FC947B4C -CD5BE48F0CD4BAF3710BB42195ADC7DA9EAEC09E124D49E7CBAF579616DFAB94961998E1 -4EFD0128982A15580D1A2ACAFC740EAD92FAC43E7FEFB551EB9322A8EA302B573A6C4B90 -87041EEE1D7B60CF1E50A88F59EB46F1DE9F9760F21B8EB325E90B536AD68829FB965237 -5097A06AAC312372A7D3EA7134A53C253505997B4FB2BC25EC2ABC8BAFAEE96BEB6EE940 -A76AEDF4F00EDAE82434B3D5C8B854BFF71EC073A0DE2D98FDA384E4DDB1D84704BAB88E -DF057C84DE21A1F7C4FA509F1E22C7B8FF788DA95A7215DEE81784B7F47643CB85D08DAF -425E251EB72FE482CAB41D49389B323E66D27863D719D78C676EC91981B0E516C21942E4 -66804EED7E214B4EED83A1831D925019709A3EB1B2CE62491339DEA3A3890107CC5C486E -F7A861D7B023B2835A87F62008BCB96748B6037BE07D54A22AA4206C85BF24208016BFDF -EC4E68D8CA14CCFEC2CE496819159C153610C4521D312B8538FD3AEEC5FEB1021FE9595F -767ABEE99B952F0AF794FC4D7FB0BA7B8CD73B543ADF833989ECA557EF2FE9E80C786180 -FE2B6249F45440E94C98C00ED7B95EF5AED26A9058826EEFE0377F4CF786450929E290E1 -D89E70679A7BA87CB29FCBE1A79F24A2713D182F1BF990340FD0E00012A25801BC643A9D -DA70E046D123E7E64B884B0F8024639E055D6F7FAE5CC5108B68125C02EE9EC0C41368E5 -6F869A55ED15563BADF2F88086EAD3E67E8714AC03D2A12B7E99C2947D6422E5F11B74EA -2CC153B8409A2A03C0AE3AE784AB05475F3D086EBC28089DDCF12C8D4324A8659EDB40DD -5AE08B2752D196ADBD0E540590A414A6BC6931CD78CF0D78B23080B4D5C5D86B9E4E0EC5 -3D774845DF7C74D07F242655018AAA23E64165DD462F5D2A282B5165096732D55A3946BC -C00AEFA41085AB8F2B6BD34C065DA2C9C2999903FBF17E9E7E39E874981E9A850504F7D2 -A1B69C85F532C6749BC675FC181CA05F486858C0F22BFEC83F14D4754C3C42F0AE0ADB56 -9A48214A9DBB6D163E528E4DE29157A8E7089EFF2E2AA6AC85AAAE8925CA4A019DC38668 -418C964DDD2EE6F2B92BA48E10789DEC415FA94C81CB95093F71BA384081A7A01D3C2DBB -A934E37E27B4232C8A3802CAB57BE8BC899635B620F54FA5639EA9BFAA5294E57856664B -B3B3DFBE40DFA0E09A14ED2DBE9C47CB032A86D9482D29959E21FE32CEBAB87FBEA9D283 -7044E2161D62CCCF0A3E3195F874F78AE00DAC349EFCBA46A8419CE0A7788B1A2527DE7F -1908F9C67D4C59DFA016D21F61D3F29AA54763F81F2837C5D4DB2807F3E47EDF257588E8 -64FEDBD51B1C169035F1B64D80EE209C5A2315B961D33E4957E11A2225F0E8CA0BCC1E18 -9428EF1FC4BBFF887EDF1375E2768129D8558658D78D876F455FF4F0C65F35004AFBDEC0 -F99C007905DB17D92A64B5D1A390233820D41BEA0F2B732B12BAA6777E96A94F23CCFB02 -2AB8BF09CF9EE6960FFA056EBDB46B04B8F187D05CEB9CF0BA0F796BB494D5F511010E0E -14BE33E45C807F4FD23AB76B0F0E3969010DB86834D787B8E0F92689807033BEF513DED8 -EB3EADA76AEEAADBB191518A950F227A0ACBEDEB778F43FCB3A281F7B7C35F58BB1B3814 -49E40140D8059E950413B9CD3F93240629B030023DD6233C59ECA2035392E64869AF7FD9 -4116ED71B821F0AEE5A68CD691653C2D6DAAB8AFE466D5D7F1BC3ADD65C0AF0EAAAA1486 -DEF5F16684DFD78B7A41F7816CE8A787019D9ABD2F4E4253C9229A2DF73C22DF22B93A8E -4FFC4769448A3E00CF85A939424EC3856CBA520420BB7001372D2F703C5B36CCCFCC5BC0 -1619D9DC961BDB0D9A2FB18759149632141348364E794B15E7BC79420F0711382127B262 -292FBB7F4D0B37A7627E8EC5F5FC374B98B18FF02DB2F442D8DB5ED06F90C3BBB17D05A0 -5D7D11A6A7C2E62F15E7644ADDA44F1A3CC71B61645C7497C242DED8199E31DB0A247C08 -1739BBE040E7CC7299BF09DC0CE4CC6C59BA7D1867CD3CF518ED80959FD8B26748EBFE0F -DF816836E57738FEE205BE2941BF7F155FFF82EB877B7DEE42BAAF4BF2E2057453611C33 -B2FC235D7141ACBCF65F068F2A90A86B8D19B6A0D7223024B42CD6D71C04EE865279A1D1 -6A401D2393058EB9A16020EC8E69943F631333D3C08C9892F8FA620CACC3D1A4F411FB78 -A6CC30F441BE858EB8ED7A92164C59FAE8C5C6F275C2025FC60E326FC2F7CD6EC4612DC7 -1D58EC6E363D90BFD5A93F552F7C3A6DE059A13C14CA2C15D35E1E5E10775ADC9D925185 -1ECE6C1AD5BF430846F62165FB21A393838DC98C2501D598E83EE90B31378D4D92CFE8C9 -869538BA6614A71D3F29E455DDEF8321C2AD78CC2C0A832B3D0F1C09E3B5FA99B121C283 -0200791629A4094DE00EB9AEC55670263DEF10783A699D69BF861FEA783A51937E1BB83B -D96026CD631C7CC3C7EF3BB698700B307079EF2F28F52FC05FE409E020B5E044D1766C37 -55064E5B49FA1FCC37E6D8341525F9DC92B35455711091F1229AA39B397E9ED05EEE7797 -B9A9EFB8FC162EABECFD465756E8B747A3041355178430CB089E1CA3783DE19454F97E0B -3B24813D695BA962CE2046C8F2778B0A7808D046AC0713E1A6DAD26033D153421A24E667 -AA649DA942425C45875437F703E68F68AC5F5AF9B4E087FF4AB87DA00D174E090D834BB0 -14B00764C1CAA2AD4FA2B457858F2784BCA840C7A8BC929505056E3BF3FF533D94C9CE14 -76DA773403FC3F80E1A2335699A55079B6993B0FB187499392167930A874EB1954E6DA45 -C9591EEDC1E8247F237C8657B6FAD992B9426D584E116EBAD9B9F2214A8E850F541A208C -A8792F3980B4CF5E75970884DD7583FE277F82ADC1FF35E5F3FB216AB68C353B25F34C0C -F2C4A60B1E51EE88F7BA84FB1C23601FA2270049E573C05218BEEFD56DF0A648665DB6B7 -81C3B0B503202DC005B8F2F00430288086BC3B4D0625BA2966630F71DC0483FC43DC4AD4 -AFBEFCE65FB61CE89F07FF29B9A9007700503043B24CD9DD8BF9E4714CA99B9504BD7FBF -DAF7ADBAD4168CBEDD5EC802F2DFE773585C5162E564CF1C39BD04CDAA50C2032956EE47 -948EE6628F9EC006711877235813960C9926CBF2372B9329C3CCE4F4190FACCF33B25BE9 -BB4DDEB7E91E8D8ED843DF6F0352E51AE0670C4E0A91E78664D5F88F77F6B9EFFD25071A -F9BF35C2D572275E5FBC2461277DCB0DCE505C6DCDF913CE7A99DA563AC06E1C4B07D7BB -0A24BA8CDFEDD3C16107DA2195FF9677EB104C08C085D6364BCB745BDE0D313D93E318CD -F7929B299185C098642464F491E64EF9A2DC1DBC34153495AD62F886309CC6B6571D6177 -91D94AD5A337912569067DFA1311EA41D5455C24D3B60ED3E698E10978C10FFB9A7C2137 -92A6FC31939290392D8ACD3253593287DFFC13CC9D80870AF32A2B82AD21C49560FABC56 -48FE43EE74D71F0E6D8008100FDC812029C4F1FA3ABE01A4EE9D99A2FA574F93BBC6F17C -7301329B2363DF36FA029621D478A795F9D564EE356CEF0A1E60ED1DBF5FA08590D677D0 -9A1FFF7CF8D657D3D1CF2915BD56B44BCF420FF4A523162CA1791A56287BE773D74F7246 -F52C0D1E22AEA987241202665D0F5EA6391ABF31F16A5BE4353FFAAC2408A0680A33752C -D527145AE349CD781E339C8A9D87E5C0B1312F5B3C150FAFB4588ACC7D6357A5A3B4510A -556A7FAD44643F04BC6D42A23E83640091DC70FBE51B57A7E0EF1E2D6112624AA21136AA -A1B1C6DBC1D1515491F0EE3F9C4338B58E3D0603E1C12A0588118F9261139CE44B5183C2 -AEC863C7D7CAC0DD272FC5142FDD80FC668A6CE709CD7F297DEA655A767CB8A088474BDF -5EC4263121C7B3F154D8396B2470FF226A397257FE5D24EFBD3AE08CEB5CFE9194DC4C6C -147F24D3B36830FAB0AAF03DA1442C1E5E77951538CC9A022370A8C3E39273E4B8E3FB8D -28EE116FEB770A6F223CFFD7925C64CEDB8A7D66212CB443B2A0207EDF102672ADDF2084 -5C2D36FF281B33BD3408CF628D7637F1E92A5D2168DBB183BDF98D99E5A68D9995AE6123 -3675A1AE7BDBD80642E27D6271437F24D28884C90351E819D9785E556334E20EEAFCCDE9 -2929DF0BAC01FF12B56C2B4EED3E554F3ABC0096BC7E5D9409C923E9ABE6032B20784815 -DE1C1663D6EC86D7476A0E9698CD3B201F5F9CBFFBE604C4C2E823045473B0381B1968ED -20DC0D0EC89487B4FFF6F3F83A3D68EE78868FE5262235C3609C6756BE484D87923175F4 -80A084A25B5776FF76742A70F7A60D8B76C3E13409A38A258E3E334F66FEE4567A68BF1C -8CEC4A80CFA0361BF63B7A0D5A0819C85E1A9EC223C0569857D730688E6D177E4BEB8E31 -F873625E39573842035C5C6D66D923654A8FAD9421E1026987A9C825505DB5382184EFD3 -6C84BDA96B464796D72571760CADB46199643060A0552D8DF95A9E6C30787CBD2F57B0FA -D1FA43FBB1E488FBDAE8273BA4F191398652EC86743D32FD5708673AD1D39F62425934FC -AC949F047C873CB94E4A3CCE44A458EAF26953DE54F645CA7B35553204A0F5C7A32E92E5 -27785DE73A3E2A3A3FCB54EA4E395E73C5C89F64B77EE218F935AA4C42106A33C78D03A6 -90813236AEE3E50C2C44323B83401444174174DE4895D090CDB64274B70F557204C772E2 -D1C47C79C1EC238D5B345F7D9CBF27C6B98C5163E6D1D93F23F311DFD594658B903480F9 -A475D3A3D9BF909D042CD76AF8D574D71BA12EB33259C745D3FF5403E579F794EC95CA20 -9959A9CDF439138715101F9FFB3E867A2FEFC41EEE21AC816B7E48F340634714E98CFB91 -E97CDEC4C25CFF567676460102255E8BF37C8B4BFA821EF0165779094CC8ADEBE5778333 -9B9F4DC83DE0360DC52628543D41E0FC9EF2EA434DB9520C2CF5E74863D9BA197F8E7A97 -912643D24CD024E6468A188E0D1E903C48B9A996ECF5D9B64A64E026046E90F5C92CE2F1 -260BC6D4F298DA5A10B3620C4BEBB5C721B830ECC1DC8CDB86AAD6C20C9EB56DE6520D0E -29B6C3EB14A93D43B951CC2C690B277B426B84E4BBB4E1719278150A03C450A9FB44F6E9 -16DFC8986441969A50F06A4483EA651839C31E89A9E4644E96094DE5320CE79DA5499528 -AFDF9C150A4CB53A4EF9BAB6989BA5D0703A4F2F5D4CBC95719C0518DED3474F875DE58A -3A2C369EDF2BD851E5F2E0BCCD47A0452C8751E45DE47CC2C340EF4AB6F4F885B0C2C21C -8E8B252249C5B45EFA5B3E8A27CB39556A262F03A04639280ED71F8D01E12E4FF9D37C3D -3DF6164A4C300E495CEF60F368C4F5277FDC5B27E369483237780072A6709BB6B1E32F33 -53AEDF5A0B1A30EEEFFAEC01A0E9630E5A50BABC081DCF71997F181CC310023AED5BA74E -769DA4D3FA84951BA80EA57C39C805F1C4B42C7673403CDE1573E1641B76F1AE22E57954 -48B4C46AB50E3EA8B82FA89C9BEF737337168E18498C3653AC2BA51C757A15A8BE8B1675 -FCB325B5130E13C36A66E3056C8A0157DB84F7D6636EB06B83FE198579DF5135C77839D9 -548214B53BD51BFC1EBB8CF2E4B1ED77EAF56E953221F95D30D6F16DCF13A57664DB4DB2 -B45DBB6410A9963DEE6496DCADA35B5AEED478EC9297FCB64555373F4ABE73D92B97CDFC -0D83E4D2E80C6433533451BA99E9B2777492AB98DCB69C2AB9737E5A075FA29CB29307BD -315A4A67E7A5519B55CD6DC3E241AA0A067B0FFD337D72FB0B5B290982EE91CAC2504A02 -71315319A641ED197E14017EBCFF2B124E1D449C5A692BBD0E7486686DBEE2F15552583A -A52385CC9064ECC3873A1530112161BDE2008B484BB616459466E66985829F8415D83DB3 -4736B604DEB0E730A3ABA6D04ADE6666E303C40BA9B35FA5C753743239361A8AD23B80CD -AEEC9B8BF6CFE55D9EFAABE474D9BE5F06255EB903315DCD4E2D3469D08AE17F2813D7ED -F8B3B5D004347932D9B38955E27B786CCF0724784E0D545588B51460D9C2572C6E4C4B4F -9A01217FB8F2FBD0757BDC1882292CA04C24E7828D9A6F64B151A4EF2507C3D3EEB98F76 -77D041A5DCBED1BDB61B43034F4F6F5807953BE78631376E6D3AC14411587526E7DD2E68 -9D6241942A0C990123F2FB111F926A68B809DC5CA2CDED30262E71CFA275767F76D5514D -9B7A435A07670F011DDDDD31D8B944151A6A47C6EAF3AE44881252A078F261814A06492F -628BC815F32E0B889863A15409164250C9ECBFAE7A749AACEA6AAA3FBF9BBF40722DAE91 -167BFB833791D3426DF713F829F60F3F9638E1559B82C3704E048AC9879E4AF5C70C9641 -BBA5C04816B4EA6CDA7BE2DC728364587A5E7FFEB8DA7BDBFCB842FCEAF179244EC8B247 -7AB7337897FC0946AE494BC487510CA123CBFAB3B7EDCEE9DA82C37D55AAB651B887E6F0 -5A71F2331B1FF033A1D553186C786C224B1CA80D6693F4F6A948E338BE6CC540E86FEFED -280166B01B5B8F9B278A91E1BC632C3B06A4BC08530D8F1C89A6928E91B8E7C393C9AE2F -91F826E8AA3E11C72CBB0A552EA0261D5912A191127D351B12371E985C6DB66834869EBD -746F758FB0140C248852AECB41CC4972B6CEA24800F2528CFA99E667FD10EE57CF671099 -527AA11667321AE9277E4293811190986CEEFE93FB7C4A1F1A5884BD786B13F8B73A1A46 -19257501BEBE4E2A6BC3DF7BE7451D9364F00EF318111A8E4FC065022AF0EC88040267E7 -BA268C6FEFBA8AFB91120EFE066B8B23E40A0A0F209D3097881CC2B7141BDAF8FF7C5964 -4C029DDA226401B9B98C6A53AF6A93B39F6E3673A3054EEA3CF8CAFADAE0805018CFA969 -7E879B9C31521B340B288FC8910E5B6E061A027A4C69DA1BF038999D693108AFB70D0DBA -A90F3B2C073FE4251064E1FC887AD3708256487DA8EEE60795CF11DEAABF0CCD9CE8E372 -AD4CC8C8DC413B9D2019440173F6F83CC66ECA28C8029C1AB834DF7BF2AF0E0D86C66BA2 -6EF90A1761FBADC03C1FE598D954339A2970A5C9EC56236D9183E6155A511A272D005087 -14F8749B03A5A2B9DE2886B539F1A377FAB65ED3437D55988512B1B1C638015B0ECE68C5 -3AEC61020E34BD8E6AD7659399F0E1D8D23F5EE282BC764249B664D75FAFE67CB5A9DA4F -2094ECB30CB6B68D52AA665BBA751B446118C74148DF979A0FF173364D79202606AC2756 -8D41821B1E4D4175411CD766FCA1C25093E6CE9A37C2048755DB82D7448526B59766288C -9225108E8E86261B57C521991CDC273C0BD25EF4434670C80AF8DB7300F26A9701537DD3 -8FAD0BB2E9EB8F0FC9F2C8629BA97AA1980C39E9BE5740501BD4D57D71235C84C3EF6B4D -CA3D1EFCDF79B8D4EB7C29EC5AB15EC38B2104745E45235A1F37F19E921CB2213F1A91C1 -C392817E7D3AD3A6ED1EC8EE290CF5B1CFA2BF21DF8B9069F4496B7E80E7E96673B77EF3 -AD7B2FD6653510AB77BBF1AC8A07DDE48A8C2AD11EAF2CA95540A164C1B0834106FCED12 -E179477B185DF43148633CE3AF60539493D0C88173C0E63CB5A44790FE41C211966EE03D -424F492C2C87C04F0C28CAFEBEBEA7D11AC959E0C8A88776B4372E356C913943BFC88983 -1C8F95A399DFD02779301D05205EBB921C1F52AA522746CA533AC829EBF7235FBCB0AD82 -69A64B2C68748ED4843FB583151429A1E9537CB40960FFE9C9340CC11BEE00EC7005641E -964F4B0183C49262F3202EB6525EEC66CB68B27185B7DBE343FBFE8BBB34393DA1FBE929 -50702ABD341F45EEAF0EE66C848EAC04CFC854FC058A9418834B4F18E6D861AB31DC1C42 -DFA8D939921067BFF8815B708537A120CDB13E775802C57A0D0CCBC6ECD4CA0DDAD91F01 -97DDD9118990BD71A1CB241B88DDE7EA4F13236CBCD7CA64FC858CBF1E5A38C98C19E3AE -AC0B7B256BA7E15F0E49C84A437DF190A81D0E179B2AFD03A427F2F9AD83DD2A4EA893B5 -BCDA0F09C419FF0D0EE4A811886E2784800865CC8177D4E80FA005C014AD9B124D3D060B -526237FCAF98F23D1F7195F72CDE4E72B87FC4A872FA95441483FEC58EDE0C8B97909B95 -D5FF189C0D49053B187E0A1A8AB85DBB6D765EC78742E334378EDAD7F2FA77E9CED5F652 -295145D463126659E0F6BA982BDC32363FCEC79AAD13248135E6A28222BE0127D807306D -C94C817B649AC020B8B3DDB18CC5B05B83014A10DB5FB9AE6BE4A078FF056EF661B2F4BD -B422CD7E80AE9B6835330AFF67FF1024136EF097F4DD5344D37FD7562802B2A1713431D6 -FC1EFFEB21A02267D7F6B2552C97FBCD4BDE4214DB01C1376F07928CABFB1106B02FD2BA -BDC8C71D0278DCB64375613479FBD3D7D893D279A3FBE92BC92BD99B6FEF817344AC2DD6 -EEF172D3BB609E961180734E1B4C4F4B2D704BA4D1D3103BA4F62DAAD46DF7136070EB14 -549FE8C727CAF060D877D22E21F474F9627507EB1FE2A28534789407DB20FD6D6D9F5CB0 -7CCD392440EDA0E18E1A5EAA7B2C8BEB249A627EEA58DCA375DAE4EA816AEE7BE8BD92AC -AE63C97BA1DF13081EE64198B83926153C8AD6F1C86FA73986BFAA5F0EF5091A4B591BB3 -32ED4334E6D67A0288D390261E88FA39574FEB6F7B19B808DC87426BF13BFE2F76ED7103 -87A5283D27CEF752B20D831D8494A2E35DE7F68856AFB67B6EDC883C45840C6E83F1E9D9 -4E4351D50BB9A03B0F0B0527CCEED0081C96A029EF47F68A1BFB0A5DC673A0C8254216CB -D84693230437E107267B9244E2287BC6CBCDF73B24DB5B947D5738568471FA1FFAC537B2 -BF13C99D56230D49E12AAFDF51B03265A9A14529147FDE45C234282644C9BAD0C6892861 -029C9F27E4AE13F8278E135E89E81A7E552B11DCAD49507502B47B1580A6222672EE9C3D -A05B74A4719A849179B6C93BECD1F18FDC9CDB1EA52ADF96D29409B9B9DD63861A2C74F5 -1A99843FD141AC60A49FA6A134FF4C4328AA9D95BCE4B89B4BE4CFDC1DF3603DDB0D7DCD -E1A3FEC7059299A216BF88469B5C9B16C20680B14D414902E8A7D80E5429AA24D94EFDCF -500C1F1ED0F3853E2715598355B9440AFB9A8D06F6C038EBE0574B24E3A168E93833F462 -B24FA106DD40C967878248B2E1D58CB8E4646DE1F2B5BCF7FC02B4BC7DF7593737F583AF -03264E5C35FBF1227DEF2C4F6889C2F77C3B84638CB682645D0F2E99E0C4EF9ACEBB11CF -0F658F7D3163C488C6E642B5B03C1E40F69BC2293497374FB157F42111ED5B96E04040D1 -8C0020820B37A22DA38F4E21A64FFC24131CCA0F575529157E9A59EC6546004241A8F51E -9E85066AB22B72FA003CC868F965DFC34A2A0055FF86443CD3ABD3EDC30E9196C20629B2 -AF3A1A0C42C88C20449F889A39BDE45EEA0551AA0BF0E9641D7D1FE0F3C286C7EE34800C -20A72C954EEE657FB36E10ACDC18D165C8DEFEC48D154FBA121CF1066508A075A669612D -26B9309F2CD33B2109AE9E6B1EBD4391F7B66F625367766F8CF0B8BC2D201124CFD9920C -B61F71C4781B459ED271EED5937FBA4359FE1DDA7F3907ADD7C15ED021E7735985E6AA8E -F21011A13E5CED0B69877C636D293BB99AE7B9457E8C4B84C4EC695C5944622B5F47DEB5 -1F3D653C7ED73B53D16B504E761B8C105CBA84E45B408B415045310CFE8D693AAC924ED6 -C61A12C7B0CED04E630D8A04F8838F286E646960120FE35D0D13F9E273DB647A999F1580 -C1448CDA80B9489BB8E5E4507A7A5B5329A2E962EED597E4B7C4E6C72740EEB351A3364D -0B0689BC2658395E2B69A8FF0600EC50868404BAF6792A59983C6E372DDBEEA9953870AD -319849F018362B016EC38C0B7F947402449352CCCDE055068417434416F0475EC82A5441 -987A472F59AD152C56FE81F1501E88D0BA843083736F783C366CB18C8A787FCB60E6F8C4 -3B56BD458D9A42FBFFBE128C928DB06C7BF8F2C0FE209B25DBE0F28C1CBC8328C8E868E1 -F1DA76549F34B6FEC13E1400B2F9A66E00D89CAA99B2DDD6A0BFC73C09C7D774CC05629A -E23AF62DD1E58D3843EAE55452281A0DC2B31CFCE75A7FEAAB90041602CA5293EA58F8ED -C18635ED0234B9799A12388C2AA469FEE8CFE1B112F7BE610990CD51BB13D955CD02D571 -323F565D7BC240FE71E3A3A1B92BB9A1C7EC2EC6406F06AE7C0D14262319D389A7CD8D34 -D41313DE9B2336963A5EC892A8051BEEBED24ADCB1F0BBDE77C4E3AED1D777C0EF2F1AAB -DEE62B1967964C98CA08561EA234879DFB0F50BA067E1462CB63544786D56935ADCE3E7B -399B1B3D0098DC19E4EFC04922CCC28609390A7B163D66853C2C8FF94591CD1DF499DB82 -F0F6FB7FB6D3571735528F544C16786CFCC7FA10D28FFBDB6C455AF2A6E1F6BECC080B6B -EFAEA5D51607A260620EDD1DC6E8AAB588BFCAD39A98E028BD26DBCCB149D818E0B91BF0 -8AFB55C618FDEDC15ED7055521BC90689E61965FBF22172F584827852B6DCD8FD466953F -D16A806E20C5C96064F28BAC94F3A7818B18EAAD9BBDFA0FC302E663B989D97A76E925C1 -CD1307E43C97F88DD731AC971B862E99633A531788BDAA4847A1FD124660B00000007168 -72191B3F124402B990F3C379862AE823A3646762EF68A69D3AA91C56F50B10807C915447 -38AB8EB6C01618880F72A6C2DA6764158320CFBEFC9F23A0C1DB0AED395C70B28C4D47F9 -7C5018499E45AE5407C03CDFA41D02E18F7AE56346D872B03CD5FBDE0D0DBF11C1FD313D -E0A7856974BCBE0EB331CE51D190BFDE4C08BE9CFF6F2A32072454EBF4DDDD1E3B9CDE7F -9ED3B2C1C5C60A12813DD88D75CFA6A9CC4583764D40C7001764B69A739EC079E7ACA5C4 -1DDAD7D15C8807719EDCB3054D9DE3DA92912F019B50B62C8C4AE9488CD7D683565B2031 -DBE9E7573595ABA60602B6023C1D4DC8370A529873DFF92DE908CFBFAEE97B0273CE36AE -6C931F5282CD2341DAC0D6DC59A693FF4AE740E77322F8073471F6CB3CA99E7A530F5E82 -7E4C5185E015655F784855E4989F27CFB02AEFD20C3D0E9E4C1346ED248A6EBEE2BCEB80 -1B912CE4AE5475DCD5D0516397CC74589AD3D52E70A9DC423CAB42BE428CC2DFA56E2C9B -DB4F083F8A7B3B2B9063EAB3FC255A489707792141F87A2FCE77B89AF7099DAAE3EBBE9B -3655691A5538305B664C75DF2DCFCD53C87C38D9EDF8F7DF8A808851ED31E8348C77CA4F -3AEC6C2BE721FA3CE9D54B72B414A0992AC3A9DEFCF40579F59B0E30EE3A9B599772936D -5E5B921D5693FD702A30BDECC82AE6CC10132C2B6C697326CDB3201D35C4396887B5CD1F -1909A0C3A19BA71AAE02E8639B6AD1426866196F0F9F0DEAAF8BDC53720674296BD41161 -DAA21FA4534BA100FA41161734E310C6E88B8BACC050174028F4DF483785184B30AD1BD0 -2EEE2F93A187C5F48EB3ADB9D63AA4D52D76AB07B93CDA7F12F3C7D9E58DB297D2048375 -5E5C6D1B8F9C5C07A142E0A68177BD7AB073CFB934EF14D9616B15BA2B38AB4FA4B5877D -04F5308D74D642B46352FD84B4FFF058C282D308AD2AA99270964618A04C0E522AB7A4EA -123FEC9A47F13060E534C0C58C327B063D59CF96413E176031FB21F3AF9E3BF1BA6521EB -C71336E468A8FFD6AC2EEAED7ED016D2775AD2A7432534704B399BAD93E0A1FD5C8E6FDF -E8DE157ED4FBFA62C5F0D12DFE4C519713A76D6B2D35FFAC7C0B90ABAA8BEC8D2221FA39 -5685428736398AB87F9B73F7094E02A5019A360FB5E0A2857AB2439999377C9D4B1529B8 -D8DC1EE0B68D1A5AE1BE39949A8D53F9274D51650124E4BC873C07FF0786CA64EAE168E3 -B8E0210945249FA48059080232CBCB56A910E40D14A479F193BFBBD701384407A2DC56C9 -BEE9A4F3F011F02D0AE09C3F6EE0808336C70C6BD82525858EECB6521238C717469BE58B -6865E2E9867FC248A82B44142F5E825665F6780B03015A6CD2B1592F36B7F1C03D58DCE1 -9588FC260148D0DE42196BD052136CA1BD82BBC0AAAC6ADE4500B9F374DCE51779697BFE -670245D126066964B61D59864EB636C43D6ABA70429614DB400CAC2ED06D85D3E7C3D9DB -B5E2E7EAD6031B9798EDF30772FB9CA88F52D2A56C1CBA8F95202DA92870CA6EAD0358F2 -183C791783746255B2E87EA261A1D9C4B7B9B4174D412BDC01F4AC19DA76C423992291A0 -B0B85C1F62AAC83B253D8C251DDC43D921AE994E7122F7A49EDC473B0D9B71D8801A0D43 -B589E6C1395255D3515A637670589D6BF4CB75870D2BFF2491B7DF7EF95F04C0531C3C00 -6BA3CBFE26F52EB9D041DB138FEF272218451237E60685E66390659CB98F178E3BEB8834 -6B1E49C6D9EEE0677281D460E3AA55250A0D8D37DF9DDDE21F002A70E2F9A22F0AFAED24 -80C169B2BEF14DB7E75ED43E2317948F2F5F17A8A301E5DD65D1950AFFB85A1B4A26AA89 -104519AB57E70A3F506453128E1614BF850F371F29A9CA224B2B258C9830F3046D4F1C8D -3DCA9AAAC020617CEDB6FC6E1EDC69E17812FE92EA38C97ED91987A65C72FA48C353326C -DC7BD08632C96BF3C9A7C095391BCD9335E8F254E937A77855854EF20235319423D2DBC7 -DD2435B9EF9B9CE1046B95421A98E910196E802263650E5D2087E34E384ED7FABFB6DBDD -48342333407D7163A1B1031F841AD55FDBE7C1553CF17CF057652E243CDCFC8F86D8911C -C6DA2FA6BD522ED649C52DB102498790D6D55EF2AE27790595E8D8489EFC05F505566958 -33A31087D230F6041DEB7173D2BFFF6B59E643B532C2649D4902CA7FBD79F3347ED28EDE -D5EFC41B0B6CC97F6165806BABA7930768FE8E4B8313A5C9D69BF0B029CFF51B9470A22D -98A6257A6BC6B34F11536130A980D985E24F69E0846C395DA6C35C036940E609F9677B0D -EA2B923A92626EEC8E224E2BED76CBCCF6F2DC14CF8D90BDEC80E7088CA871846C68247D -C4912B6DBAD4C97A472C1FEB6B2B460929E374B23975046E6081E210116ECB0F3680D99F -E7BC4794EA19037638DFD2ABEB7365F2A7BDFA3C7766B3FF642F0639D897A3F0772EF880 -EAC10E1BA44C207039C64D2DE51AB6F71E703F36B24F9BCD0179853B815DBAB59057E8F4 -7C74B338BF128922C8057518CB7FA34AF8F590BDB76296E4258570F5CDCE24B4F9755C88 -F4F3CFAFFA1EF7EA5052A2C7D8A823D0A1EA7740A726FDD7B1D28D17B01A0EFCD601F20E -FEFB1688FBB375573F54EA1913230461B54B64174D7C99ED8A2DD269CB60B02050A2B300 -C0E7039663C388C4670BA295EC5BFAF496DFC11816ECFB433AB94380D1982DF52B362305 -289A0EA2205C91DAD93A6428491028D50A987C5501D0FEE5509196EFD2CD36D695B71289 -E2A4A96BB065C0D9242351C6A3732E49D51B5E472F9EF2524716B7478AB7460F43267CE5 -6B2DFBEE8D34E1BA79A57B175D8B9496BA2C806C2F6CDFDEB0DCCD0D813E79E766FB8548 -9087D61E7506F04102C2DCDE9B44EF10B38443F7207B707A265E1111FC0E411F04A64524 -3465AE5AD4FEC01561DFB4C1384B8FF54A0AEBBF189822B63ED986B8197B3B1085087B01 -B9EC606AF3C1CBEF701224ACAC1BAB4DE76FE28BC7F538DF318EBB3CDA0E9FB06214F497 -BC2926399C79CCC70A464C2B58D51A52BF06A5650D21929E4C2EE5AB624F5EFA25E64B63 -2ABBC3285A79C5576ABE016283D08E19246B77166612E83B2244A1BF5A7CAE45A691AA7D -BC31377285E78F094870584C23A2216453B9F0804BBF32FFDF810A2DEE41CB2743472A57 -D050F61E285D232C6EA0C2EAC1C0FECA0E489970C7B83D6F1D64B187BCBDF29815CAFF8B -8EC2AC2705DB255240A5A435A0B0AB6F2C9451C7E14FED26DA327D432A30B672CC7E0D99 -8653AEAA0DC7FB4161E604CEF7464934795E01C7CD625A2C7C4988CCD213C19CE963C6EC -F45078DD17A158FB2F9FD1241FE5FE0C45D05AF19E5C5D5AED76D297414EBF0E95E451F8 -B61EF47D7A80B240518FD2BD42C53B96BCB17F04B850CC889859887A2EBCA1499C10D034 -D545C5101EC917FD27B1F87B4460B8D5036A7072070ADB83573796D07A4C4C5348FA845E -C31C83BAAA79D880FC9965C08621C9BB6A982CACF2E9076CC88F14F4E2B1403A980AA310 -33CC1C16B108D3C390F95E87D6DA3FB4E9AEECA82F70424F82C243D0F0DB273FEFA8F57A -CB2994DF51CCD21C45A00F60EED00CB7C2CB6D131A57AD4CC98FA2BD0313E15AB964221A -6662B6319E305F2D2255741DA5465C9602E7AA3558B98B906B4AEC3AC8CBF877E51AE0A3 -CD1423A0AFD38716B0B74C7F492412AB575D9DA05634E20D34026A1E02B58806AE95378C -8018A42F273FE95E72C6E8BC54646FDC010E807B2E78AEE753E9A223B8B014CE464AB7BC -5C6FFB19A0687C0FD300BFA19FA2E9A65FD2A4BB8B5E6967289A70EB18821A32CA0751A5 -972A6F3E3054E10972F59A9DCDEFC5DB1E9FDD87003B98228BDDC733DF066CA5490A902F -2930EA9C937B586CDBD433532E6230F87773FFB354BDEEB778ACC289F3015C5158828790 -BD620956700DBDD6C2A9CC76FCA2868936D279495651B5798491478B1B77CE6656E8FB2A -69FDFCC2C8FE04C5C6AF6054C01678278164ACD9CB8C7BB41E0A4A4A3513283C38B03B6C -27E66FA995F58346B724189632494406D7B8E6CE243C5BF1CDE8C87AEB0E6F43C52D5D3D -4F3F9C876FB9ADA96302D73FD3DD51D82E1314024C5B1262CC009052C4E598A2B7D855B7 -BEF4FB97D65D8B26B69CA86C173CE21A159B3765FD48A6E978137FB2C7B9C4A39A94EB09 -A9825BCFB87EDB546D917F4BB3B618906C643280D3A33CC87311002B465D440C5FE3B8EA -1C3AFE1CBA90999683875070513E14D37D5AC6214D5E38748901D3740350CBABF87ACACA -FBE7CB2A97332D9BFED8B0A7EB95BCA79E8D4D6A80C1162A49C73961822A568D43BA71A4 -90E3571845A95B8AC2313098F7C3379DB959167CA17281F8FC7933F10BAF70A573981F5E -02810780D9780AE94EACC4F4A2D1BE14649E1B776175FB5EAF25DE613686161995472B24 -86AC004708550BCF2CE0CF3032A02BEA90E1163319C20894648844A936D39C7A266060A6 -093B59CBDD59E4FC67AF429BCBFB4037DEC87FD9CE0FC26D488C1987E0D6A79AB19A7601 -3C3286ADA28464BE78C5C591126978FE183EB480403432664318992C47600105BD1C223C -E78F8F5B3C1C56F298C28B700886B9E467E7ECBA6BFD0BCA114CC74CFE8252FD9FF4C39F -AD3071CC0E832A9F4BF89F9AE4FFA1FF02CE797052DDE080C175AE529C61B639D842BDBD -B8D349090DDA8F503C909349A69BDC6D972805B15D2E8D321E9296E3E0965E7BDB040FAD -CA90D1BE06E438AB653E7553EB43A4430E3AB1A43BEB97715FE97A8B76A7B5B1262DAA01 -DFF0259186017062090F6B9A35B9962DF2F7EB85B6D20A693B1D925DB4BF06996F60BDD4 -6C2381937E21B3299CF3BAA565727DFBFCD38BF24143D400CF99A7F3D09D17D5E1CBA49A -9C607D434EDDD31BC70D277CDDCC5CE03C001B53CB1D448A87DB676F6BE0681BF57F66C0 -43BA1BF6889DC9F054A544C4D498B74988D5DC13262AB95205386343ED6D3C077B058B57 -4C464D02E35DD342CF013B84CBA67538AE13A3F50BE444014ADF085E95D736139E1646AF -7C4A401E25B3511364DA040AEAFF801A664E71B0D2C6E46B510A97D5B75B2377E54BC7B8 -C4B368602743EB5856E4385C4FB3F364C54239B5794F69E39791CE5BD967BD03E212B8B6 -E14336AF3900878E5031993E3043B23376975A43CB032C9D9C1E485CF34F3A1F2055AEC7 -9A2D2E68CF82F1CA0DDF7200B9FE4172947540769AC5FA6AA53A87E6A79AE9CAC84C0FE5 -F0C0752F85329F95AB21AC314B7D32C538E70112C12A34DF2CE7127E5696F88CF65BD083 -5E57CF98FE8AE4873FD1EDC9F775E6920E87000CAF9C8B7FE3CA5A84A5AFE056CA8D5610 -69F8979E13055582F11FADFDE7BF60FA9EF36AEF0D85F29D94CE5C571574EE03FCE5E5BC -A5B2D3E4FA107FED636226B59D00CCE51BEB891DFE12F04BCEEC13606B051D5A50B08F93 -D0B3ECDE4EF0DE6E06829E559BB2AEBD02D0B7A1C505743ABBFE54A9682123C3695E86C7 -54465D3A60369CF9C3FA800658DC52000B8F6915A9F5549849EE092CFA885BD5FA96E6E3 -D04DE784BF6F17F333AC90FD8AFA98ED04F003E47A44893E943B6504791D21FFEE630A7D -026F82D0B903496D3E08DC35768EE6FF9AB617D29193A5FDF8A0976336297CA65BA71A1F -56E19EEBAF4AC438B9807AC1F4CB0DC9F740910E2BC32220D37A337FECB98301B0A203DB -739DC361838D4577296B9DF5E1DEF57DBFCA489801685288238CD8DA085C709663DE7F84 -127FC9E6C4FCDF327532C87635A6D7822D36583930BC9FA1746966A175670A2EE77D5FE5 -DB0F43189C37191F0ED80A333E8B117508E17C010FDDAA44820EF17FA9AFBDB754507F4E -1AC0D09A0FAFC80ADA11DA469995CD7FAF67CD8E29AB323C03B6A1DE80B684FC2AE84B46 -BFE4748300EF789A12A166FCD29ED3AED2FDC431BF9B3A450E2B15BDCE9F15C13E4C28FF -15E145C661B3EF6DF748C32129BD734087B8DF6A5C00B4765F2B518ED29FC53D283587F1 -2B62F177D14E3956A64C425AD811AE6833F2E095AC0F7BED54333095002EF33824F6A7C2 -3CD332BAEC7AB22642A5331A0C1656E3E2E4FA99825B5F1A04350BD96AD4E491F97E47C9 -F5FDEF0466EE0566D5F2ECBDC2C3B0DCA65728196BC139EDA445C7B5435E293F50C91CE5 -4FF3AB7112603BE44D41198C3A5BF2CA4BC460C0BD8D86073948C452AFD0A35CDF30CE1F -AB58276DC2A49CE15CB2C1EE44E0C3E07D73936CF675B1A40B1A2DA5C61BFE4E56C92FD7 -CFA03B2D6A9A108054AE303195132BBBCEAE17F83B7B9140BB11DC6D2A3B17A46CE4FD4E -0EEB5FDBF8028B1E7052C602C5E7BC63D6F6A9172032D538B495C3D8E3DB6FAFB0CEE41F -35884819BB65463B11378A7526B582A4D2EE1726615B66E8514B4173C47B399F86ADAF7F -E7F7C08A707A30AE31400B603A31951A7F617BC16E5905ADEA0197382CF2F799F8ABE8DA -134FC37C99767D4ADFD45502F189ECF7D08471186F4D29A054DED0C5AFA56A8AB3AD5F3C -71D784803E0237F41B764C6A91676BF4623E80803231960AF3B941EFD842235968071455 -F1BECCB46F437930B443A1C4F681AE595A7F7057496C5BF98FECFF07CE1B4E3653B7AF75 -2F647322BF2FD773C8C79B305EA2365EB878FEC55A277066560401CCA10AB996645BAE4E -728E34864C7F2F0ECECF66C0387B2DADBDA23EBC4C0B904C5D152C9856EA1FB76D10BFE0 -7213A87551081FDBEFC207AE33B860649D445724095B28D45354590E967DA4960814E184 -2ED400AA72982427E378092623D784272A07450265A89A88C13F0A71A03C4234EE525034 -2F5F28BAF685A2D8AD6C195B4CC3ED9DFC0E82910D692ADE7236347002251126C4CF7C82 -175624CC08445EC64357BE592FA06FFE3FB52720F4CCB0A78173F0BFE317F2C22EC52607 -C9479BFEDD6FF60EC8F1F613251BDDED25F2639E469B344B86ABF4BAA8A9E05C5AA49C91 -826B39636461E805364EA49E222129B12D357641D89411DC5081064473E78BE378BE642D -16B4CA3D926E508E5905AB84C588EF25E3AE064348C93A28880A02B0665C2486BB41BCBC -8CDB229607ECFD58E01D99D71BC1AE9DACE87D02D7567D570CE3BB7EBB5877A5E309B181 -0E75AB6AA6E2A72B9DAFDF89862C96141D72DAAA090F0EC8A239F1CB565C7B7523ADD890 -76109390815D4D128B26523BF36FFEEB3D1DEFB8C44460FE64C11F1183A99BBF9C5D7BAC -B644531BC4873EEF693B2E5401D764F0172127F873786FE8A95142DACBEE14E4B1E11E5E -13B3015B6344C9B27CAD49C457FFFDA86E0097D8533F76344AB561593CC09BDBC1758F07 -9F31AFC4BFCCFDC2D54B8FA7F1265E8AD350C44C940B8111B4A59D078423535205A22202 -92F892CC2A5AA50ABFA912D6FB0304EA164E191CCC659DA1E00B2DE5A6830B60D69AC9D3 -CEFEFC2CB0DC016B7FB41D5853A0BE141DC15CAE07A90E56187BAF3716B7A7CC839FB123 -69DCD8656F62C1E631FCED16D171A3521ACF60675FFD2911A20DFE45A57887984AE2C41C -A8C6C24A12445E167CAC1A3FAF610DDCC8649C6F6CF07AF89125C6F37C70B682BB77394D -F4F6E7A111A0ACA9CD25E1679891B3FE9FDB3EDDE1D3805DF7C42BC5FE4A6D91C7042F67 -6ECFE15B9A90AEA755B3E032C60A71554102A9FF4C2E9E467F0B7DB9CA0F2AC3CBC3CDFB -8DC2A7365807E409E75E89047415598A8720B25CD32FBC18C12EF6E1F9A193132C0DA8AB -134A567DE1BA0583E12BA2045A36C298ECC4F909510D29ACAE1EED825ADA28437F457BE1 -94FA7EA3ACD0119F438ED2A2A31BFC511BCC3CDBCDF34B6DE3DFC6F4836178D9BB35BF9A -C546AD2D1527D1B020D2A975E83848CC431CCDAB997A195E2AB6B3D5A8980D5824EDA901 -EDBD85AA2B82480CC76BA911F2D4F7E2675E69F4005412AB2E88861A7D925EBDE0799075 -F858F32B8BBEBE0F6138D4C8AEB2EA647046C533519867FCF286E04AB146CE6EF4080A8B -2026BDA70349038DE8C2B71B2B2834E57D4D486F95CAB49C4DDC2DD17D8C959101CD2DF3 -D9E4E9FEC4CC05B2490A90A30C898E8588CDEAC838565BD0B6B494F2DFA565A606789728 -0EAC877E47201EFF4329FE524BACE5E90E8525CA1F5206B83D1FBD284D1109651141B4F1 -CD1D1F5A0406B90E4FEB435BFFB60BEC00454F406B6CBCC3883F8D470226A8214207DA07 -76CEFA99D769166A8327F8543039B44FE297A1EC1611713846E67B20E0DF311F715E4CC0 -3D1AD8EE1D14FE0AA2D55D1C30F9C1F12C9D8BB8E5429FDC4247AD4718B634AE34213480 -45B9ABE0C2E231914402548748A388FFE3D5148DE9F9BE6CDC21DEE4B5F9FB0C3A52EE12 -A9B23D6815E76979C6266A811157E380AF6C7911D55DD522FB766932E2CD361406517268 -43C8C1EA841219D167757C201022045656A45FA93AEA1B404B16882F20BC30B36FC2DB62 -96DC200D567BA9B4D49366EC4D3AF556013DA5878F04B437257CCCD164EA4460E472DBFD -AF091AF1C2131C55FD31E7DE78BF0380C4B34C89528CE0A36ECEDEBFFB34DC33AF1006F7 -EAE6444F7F063BD1B1B9C88850B1997D3A24BD1650FF98744C9A0CD6F7246CE22A1A91AC -D1EA6FBD9237C32B80D6BF79B40A3E622E83DFF1366BC6B7B6295D5785BA00342C146BC2 -527FCF50B73C17B76D6B4B0B98BE03BAD8A67C7D547C866DB6FCAC78C69735F26DE9FE2C -D9504F5AF31727791158F17D129677F5F9BAEF97A1899A7DAEEA53E70EC6C822C3F893B7 -3A4C313551553E902E762BC58D8D1E9508D9D3355D5FC528DA87BC94DD9EE305ED737379 -CEAC96549D3E7E505A13F11EBBF0BEAD38601BE5BF68B1EBBC504F8D9B4219307F7DE93B -EA6B153F5BB35E2B50AE9309229698580334EA4590E06E41D834EF86DECDF64687DF0258 -6AB142A457531A9103D49D0D64FD583046A107210FF1FD544A8B07EA3DFCC04ED74BA498 -E927C72907E896B8E6C0C0FD016A42B6F45AD628761A78C405C51BC07DB9D90D54674B0C -62F43785115A94708879349142D612DACF210116A3EE5F0AE9EFFFB694C328C73EB4FA11 -56E38C4E25BFCF9F441C2B0A6752091DD9F9C2175495B973CCC0EBDCD43125CADBE4DFA9 -3E11EE051D6D46B0B8A8C4DD6443D392CB7801D131DD58696594B1FFA5DB9D70F46E1C7A -84B445E50922880FE987BF899BB603CA937D4DD3386C24D24AD31038CD9C5727AABF3DF3 -0FA105F554A39A091655147C8511B818A5932FA9B33C2B1DE319C5F704BD439ED6E1B8DD -FDBFFBBB038B350E1B8579A1B2F55B24FCAFCBB6905F24C82A3FCE3374F979405E69BD62 -6346E4531E130DA4358CC11FAC6E705228CD1D4BD865DE15F2C8629E77CE5152E3CE5207 -D42D9265A4F27C5FC3AF11712F1736F56CAE5DB347163DE798EA934C189E5FD6ADF49DD8 -4E9692559753CAE3584F3C43902F775B9534A4B541DF22DDDF723339562A5785E37CC808 -47E59091A5A339467B57F15902EBD2399B55A19E098ED661A475A559E465A502CA339B3C -64A55AA28D3DDF57133DE6FC6443B563A0D49F898E0CBF45E55748AEA9E7A215D26E07B2 -C8CEBD2D9D233D8E86D53D079691EA21DE11F9C4FE0D3C904C5FDCDF2301BE7C896C2FE1 -036C2B3D9EC21292BF87593E27BBDA40DB83CA23F65C56064816657C97DD53CFC7FB54E5 -353730E625C5B31F030BB0E1D09429E6C6496EBCB17C114667F9B8A31ED328AF0EE9E7F0 -1AD0E70AF25BF2BBE8F99A4AAE42A6466347CE5FECF91355D61A312C550AABF782CBF1CB -649FD914B4AB1EC2BBDC6EFD65621921858E9CEAD02447DAC2CCD4D9D880BCB1513A5AF0 -D931F417C1342554E7EFE9529B18CB931453AFA51E2830037D2DBA79C565EDF25A0A7059 -315E242D82F2A32DACB9D86C62658FFB7E5A11D00B59CF45B48C1682FE8FC4A4FA41746F -E6F734D86B7CA91C976D40B64601831546DF211405F1F44FB6B8FAD3E880B74B66A93783 -F12CBBA01B8D456A1BB0DB78EF455B230B53F95C4E7B13EAA9A8BD49F886CEDBD9066819 -085B30488B011B125737F16BB6B31908808E7B076BF88E2F23684929602C888BB3A51D29 -A3D8DF55B39A48E5115E686380452EC5784D09C44ACB5EB20ABF8DFA9DF66344BCFCF175 -A877296E511AC83765358D8C091B91A6C70AAEF9A66C2F36F6387D5795B60261381CAB7D -9A1EF15EE18683C485317692DC0CCC859F5DCF51C3930355BEE5592A9E5DEE4360E8151B -582E019C674501C0F27D1EEC05B1F55FE9F79C5FCA04AEC51BF01CF8BF5DEFA0C9DA4DF1 -0D923E6E56D35364023C84D9D71D68168A73ACA6A6CB8304C1A830C3CC7155D9C5141DBA -165A1C733FF5320A1D1028B7B543D2A1516071D0C02AC030E52BF79E464D8938294A7D92 -5874AE6FCB352EFD4790F6973A627FD2979C19FBF19D2870FAEB6BE729D34FED4C87264D -65FC15436A57DA96DC09C7CA864CEE0D98AE9C498F258C4599CC97A1B9095825760D06A5 -C53E257F54407EF4DEBE04606D65E3D09C01535736D3852089D8FC0D2CEB60BE19D959F0 -CE1858D5B4B72A953FDD1CAB16B1768236162A67C1B77CC4DF6393A480DA4223B65C9747 -67A08C86DD75BEBC418E370D5C2853523D68852E705A4BE611142EF56ED90583181D8559 -9AD285830BE0986BD8FABE86377F5529A5749A30C89A272711A694AE29E2700034B6B620 -5413F9BB288AA9B0BDE0E91CE8643E96C8A771FEFD1EFED94DF8D67CABBE928E3A845723 -BA2B85A2BF2BB4F784F2324040C42292BA0966DF1A495D7DA80B9B79F76D10F1A12D53E7 -A16B3175CBC39C1BE14A36CA1E3C7CABD9F8DA323243F0703C3BBABD48B1CD35BBF2755F -2508FD2D66FDDD1DC21D232CCDD7CA5E749A841F82EFF35249BD72B0820CC69FF176164E -EB3E885E1DA18762FCD40761FB5C91D692F2678BA2BC45CF1BECC0A8C28EFD62D1EE29BC -2CA29D922AF0A592E19AC004573F357ABCFA00916487664065D3864EFBC54AE0A70952EF -676B5087CDD43D9540C784DBAFA0C0ACB72E35CF6D82789E3352A16D379A4C26118C4B5B -8E5C7258B2B9082556A1B018085F19168CB7787CA06283382260FA3743D036EC4142DD7D -2654BF95651123718193310928CE49B532F6B26181B078228B97B4BACCD79F6A8DAF1004 -096284F2D45BA3BA14F1D0CAD558239BF696B1F2D6F6AA2D11693B497A7FF12BEB36F65C -C453320F8241820AFA96FB54E83DF38BEA9C7A004EE4965EB7104982F4D7847D397B9EA5 -9F93C61BD259C3BAA15323EDA020E35DD78B7FBE6D7CAFC5C34D9C8A60B079EA6A3123FF -B7352EA72DB9BF6C80E7D97AC188A9B8BEEE3C80819D35EDF1CE62AC4DA459EB208BFF41 -4A3EF9C4E3514F44EEDF60CB817EC66E3D698702B5DC889EE0C064A387C7487DD97B4EE1 -2792DAB796E4123E9D7F3191B22F2481A4602CFDE1E708EC6BFA63C771058B380EE6AD48 -2524F9F1FB75D470EC11226A138F4B9E5360AB443D5091B324271E8B251297D8236E3C5C -E92AB19E2005DB4A8BB12950E6A3C47C16229F300F8BDEB8A54211BA195589F6C8CE22C1 -A32B3610EF0E43458132703F86AB9CCAE7F99CD7DA69EEE32CB011EEED797C841ADED034 -4BE043DC76BC7E5F877620283E923259EC2100FB83832D104A256105EE8FA5742D7E252A -7539334AAACF79E4EFD98C32661AFCEEEB5A9CE44B2CEB765C6FC6B361E95CBAE60A8680 -D2741C9AC12B834BE5EE4F498B1FC7137BCDC32A225DBB86B1F342BE3FBB03A17624066D -2D652F7F7F8D431AE8DC401FA2FC64AC056A9F29DFFBDE1E07BA398624F3337B6001D1B4 -F54E9E67B059415D43144EA8DDECCB6B57022B678CE554EC7979BC4DE26BBDA16059A3F1 -16457844011864CEA021FC099B7FC141923CEE982E2915C6D0C28767027E139BBA2EB02D -49DD1B247EFC7A2A1504C4DCAF35305671CBB20B2BFEB0EAE475ED4AD53293B94A6E6AC8 -41FE1E9CACBADD1744428F6F992348A3B1D391CF65C86E2F1E57382D245C920C7CF3140D -6AF604F686019AF155ABC0B0BB9835FC49755277A5DF9E6F0A7B8E91EEE7A2287704D71B -64D4F6D0C927DF674B35A38E98CD7ED00B76966B2E44912BB1EB240C25AE3DE8E7668062 -55CFEBBE98D8A49657D1B230F8A9AFB157AB3BF74C8485F5A275B2C065797A9B3E1021DD -7FC20AF45DBB60346C53E3CEEE031619153CAE0CA4A3C25458D73EC46E8B7196CEFFAD73 -6243CD4F81D73A2A7D0C3F58DFDEACFD4330655FA5082CB75FAEA9B99D8BE6A0FFF920FA -9F8AA5CC2EFD3BD09C3B8A94BA03D1411D6AC5894A8402330D5564AF8E75AE549A11BD49 -E15B20F7879DAF938B09E430CE1B57EDD9346CA8AF022DE5548A4726D49E8DC439D7DE79 -7C006A7AA78B018A1D68E15AA83FAF97394FA4F0E1460DA5AA9710656AA1E294016F2F8F -D7B10DFCD2D10AB59308DE6108C3D44CA6B5B1A0A5408E6FDCBDE1B5CF86CD7A9F815146 -B9721F11ECF3EFF7640EAEE03D8D3B4B4F055C6EA18A7FF129F369A1FDEB7B71A3223890 -BCAE11DB2848941B6323221AD976E5986280844ECB67C4A1ACE6BC87517A2DDB2F928A01 -8727B99FDCF0D0CFF57A0BEB04C7DA62E41E9623AF0FA6EB651E0D1C9C72140CFF8A7A2B -BBA67EEF1AD2419BD5D399E09F2BAE43881E8AC834E46F6F1C96B6EB4DEEB32637DAFA37 -89C2BD92A4989F9AD822A6483D516A143EEF6DE93ACDFF3B118F8B80865EEA782EEF6DEF -D8E5E9252B378E3F09E770F38CF1A71A5CA9E872EEC7E1AB4AE8B4DCEA41630FD47B9602 -81A711304DDA075014AD733B83D5631276F636D4A470C1DB8F5B1E1AC5B005FE2B5B4D79 -346B39D86048D7066C0F5476FA7E8A8F7D48488F49507237719121AAE83EF6938AF31754 -5C848CE4E8A118A8093F5720CC4884D3886A5BEA6312782D229ECDC11D4AA1731A5B098E -DAFBB3EAF2C539FBFE55E96C1129EF344000D8DDD7C7CD53196B27AB252155A634FEA9D7 -971E3079ABD8F38DC7C166B5DC2D0B1C66D776BA678C5C57E8EFDD55EFA2F5B5FF8DADC6 -0F18A0026B3159C7FF28D5283E6835147CE4D5E5ECB6A8E537CDD7F8F7A0E7B6FC53292E -FE0F780D9B58293F527159A8440C09FD842877464711F7256DD732AB76D834EFD0C5557B -DE603FCF0E35B4025848595E585A7707A33F0693022B06FC2032659BA15DA56C183E51DE -A5A8921061E9ADC27AB380DCFC851ABBD9A51632F60EF08C2FCF84A86A89516D66DBB232 -A4EF10707682B9AF6A9B584766C8432FE43BD4D2111F81446E0D508817D6E6742261939E -36C71EE1945C10C1CF6FCA1236AE71A10957B57B1F8F69EDACBBB9898735D2071C073E43 -6585FE7EB0BC41E40DC59BCE6C311D84F9C41929DEE8317615033CE146B3C8DD7C1DFC28 -471226DCBB5A003FB6185793B313EACB67A443C60A2A7873EA4F13C0DEE9209D4829FBDE -5E93380F14C2F04448CCCE8C92A0494E4F5BE68792D35D019F1C4279D261579261B6A990 -6ED88C23D9D7993D36FB0F0ACC744B14FCA75D62AFBDBDDE020DB4EC979F9A816DB0AA8F -767A0CA4D561E00EE5917AA1FCCD701A8FA3BAC8AF96268B9E141D891F15B918882FBDF0 -4B611708AB3D464936D9AB17E781DE646C2BE7EBABF82F4D547F09719EB03FC702894480 -9E8C963D076BCF1DD1C29F3E6A57DDD550B4C50C940363F0015EC80F170B282BF9E9E8A8 -7E11B31975583D1B8678BE0F782DD2DA711A0EFDC5EFD9BCB47C4C458AE693207F67915B -388CF71C508BE8A2E3336692A068097AFC21A42DF45A12CCD4E6E005857D04328032A455 -070E65A5F1574DD06B48CB94508FC3DAB04FC0D777C24F1B8A32F5401919441A01C7FEA8 -90AB7C15FE2FCFE62713F42E9ADECCFA5114E46E8FE38448282A694BEC76034775C730DE -B2813ED4E2EB75C8D2CF9F6EAA42A82C5C711BE920E4497E4DC4F60ECD923B6F21FF8C9B -2AE3EB19CBB422FD027B4C8CC503F523E7B18DD1858D1DA08C9B0D0B9C9870D549436AE8 -D21746C86310CB94923304496CB2112D91AFEA2776A9CC7CD79D381AB7E251B6B13E8DCC -36DB7BDAB3AD9D22C7A9F6CEEE7C130E3753C4AFC946839697EFFDBC4005EACCDFEFC029 -9D259947810AFE57002A3FD3B9446977345BC5D5D53B6F9722C47DDA534BFF98C2433B0E -EA965E20ABEA481A9C81C612ED51CCC35A74CDB473AD0A5D2E42950AC1F66DE6393BC9B7 -B02B00441EF8CC421695854293874A7168496467FACB15062D50600824D18F65E3FB83DC -C5273D5743A84DB5CF9D38AAB1478BC6CC1F849ECDDD397DC56D1B1BA395684520D68729 -FF5132F4F7B48A17DD6FCC303871D6AA2F29CAEF2EF77E0C149829B9225746D43286D1D0 -940E765628810673F32809AE451309BDBAE942726E9A2D57711683B3C4D39F6DC393A20F -BF0A8F4F73E8A103B3D9B12572BA4B846A0A9EF3702546EB97A046264F067FDC72CCD091 -E357B618687BE9E5C7E667914F44EECBF3DA82C9464380981288AB2F9B058DB262EF5BB3 -0A4E0327AF77B82AAF49479A96A6CE7051D2277EEBF286FECA3B0CFB56E1A94B147620DF -BB6207691D8E751D5E468B36BD64C8220F2883A5DA60346EED5616F924660658111CE6A1 -0FE807C63FB67BECA2AC00D98C47B5F1CD6B9FCAA51848D97EAED90AFA582F925DB9DD91 -F77B73CE5BCFC0A8B21C4A75862B345ECD68545A4ED15FD4A3235429019E3C922537DFF6 -F0C2907B10D068D116EACC7E0C82EECD67C0A377E367500BAA0B47EE6444C4FA196C7DCB -F1B080A2531A96E2A874DDD02793E72C1D259C3004474DFC91F2BA21554D2DBA3E4613D6 -535691E6E4AC04940353EC25951DB2D4EB2FCE5D701249B835FFED7C78225A84A24D138F -631AB67295866BBBD000C1D5BD26B43EBBE4740716DA3D8293CE4E359792F7120811B32E -2B378B876D41E70631187CEF898EDE78C0A8986CA30889A8F53C2344384E3FEFFBE7AF07 -171E031BFA6536E2E6719D934F74B39169E1D912790256B06BAD12CC3AE588B2B2DF1C7B -ED6A3E99773C25BA78DAB1C8E902D65E4E55FA9005C4D80819AEB20723269B6C091AFEE9 -29D46C11C198A7BB0D4260EC9464156F655EB1D460DB7C72D932CA927D39EF98F35EB6DA -7F8143A443DA3D0E909E6B846DC2DFBED888DB41F2C03D9C9B61F31B2E8334DB7205FA8E -C2B94D71CCF61FDB51C66D8AF7A47417DEC7FFBD8A052779869E709F3B36BB74340E78D0 -3BED0A4618738C9D2C3C447C0D50BAFD176208820D1F314E21615B7A4397883F8D59E65E -80A814CB6E8FBA91B0C410A8B7E37188C1849AA206A66162902591AA90F18E0426C586AE -80F63CD8764DAB7FE811172A87AEE833E935F5F56AED5062E2B35F6077EA26AD8DBB1011 -745F36D936EE50A88144F211B37D8C169938EDBAF26E277DC7A921C0154317BB081A7537 -F0FC37CD6EBDB6F97130CCE08B85690E173D7158367C616412A63D0B8ABAEB47B1BE35D3 -23456EFCF7962953F630002DFEA23DF4672FEB5DA149B713FC91C94505596471E44D590C -54FC5D336DF319A98AA87DB9D313B9DB208DDAF46FD5469AF90F548E704DE24E3344B95D -6EED106864FAD4001FD8DE48DEB22C8AC3FAE18F7B176804DCE5AA2144A073FC9BFE4CAC -CD6CA534902429E28CBEECFA8D984A71E77B5662A1AD114F301F548F192B11ED7EB56BB3 -F8FE62001753FBF161D538878778501F917441F9C5DC3B39704BC1A234117157303EEB24 -EF453A1E05208A07B8AB22DA331527E0871EE7D713917E86C80D2FEC3B934E5B7540C672 -34D0FA0E4AEE6A5B1706F2F3AE147690A76815F5575A5C5B44682028A065FE8037E10526 -5F282058D027620C117A57CACB77AE153E8517134168668E79017166CC435DD24831DE0F -65872D49DF581C872FBD74E0E2502B9C0C741322E9CA72152E7DA26D84696366D3DB5C56 -943FE579F99CFE384EDEFEDFB30F7EF5ACFF5BB88327E5A63B796C7EA2461B21419592B3 -65DABD1DB63F6AFE1B959CD018163A48D82D0D36284F118263E9D2B8FA2E3104BAE034E1 -A1DEE263980EFDB385CD6D687D1092752D7E3A6C46D678BA2A2F3E208988AEF16EB2C67C -0C5DDFC85C6819746A034BE35F5C6DC967D64005E4104A7EC6C55CEE199CAD3F98D83A22 -E9A32D0B0F4E7DDC4BF81D77914EC3C3DA3AAF51424CE3B50AB293152EF0EC717F16815C -4ACCEA27FFF69DAD5AC1DD549C6CB01F23F3C5A3DA340CD914849991C554202076C37DBC -7FD48DF9DF23F5DDDBCEFE0114A2877C31385A184742AF5AB3007908A359240E9DBB0AC9 -501B7BAA815CC273D953E0D50802CAF8C00FCC054B10F0AB7C072C573FC4D3EF018754EA -32203E847125B73AD879F613804FFB9470CF39D0694155B3D5D500E3379A163C86CB1AD7 -85C3AD12B724AA4F203C212FC0FB7051CD0EEFA161920E515FC83EBE802800D1C851E085 -B069541D8E183032EE5FB6D8200376FF0FA5786796E7B33352601711A2323AB0F2CB64A9 -B71C936643B259BB73CAD6D04B33201FD772599DC49B9611533D53630A3C91A6DA4E3CFF -519BB469F2C23613B0D445D98377E8EEE6218E0CF7333EB5C4257AE30DC6F8FD35C5978D -4071F0D9464C260223902E3C76703BB2E3B3FDD9ACB3F6E43C3BBEDDDAA846A4893A6E6D -6E8D5AF8FD12DFCBEF1B5D8F537AEE87AD8AB3B486910F0013FA6239528F698F61B6A2FC -FA7CDF66B238222B989DD390A1647AFDB9AB7E287F5CD96B7E443C293B39C7C8A91A207D -E7F0A73A48387C9955747277BCA7E97EC37EF0741EDC541F9804C12F95F3325F2E80CCCE -0CA03C931C7FFFB7419BB3B2A3A67325DAE74C4D597C41E922B09ED70F411F7E29486C5A -3D94A857CC69502C6DFBB6E63780DC3908B989F01116B28CD8BA096CD0B09B3EF4AC8E64 -55FC7300CD8861EE2F1FEEFCC03D95FAE9DCA58000441A1D3419B77DA35E80CA40C0C49C -E1DAA21511AF32DDCCF3935CF78808330C469C4F12481571303335C945937C0080E56DF3 -ADAE10198495A9E04DA1AD8453A5C3B7D9E6E8A8F6F57BA249F0E9CCDFCD8D25C8E39BCE -2B158052D9112093EDB087E2DAAA0C835634BF21B6C767D7D622BFC669B78040109BD4E3 -673468377348A6EF3D0E6D1D7BE8A07BEAE0D72CC158FFD8904003E7D928F7F9B78097AB -A98804FF2BEEB62C695333EA76444009C03751DA71269219D0B30BE98C710803DC3C1159 -2CF0B2D8317B13358B3D96F2B79F801E303417DC8FFA4C1B5B246C5167410518BF7B122F -072E1C356BB87B6BAA4B36609C3CBC4FF578ABCB0A9B4241AC991354B9BE34E831FBDDA1 -D97665C37DD1AA4E2E2AF3D41D2E9561646C40D622883D790D6986C60A2E5B2D27D9370F -0F2E57DBCEBDB45A6244D1DDE4F64D30B94621B21EBDD2DD7F87E75E9BC4F47F1E94450F -AB7D3A2687C66FE4495A05AD81E2C0AB09B4814422272290A024FC55819E7DDB08666BB6 -FF9C9C4F1AB70697649197C550C48D221DD1BFFD20AD9B43F876F19CD818F3EBAD352B94 -03A050E79CA2A369363033508882A1B63D0755B43E01BBDFE55E7F6C171E1A6BB37365F5 -6241C6DF75D3E1B1364A655982D595C66A186310A5B2B3A4C99D39069337E0B7F3448D7E -E8AB0C5EF3AD79CD8D9C86C1E54392437C1077573076513C0DACCE6D16A3ECCED9C438BC -F7859B1ECB294B03260BA9D9890424DAA816587C4004FF0905C6026A04E130E3B59F1952 -02270BCEFD5B7CF306389D3F255EC17C85C6C53D597E11DB5C1E0902508F22044441EEA9 -A474CB66BC40D45A2E0DEF1C83FC4432E155567ED91D8A928D2986479F149E4AB3987D95 -93B419964BFCA0E042CCF7807B125F29E22A488BDB19285FCAB04AC29A564D599075B2E5 -B3CF0C6D53BCC23C1ED6A5206A6AE91E2F21AFDD4542D64A85F397B3CB0DC1F2A0C2AA87 -5C38974242DFB90B4CA67259D610BC8691037931C69D18242CF469FADC88CDC85FDEB881 -A431ADFD4071F3C856EE5BA0196D1A7F157887642EB50C8662ACF5BBD27C4038206FD907 -8AB7146AF5B02FBC3B84E61DC936C2B79F204C8765D6F366CE1DE4FAA944852EA71AA25E -BFD160E6286C927FC76EB19F4C5878B5D847FC5A941B8F2A1C7C38A0C310DDDB5D171E4D -0A1774ED965F237A5396E5A94F87367DB141DACB4448F67789C26DCE06FA01C92014ACD0 -1209D727E37A5C64067B2DC0F91530D8AAF59DE0D750B2A18BE91D7A3362EB026C438FAB -EB0AB75C8B2F4137D843BE8EF156CFA20563E291B34F19F97081D4E43F4A62DC72591D54 -289D839CD857540EFA38AE1A02A13EEE35A0A4A3576FF6AD5598A76B3E83FB67F5062FDA -4A2DA616282CEFC090E154EBEE481B906CC206AC6A5A9AA442265E95CA379785B96E76DC -D4095708AF8A65DC213E42581C59359F3B48EFE9F20AA85E04EBD4F8B4B8201607BC2CFF -FC71D43AB06A3D82E766054F2A54734A38A714058C7573B847C8A3A82304638F2579F037 -83B88E29709F5AED8F17F68BFED85C7589F5343D8A1B73935D693E70E49F67EBF2E85104 -F1A384F7D6BB00AB4067F816CB11C71C625136E073E4C98486A5972DF70B5537693FF55C -DA94FFF774F7C10120F4836B9E26941B8AD2E48B90D71ED129A48DB73DDC0E7CD569272F -33014FABEABE382BC029832CA1A7EEFBCBD24CB435B58703F1E9909FF7D30D37154F2D5A -29CFDBE1892DBAACC07E68544AD4A1E672DD620A5EA6F84B360D6B0C9D2A16600731892F -4BA194089DD0D829F7DDE7885C7FDB37B8DB601623B7B398070E617E2DB13AA6B7C7EDA1 -352570A133F0DD267E23EF4885DDD4B6A2EFAD3B55741CE7B36475A878228A200A49202D -13A9EC655051C1EC4FB61E9D3C1029D21C4B943A64479F82B247759FE49DBCD64EAD1605 -81159DDDF18584457D99949AF2F2EE4F2E3AED242C25919F51CB76A188867D5959D8AF10 -FCCC2DD8D2EBD266B751EDF244BB8284A4705E1A4649A050348AE54A048E515F29469FDD -B04A905C3B9C2B3744455C781BE4487DB56A085A9BDF8F8256FA4C1B37DFF3295F5418AE -C03ADCB277B3157A1DA2D7176E12B334A49E7CB311D6BEE45459160E34B024E8B68A1768 -E83A7B8D7E0D5167E4BC7EA55157A20C82EF009A2631CF53205E11B7D0E7675329822052 -C2FD7C1FA61D269A90B94A4F103E6FB3EF6B1B0304ECF573EEBB1A432F7AC539EB7D40CD -C2F67D1D3E87E6B66CC16B63E00EA442036DA83A7E3CC8F2946CA59FCC0C085D642DE6CF -7C8B642EE62B830ABCC7CDE13DEE8C11A4718ACE97C8D47BE41AF8DFB4A95D44EDD219FA -137541C53086519D6F32112A2507D37B2EB7D2FC10AE66CC5D5A2D6A4F8E6F084A95C923 -CB40B8437D3D51231B50C72DC5FEC25ADEAED8D72EA6FE59859CD3512F36A0A46D55607A -AA143A65CCA0203366C702554B905A093B2E845FD90002C689CFCFFF02586DBEBCB11688 -7FF863EA45DD0EED511F4CAF921015383CA0391E393A44419B34E82789A62502C19B3287 -DEF1F5B24C60F5677576902DCF76F00BC4D3A056875990D18BA69154154C76B2BAA38ACC -39C8C1D55892583B7C32CBE6411834223200F22B416709FCF635EA5016BC3CCAE42C68EF -AA30B0EE474890D25C9EB745915FB60F517600C7F380582C7BDF4B34FADC9C60CB139D03 -626F4DAC953F9446C02331E2804245F7AF2BABE7FD2636854AF0CC676792580B228AF541 -6172AFF0C2FD5730C2D71C9FA3E17D36F9AA4120E180D025B710EB9F95AD8AE31B66D872 -20F028D258A85409CDF37158F840C2F418A0470357AA99A825A9537D24BCEB415329EB6D -5D985445AB19B08ACFC1F58510119ED297B034334EEAEA319D0EF5F7DBE4836DF61041FE -071BCDF1644E9C2D924251049CEEB73548286CC1EA170F0895771CED237B33FA8EAF5571 -E22C890F0B552D319EDE4A59928F14FFDD911F08C17E939FC035D7AEEFCD77AB4A2E7C4D -91B25D75F5C6CE9122C27E0E4A033417F389CF8796EE0F55794001AD285C9285436E983C -94ACA66A8C8027689688D0FA18DB23BEEF57C73CE751FC6ED14FB4D9601080258B7D4885 -4CF3F9A8DC58E073B3D2961729AD90372490C0202095ABF65A8C95691D7A32DC000B6FB3 -EFE315D903FF04A6B366788B5A5FADA322BDC00BFE337DFEF5EA0B899E36CC226DCE1B75 -CC352F71064E7F05420E4C3D1102F55E082E04F1CDA182E5DFFB5EF1283E721CECC5978A -A1EFACAB70A21438B380BE3A972AF19381FCDFCC60FF173ABA8BC049D0D9F22DBD722FED -1711CCDF75C710D083B0F3A56338A7708DEA014BA01943086306885854CBBFB8E372AD75 -6A00B5CE723A2558D80EA8B34F987AF7828CC5457865D9299E3070077F8D04D94C569806 -97CCB42D01ECF928629FDDC07CF668E87ED8313BDAA0D5FD84B0B416FA83998B1ABC0B03 -A3E43B188B7D74287A1463CF2967C7FF64335B205A69E974789EF5741A6CA9A3B62FAE04 -37B957A01ADC30C6C1CEBFAA7044161B9A094377D57E4E990FEA040EE9E37414D70376A3 -66D16916752F4F51F45171892908A53A3F6EE0497A69CE4D4F4085B1BC10F65623456980 -DDCE8C933CAC5C779D518720F5B8F511C8FE4C53E23103A12B2FA4DD02938ECA2AE76C58 -000D38B2FA467C1E1A8A442F9EC4F02E0DABB0204F2AE527B6F7CC775DCD07DBD96C589A -B912F727B9B81FCDEC5B3761842E845FDB6CF3840CF0F183F2ECFD28A92BB4F5CCE7DE8A -ED8912F728E39646F57DDD2816BCB3BE81DBF41DB3D3837BDF55B60E083EEFCD1A012A38 -846E025EC9AF4CA745679C60F88F01E3AEE7B65599AB02836F7A1F192466F5F729483DD8 -7C2E1CC75A61F0D7171C85DB04073B9A319A2F2B76C632AF2ED220FD9D7A1F9010836070 -E0D864D1D31180C1B6E35B6CA08D7261CC843915F15F802B3613E14218DC9EB7548A5680 -C1A9E7A6AB73A75DB974B4359BC428F1CDD2BA5E7F4590DCD96F1C3BD35AAF8549463541 -2A28027140D352FD0D9EFD97CCE7A86729432B246EDBC0A54EDDD6E67636A6F908BA5BD5 -0A90F4F1365DEE1C1E8989C0AC6C4A64861096C1B1D3CFAE51DDDD96CC24C5C11275EC50 -5F8DBCB44E345EBEEAD458D458A177542F5EE64FEEACA55A61AF8738E6BF38A6C9B211DC -F7F2675EB86CF3711C97FF23FB5F5FEB1867467158BC75F7BF7414BA151937085005B8DA -A6D82F31DCA1007E8D3D317D13BDE2428072D2A3A2743EBD214348B15EC3504426FDF73E -3588BD1789A8FB8BCC1E1A021BF64D274EF0C9FAC95EB50E2D7A1768E82BDB5A4239DD1D -9DD8E1775D3BD4CC4C07523E74FA545D5D650E9BC87B80E41EAAAD235833D1CF3B6B9411 -4EC21687773049E082646C8F29641D858D9890B41FE8C54649F840A0B81166130722EFFC -A6446C5509D988E0B4A9AE8E8765E1DFEF579A6D658C4781BA3B3DACB899F0AC467B9C14 -C66C8930E9A8558C8A19AFD95FFF4A3DADD1DDF80245C2F5F91D23B39CAAF4D2BB1216F6 -4490CBDD7FEFED8406D62DDA4A4B0F0FD80487C9752A0948F74930FD47AAD59FFB8B5540 -DE795994B0B6F209699D1DBFE7B7A94DF25522C7BF57C77EE9530784756D2FD8D058B9F3 -BEE20B4BCD63C950F9A4A01F66680608D66AA87E2FE5FBCC265505325711299F6E8F54FD -1686C4B532C504753EA7BA292A91A0FEB9E5BD690F1FC1D1B16D3B9870CB2CD14F7454A0 -8F365FA3FF1F0A8A33F9476A7053BF19ADB66EE28825530115BF79F60AE108B28822EC6F -313C14E43C02FE8871307F481D8B00F0E7C847A3F239723F4003226EE84B31A72F19BE81 -CB986F92710E37B1F6F263403CBB97392DDC7550F03A1ED56165B3082314995D75A4588A -C4E503C6BFF1E642802E0C3F1058B45E370D3DEEC937533E1CCAB26BEA94E9F89F6C5DE7 -6701DA7753CD1FFE77A42B11765EC6F80520EE01878ACB37096CB9C091387AB3BD68205D -1CA6E5BDFFABB2550E6B942F65FA977D55A459DDBFE4E17581CC19FC3B589F976EC22F91 -8E95546F8A447EA621DC289B7B7D67CC9C246322B221E6EFF507C2DBD4A93E41C2F7AD94 -4BBBB57372F85E601FFB6984CA66A5B7E98650E84F498AF13C4B0EEB0038953B5A33DEA6 -9CAD47277A632B26BE464E87951E89B8E0C051BC34220EC245E6E31383B22980AC124D84 -3662E9A1C8663100520AEE44DA661F4307BE10122C14D706993A586C7400BA3C74F020B2 -047CCBE55A6DCCA5AD37AACF9ADC82A59060518FA39649A726CF23543CE91A1A1070FCFF -CA48C8C6A9B02CC28479D8F58040984250C0AA0F581DFC8A5F978EC3DEAD276FBF7722C0 -2C3E41D993368CC019110A5ABD10C1ACD5A5705160AF288A60BA2AFD20D22099265BD254 -28EDA9461AC8193680AD019787902636FF81AF8C0CFE7BF8C064850BAE2E652CAB330EAF -13508DC67B881361C4F29B45D9885BC4CE554493AB16F995A98D40B7DB137953488710E2 -03295B129EB42BE45B089F8F40D505380EC2EC7C1DDCA1940DB8678A1CA0232F3140FDC9 -C00FC77392237C66F9A0A8B88A7D7D7162F72A1319BB22E8DDF62DDE64C9796FEB38C360 -D00F5C94FB772344423AECC5B4491B100A2A93D716B57B5B44083101335682DC6BCAC0DC -B500EF88D04F4F955A1214F56508DFCE4299A8B5DDE9A997E431A55B0E8DB6CA1C332502 -200C5C5899731AF052BC28D2980C00DB0DAEA4CA5EAF199A5DBD0BF794AC18CBACC20981 -96FD0AC31CEB455C61991445EBE8AC899B9AE530847D5DF608D011437B2FB24E4A1C45F8 -05FE4FF8D4109B5394447D7C9FAE9F57EB904B7D6635C77377D84D628F0BB1898FD9DEB9 -3E82CC2ACF52553E9ADDEB1E275280C62E4E8AC9722C5E1CB54DE4C4DCCCE6166F7F70C1 -50747CE19775F12C19E4A81599CB9C57918A42BB0E9AA638429B13B606EFA7EE2FBD7632 -0275BA3CCEB743B7101BCDDB2CE5EDF843E8944E4D87E1BBEF47C9D5611E1805CA0F2850 -CF8A205D53F054DD143C3C90D9605C3B7AF045C553A6332D791209DE72E02C146312B25A -9A5F4AFDBCD83EB67685ACF487664FCF0CA5C455F5848E18A5ABCC174F55984E368335D7 -BC77BE4E2923147A111FC8CC57CBFD5BD87D09867347F01E11DA0780E4FDE4DDA54833CB -10ED212340A0180CDC5924F675AC6DAE629555524297FD133BBACC4F51BA326AB7D07DCE -2093D6DC8E6126DEDE9ECBA129DF931399C72CE690C0B119B117A14E3AFC18094DEF65C8 -4DE9705255D3D411BDC6958D872CBAB28C9586DA888066A2A00B05FB21B5DFE2B9B4C87A -A0C4D7B91EFC7E8076DC5817C35652903605B78FEBFF1B4783A170D8060FC151CE533755 -7B8B3B1EE083114F977201446CB8A5BFB5DDF0852365330CD5C82CFA9BB2DFA6BABDF675 -45586F4D28605BCCCD80BA8B59B501C629D6E6BD5D676665462D5DB2784C5D6D8A42B406 -11700F3A27FD143BC1EFD859F7705C795EEEA9FFE57E25AECCC5C7E270833AA9604C6248 -612C356B6D9937E3B770F3B4FD632A0D8778C5EE2CE62C4E780AF5CFAC1C7C564637044C -0C8C90B9BD886F9BDC287FA97D4B4F4E4E8D7816BB25DD740D8C9307B94DFC8E8E91F41A -189E20E2B438AFC4F42607744E8BF74F3106312D7480A71840D4994ECB0A7A088784AA68 -84BF4DA162D5C38A4EC6354D19F06313DF2D4167B57BD2E5F544490D711E4B97F8D5B68B -F4098D8C9F2D8B8256EA8CCE05D189DEF0E86938052C44D7DA68445A6AEB7AEFD865BC96 -592DD991DB7FF294AC7DD8241E23DE5C908046179B44B9E8A79472154E254D44BD9FFF4A -435B05DEB14C08377D2ABCB8A26F706A366335F2DBFBF5D59B9DA9C67CB396A17A40C874 -C28E4AB5E242B6AE244EF37D90C8699BF1F2D5F8CD1D3130C0CA72B7040991FA90B3C413 -699CEFA97113609A486483E2A72DDF26953094C4E2970A243DE23963F929C3CED76AB062 -8072F5AF6EE3F950DCF88F57F33CABA2C8E4598D4FA6AF46656512E180DEA02FE3BC8701 -C4EFD669BDB52129FEC53E6FC55499680208E6A874BE255EC21B8C75A9D0D8A2622A4CFA -7E6BB9E8986AD3EE513F341C595AB2A14784466170C4D6DC2E9BAC82B988CA2609FF4B01 -185CC5A2B639A028E4A378503F55C147E6F8B30CFE5380A7A07981C15BE3C7120257C67B -4B603314DC2B65A2E4036151713B934F460FBC1B052417B907F70FA06E2219F310E34443 -A17AD4524ADCD140341BF982EE4D8DE7D969AC5621129C600231B16E97B62B6F618CBBCB -638020E75A77DBE28CB0EC9E4221F5D573DEE815512CEBEA629E6761617E69BA730B1EE6 -14C96D5758E519783F0862FB4F5C10D444882A344972A91E12051B2B29DFEF503D8762AD -895871D7CD4CC8BE62E1315831FC25712EA1C4DAFE49CA332CCDB5AC2C2D67F6594D592D -221B7DE7E93261E9D34179DE194AB2F4F4DA9DF9EE3EFAFEA6F1193940AED5655FEFCEE9 -E38DB186C5B5DAC4B0AA13A89EA5E81303A681133ED154B164E3A1D416DF8623A38213E8 -049B876C7C22F625A57248C0B61E4DE518F982E11672AF1765984203B7B7A17C2CD7C7A3 -847B6FCE423541C14C6712572DBE3BB99D1144021286B4E3939560998BC16A6CB47F9905 -BD48B9E25D1B548F6AED304BAD2823E364DAC055423B76800ECDA7C554211DB47BD28200 -79FE362F799925A8BEC4B4770574290D0654CEC588933BE1845BE51FDA15760DAB3257C2 -67E89BA950E833DDF7D7FC37F54AFE1954B006E3C758ED7BF3B28217EF77FFE36196D8A0 -A81157CA87889D7239BCC205459C3A11B808545C8A256F97F3B7369EDD1CF5D916E71B0A -77BBC006A71865EB15837635FFAED75D3172D91BF820230392B102D1C6AE05F36AD0236C -90133DEAF1B0F7658B6121D1F2F293DBCC6524C89A3554827D44601BFAB910BB7C908B8A -7EB7E84221ADDE214CDEB6B74765F2E8148F013F4D6CFEC4C7BB344D82B176D665A98424 -CC385736C4E1D81808ED22869C8132E5EFBFCCDFD1DEF732C3604BB683E4728EB60386E4 -D03D08E76B36DB7D39F07F505FC13A336B7AFF4D9587D1EFA16105FFFEEEB8BC2406766A -D3742312A7DA69A7B666A178BE43DE659D46CFB1A0309EBEF7B886EA3B3B554EB7225644 -EEDCADBBA3978EA1EB59B35EEE61BF1396A61922DC59487016F66561EFCEA19F30295719 -156A8C9099F0C07B5C076DCEA85C4924ADB96095AF46C1F9BA08BFAD5A4DC49E95CAB635 -CF1DFAE9A1FDB81E27609EEBE67A9636AF703415EFBF5EF0EAF7C10B1B04F139E60FE96A -6BB3104555EF08139F1641575A227E86F0DF716C829AEB4BC5CA32128AE75286C6CE0147 -F4D6873FF3B94A6CA54F701B9494B380D65E691F988CF7C6D74BF67A42F169FE5AF96CDA -656683349FBD542386DB635D09CC032C6BD486D08ABCD17A69C7FBDB61378024D2866932 -47E834F7BE079A875D8243E46E1533BCD01EAD3BB390A727226935F1BB5A9A1C395C92FB -679D980E6E67EECF4DEB74D75C164D53DAA8AA3955A91C29F28AECFC65BA8D7572374DE4 -F35056460B36941E7E0BAB36B8C28E081A29D92526D2F19BE960DB6CB355003BEB9B3054 -2A56413F77FCFA28B73258A8F4D473C04F8876C2B32901F62FDCF97261B3CF09D0BD6087 -ADD051543706CDFEF061C5F909E6BACFB2DCA11F38DA994E7BE7373AC2877648A0628662 -00AEE5E012297FFFCF714986436209EAFF78C09FBD9C54160A4D4C0629FE3F85CE065438 -8A996B462D6F520EFEDF8EA2578FBD42753A2882BB3FFFE6F65A89D0A74E27F306BBED76 -1F35A13A1DBE04D998F5CD63054D98D5A209E82637FB48929F7C70C154F66B6E40DB0F74 -18C103D628A4BEB3BD0455D886D752D58009ACB9D52EEF4F119F22CE23AABF40C558BA77 -5363C68AEFA720A3B14576B1EFD95405666BDB2966B36C206DF8DC7C2797412602A7603E -C13F0F2FE5747134C666FC26974D7FE913158CBEDA9AD94535099E136A43B962A93F881D -880E205772643F2B60C8BCEC7E4612BF86F9C0FA3A2F13191C1A6C3D50B35D6E07F8ED98 -1B6D2F8DE15FD9709A8E541A0276CCA6542FF3B921CF5A5EB6FA0AFD68A952114C9A3F8E -3B3FF6CFB9EAAB6DBBC62F38461824B3D0831C5E560C6459E6453B629B95F9D2CD117AD6 -E038075BE1D25A833FCB17D3FF657B483AB6CB82FE2AF17EC4AF1FDCC3FD6942A0425826 -3DE038F6D17E3F79404D44819424A2A4C559D44241D5F577FD60A00990FC2D14C271DBA2 -177747C6DE94CBC7C9C72D0459752D7E9680CE0181DBB43180AF135BCEE65DEBE77C1687 -078AB912E9183A60EE6229F6B9ADBA395A5559739C3E29C8B0EB221A036BA888FABE661B -F4D4EE0B4B6D62C5A6C96EF3C57A8B104E14B9DF763CC16B81729D771B557C4CD2191384 -0B40201E52A80869810ACF32FF93C005CD90B15F8628832CC689542A4D4DE58B55B050B8 -3E246BF54510B53218A2C556758FCC89C07E5E7D892AB0B9264529368EF16CC4BD6348B9 -57F2D5AAA98E0F999D4D400E77CBE175D35F004A19AB64F00169769EFE8E7D287A7C024C -A1A0D3F915EFBB25CF9604BBDECDA184C0D81EEB197FFC04B2190687D6086DC57FC08F7F -2DA512C57A3B9CE44115F9A6A7434E203CAB798A8ED7A68D9DEC0919B0B7B334337B652C -34F200CA9C679806B47152B2325AA1D1275B62F78B8610CE4D37F7F7DDD281AE294B7DAB -508AFE5492C4A497DF7D37837D43ED2A3D91C04ABCA7B0F7414A451ED560D20B0164DB0F -227CC753A9CD526F8C57468912A3780F3E9A6D626405FB486F6945AED27C48661FE726AF -EDF3D69BC7ACF0CC657CFFD5347869D16AC4C6ED41F643C9BC981425125B563065DD7963 -22413E1EBADDAA6993AA9629CF048863BB3AAE34B44308D27C48B6F4F9E8E1CE6C471466 -678EE304328CCD8EF1DE777AE28EA758360EE7BE768332794871E18009B99351710E22F1 -83146E57B21C72EB728B83C9BC618904CC0094FDB26814C8667AFA12D26076575D26106B -1407B08EBAB89EEEE0CAF34616054550D610DB759C168E26C08557822B995606459FE74F -1D085225CF359A8092A9175FB03ECA2812D7467622F4F0132EB4B1DC6C40CC969842000C -3DDEDCDCFA0E8CA62B214E34F1051F468224AA8D0867170019FE82F745DB85ACE622A175 -E50A3A371D5580313E08E2BE5A6262A83CF8B6DF0A02F258F81C636D02F381AB20166A5C -AD53633533D61E534CFAB2899BFAC061ED7734EF53E7652C6D56186FC27D54991C8411CD -D2E9D048910765AF119118607413B556016B075BB4245947B9ECB4DE17C38172AF945904 -92630EF8789A3B7D973C9152A4EAA90AE6C984622AAC31DD7952553DB1289CD44C16A3F6 -7FCF7BB135F885F083A539D05DD1128322FBA172737E00842BD674AE3AD8CB68D95004F7 -0EB5E23E04182E56D4E9355FEF193B4606D4C3D6B9275521AC4EE52E7148DE5196E7F84E -A8E19C639D8D20F70EA1D413CE48295B47880A8535F8E0A626E913543AD381A8259FC5FA -593DBE84701260503BFDF27E719A99635B710F44EB5382AC3E6444E6B7C6D5931AD45866 -08F06FD25CFFC918DFB136AE01275EEA017BFD989D0236E7297EAE998B198FD2DCA030A3 -B851EF96074946664C4C12A680DF7A412475EF3E641DE2644A11F9FECF59332241712B76 -4E6F32AA42AB853E51078416EAE47704A0063CDE2E539A46DC16516C1E4680A8B1785BF6 -CFA86A558F74164390C3D35DB0CB7659910B6709393EBF9397920D1CA964859983FB49BF -7DF5472D866E654ED33A10B1726A5F3DA71B93CF1A21AD65ED51DEBE5625236470C49485 -AA53F0271E41C2A20553C67DC3388EB8C51EBF88E533B014FB9CCECD1CE071FEB8353D85 -E89DEDC7AC71C3873601B71CCC7BA3B5988DED9FF85CD350ED374EB8BBF2813854EACAE8 -3460EC71E78B7EFF1EDC8EB3E7AF2764C63760B38F6015B5299A1B1969251CF1E80B8E50 -4EC30439ABD13E9FE242520E37F523A1CE4008A75E490C2D5283F66FF5CEF6A97FE86B78 -4551D1B4BA916A12CD2BF1434FC74F43342297E4E6BC9E0A0C9F54ED31CDF86C93847E27 -B3C4DF7815D96E6DC9E88DF85BB7956FEC3DE7E867765E6986DCF54BE77F07AC3E36F27D -C4C0BCAE8CF485A549534819543CBBF33C6DC3B04766DBC4DBEEE029DF6D7AF91D1170E6 -1F7968397BBFA987A4C4BC74CE816AAC3646A02C8E216BF2CED3FBE06C98AD6C5168A570 -98AFDC8F3D4C59616DBA4D3DD61E7774F6583644B27E85A670EA442C9D575265A892A87D -07583509186E84C57EC343221FCB436F363AF502CB6CE631EC7711DBB3C37FCAD34D110E -B82FF2F7209B3F68EBCA22D918D3FE424215139DC75CA266904FD5F6D40269D39517051D -5B077D26B22F5D3F07CEB35444782EAC7DD819A401590F38571C148EBEA2E682E472DBFA -43103B2183117A9002D04D419A7DB18BE5365FE9F8E2F8498035A992ACC07EE86E1A2AAE -1258DC4B4C6F8D0D930B31FD0EEA876D0D726C7328DC4D5C76B6BEEE6190EB3B650F88D6 -45BC3FB7822F2DB69C2174C93E39A70320B47816BA3E8EA313BBF34C3EE729112A0C9254 -1D09C9BFDB31F939E8D03E31BD3263500F7B92E6072E1A418F7A70112C7C3609799A7203 -3A1809AAA623C58E93213D12DD3A8C37F3E156A7435A42D3AA20E62DC8D4D69BC694DB70 -533729E878603C0CFFEE8D5A4C1A7F29EB6E07799846CC096A8257643A9F85D5CC913E03 -E72C1030636E078D42761C2C3F0E1E84C205B4D8A3D17F63BE4D70ADC45F2DDF2B5121AA -A4AB3D909D1FE0179CF72BDEA0250B110CB4F74648535A1E9BE45A8844EB110F60C490AC -BAA48F32526582B619AF1DCEEA109B7DCCE048996547BE21D4DF519608B5ABDA68ABCDE7 -AADC339F5626E64C93110B21C112E12B5E75F15A8FF5B0DCDFE85A1E2F0968E721C242E0 -4B9543CE6D394F8D00B20A007EDA10672C511445DCD8470ED2413862E6809C15A2E9205D -E522936138B66C44D5BB9B20C908A6CC8D6F6DEDF3568E5EC6672107A24032130CB5D5CC -B8849075CC87FF04B7D8D5370E0294C87D20283B1E6D54679D4E73CBD1D7BE72B992E0C7 -0686C5BC456FC44BD468B6B1BB22D7DACC0FF36C94AC831D391CB9FCADE8F469A5F89414 -B22001501F06BA70414A074A4B7A6A0F2AA2AEA1DAE282C549ED6F656394D187E68940DD -EEAFD5414238578E2A5757134DA9B6730BEDDF727773B2EC1A17E4DEEEA30482475C93BC -484083883EAC5E0D7AA0DAC552FC82F99D6522FEFD818F8023B1F945FB86AB96713B3041 -03F2B5E3913A5D769D5033B2B23D69BB7F21E34B0E808A750A89885CDB2B65B490F7EE6F -DD0A636187F0271C9DA27274A01D4380A02BDECD5D7A5A1AE228C22532838CCA3750A8FF -48D831F27F3712E85B956F03F534D2A478F8F819EDE0071BF9132F78DC0F5B7D578FC0DA -B3BA0CAC5FD186610C32FF89D130E0AB9E9E2980D9069D4AF6EA32E2ABFFE99B09BF4FF6 -588E56A2A87DB9313742A901826BFD2C80526CA519010BC7290C8B3A9F47B917343D0698 -E17565724A7DB1207EBC6B16B449D9E8B67F7CF227AF62815C71E553F644B89ACC4B9EE3 -A8CB7073905DE06FB65E44E0A762AA5D3A109B5A9092658CFD43E64F634BC8C16945DE3C -267546354C88EA3C459AF00C4DA9214692BDA482D65130CB6ACAAA37CFAF3CB336090A42 -E7C67D0961B02F1B2C167726893D18FA3092EA8B2CD553480FCCBCE14BE635D0399225A5 -F65F995B463D640A43FBFD8892A6DD3E0B284455EACD55F2F973023DB12EC59EFAADE85F -55139137DD595514800B235421CCAC9B0CEF4701977406565B494E6AA763FDE3127B2695 -6F0E38CEE9988649FDC62BB0C46DA3D253ED787F2997F0285CF008F7E34586E304AC3AA4 -87316B18797A189483105B0B4F9C96BC191A337667B58678C725BCCC51A5DE3FC6564C2D -35432A453B0E92F550EE81A89AE84B79C3A0E22E6A23D0F2C263660AEE964EA461A40BE5 -8D2B1CEC1CD8342B764DF2A9901F20B0A7B44E5EAB40D3F0A0601794E5B42ECB812AE487 -4B96EFF33C2BA5801A2511B074F335AF4A530880F73F7A4344D22B2A9AAEC85B1D26C878 -201247E53901F4C41CEE45555EEBB174270919C0448DAC16160EB7AE2B09E96ABD9C09AE -B7A95C4B5226D8F3125DD27E6CF0CF6E2A0D5CD6BFB414ABBC6C4A382E5B7F34BF4BBFAB -013F885C4F224147075FDAACA41AF49F4D9034C22B0B9483DE0B075E641B5B3ABDAD073B -0374B79BF3A07FCD45C148C8374401B57421B9B57CCAA25D4C8CC7C9EC5BFAD5879CCC93 -665C1BE2826EBB24893C36F75F9617BE4A54E01FC7A2F52DC845C95AAB9505EE18E370CC -B5F6DFDD80DCDA36A05051C3478022A57E91F4A078F5B486F88C17763C285A2CDB6615BD -62544FBAC5F75939A9153D31ED2CB79ACA1FF6F2483EA35AA9CA0582C2F2DE156E8BEEB7 -EF12CF7453475E7460A3E92DC95BF6189CE2144B23D4FE778E29AD6120B5B93F441D6FFC -0310F8F22E39393A21F342A59688B6C11A66A3AF852AAA03C46A932587AA5D3685A3F4DF -B1B857FB12619686F7FC6C2430B9C24F1311DDBBCFC8FC294D84EF5E99FF22EF6BB4B2D2 -20B301EB713FA8C76EC566A253A5A7DD2323D70FF5B48F2CA57A9D3F94C737326D2CBBD2 -2D7FEE0100D039D28474A64372EEC52C616F800C2CC1B53BA93A18E153CB91E089EF0F12 -318E3A844F017EF68C496477D1EFBED61D215ABE6467563A625FC0563E2A113B6A58C7CA -75ABA028750E3444F6B19DBD850DA52880F3D8B765A8E9310A1F22502BF2ACD7A3E40191 -3A1D8B7B79BA0CD8D85225CC31474CBAF4479834FF184475C7FB6EACCDD0D5F1733FC56B -BFFEA34E08A0B7EC795FBCFD8149E900F00B6E207B6E9464880A5344C309FD2BBBC58D32 -68EF30C36BB5A5C892013E8832BA813AFE822D11B3E3ACFD02CA56421671DA938398F57D -11FD157449D3E423DB6A0A4EBCE845936F542BEB5B31406A6B5C8842783A5E19A6E8FDC7 -94D322239F4866F9EFD89CD88D9FF11C167AA63A9B6707DB1356D757C80623F10B31C661 -FE9D9F118208851FB3DDB8B0DD1937005B15D900B8B854C4571F3A9C1D0D67909E1AA591 -A59B2A45B5D8F481EF7B5DD6D4E6C8CD5FBA9C812F8BEB1C2A6E4BF8F51D7A507D6B6E18 -1991B5D4955FE3210612526CF495CDF2C3CD39A26F4BF6D98DD43C4D407D261C603B837F -E8E09B15F403D721FA990224D46FEA9D7931D4CAFE3181F21B3B47A1D3910913C3110A1A -45EE125EE773556E17EB3BC516E336B2C7733D8FE30FB7C22626BF7D94EDF00FD945EC44 -0D4570B85180A90BC46B280069BBF5B69A3DCEF13EF0F159B07FD5DE0289EAC807EFD6F8 -30A20CFE8DEF807947EC1442EDBC9C32701A9CE873748F33ABE5BBA35A85453DFAFC4CBA -2F01ADE4DECE86290C4DCDFD676DA97B69BAC7A8BD920C4345DDEC907CA183FBDDD2638E -D5432F9188CEA76B10E40260C4A8B559FBC422C41143432EC319E1727E8989EEF94B85A1 -8FE398A4928F6554DA075ECAF0A5B9305580853E010CB59142F847621234B4B7DAC52D86 -151E920633C2951731D4534A174CA7685E8F617EBA01DC1C756F91F8456DE200DD557AA6 -830A506DF674D90871943F822ABAC2867414D3B9D8D410E8BE29C00C7FBFA5B03858146B -DEEB557A662A30F1C858376DFADD19125C60CF5A73C1B4B0BA6B6218F1BAE096C21F004D -8716DBEC943156F291C61FA23F1FC37C20CA2CA6CD42A3A1223CC0DA7ECCC0D4C2604EF5 -796F53C1749E6B5E2E22F52A2BA077D324253BFAD6563AC2F6126B3F94E160D579BD0DE3 -8806C554406E63CC803A83D29E0DDE72B999D345E655899DD0E9873CA47C216C902A7443 -3F54D6D8BB3A716DFA65239FA2AF27DE88A97E521119041FC89312C4B23AC10861590A65 -871B7F0731BF11E3712182E7FD8AC4C94C366E93BE90243B0F5C29201E418CDF3DCD649F -0D9A0C1696B0EDCB31616DB976F4761FD47AFC1872CAE6802FB506DD67737DCC10A658C1 -DA0CD9A920A96E5CECB844A302FF0C312C5D7A8801203EFDED0049FF37E9887132A484C4 -1D332E72A6FCE3C3D48705D86F4187910AEAD72CED404526CDCE1B8A34C91FFE62BCC410 -64663903D557C5CEE087600C09E32C8EB537EA43F56C62E78DA50FD5F598C0FEC55BD912 -BADFA2F5DD75523FB189146F92B31FDF6BCDD1119867C6480B258FB96A916092301679EA -E82FE1D96EE14E382B00484A2F983FA5272B2B86280917EA80DA0449286CE2042B893755 -EC15ADDD93C432CD6989F9B6B8DE2A83A94F2B5FF22CC849DAB24A224DEA14A11BD68F10 -06FA67E62E6507B027F21A940F7E63A09BC9BC5299143AEA8B008665C9EB1F584D7070B2 -FD5B5E0C10FDE0AE740FC6C5FFBC1693FF4D2285D87392FEAC408409016980AAC25D93BA -3C3F5E1F432706E6122FE76519F584F96A552D58855495FE5F0F4919DF8285C668416523 -DA7F2703095BFB3621FE24F6F2C97C073FC5AED60F7A32CDDF72327A1A0D32D58BB98F97 -01FF1F6CE4ACB58F44090E39269DA552D9E242806BBBEE9B65A619728E863896C26AE155 -6CE6915DC42ADB2E3A386FC4CBE64EF8CDD835A84783991F9274DF20FB6B1FEC860E54AD -44F85774FD50E3B7817173C23DD46003BCE91605B7F861666F0774489635F4611060EA85 -8D66ADAA95B2BB066285F485B6CFC8FD3754B01CA01266D27BFD2712F4DECF25AB7FEDB2 -A4455070BB51804379A3D4D184E89B1D1BF94F870800CADAA95FB57B1227F0B691D253D4 -A85EFB1D8D182049259115AD8272544FBD0CD49E7A9F551E22F027272C60A1367CEA64CE -49A07AA8183B4B471D83072DF31DBD739B6F64158165F8941084E880C8CC46F06F3AC420 -B70E97D8A8B3DE6478633FBD016C258DDD12DE9062988CB9CEC82E21D9960971AFBFE9C8 -B2DB92E3F848653BF165A78118962E8DBE219E4FDCD68BA661541B0220B2AA0CAD74284C -8F28AC3E19638A0EB29903E703FC1145A0E9D33584455E5D1FA7BD6A733F8D8AA9AFF447 -583B0176258139CA3757A4FEA374425E9BE34B4683B392B6E334951FDF4E6047077B7011 -39F27A73FD2B4B115D8D408EA5E14636470794941040894AB66F19EFCFE812AB289C3315 -2EB58271E458B257F63715B3C05B454AAA50290F32AD47F089DABB1C480D92D69FF08211 -7C867A731F50E3EC9DA99D966AE570F584494A3A55EFA002D97D3A0EAD08DAD1494E57FD -61EF7BA94C4D0C3E85732A07994726452A69DB3C27DFAFEA6BD6A2D192264E6B4B846A30 -A6BB1625381511EE16BE4CD4D5C7CE332A8524AD748DE4ACC5E08F3167E99F63B785964D -B5871FCE8BB244F5DA0C7F00C5D198B13904D2B57A8399420AC2DF333B638F2A29B2E261 -D447F2AD9EA4F11128EDD65C6524A6B53412A7E92B1F3D7B4F7338A1CEB909357ADB0819 -57C48AD11E96AF967A60638E91B6FEEB4AD90C33F98AD1EA2B51F302B51D6D1ED82DBE81 -3DA68ECE9BD145FA28B7B6A5D6A9F7141439DFDA0E2D59530751F16B010326B54FCEEAEE -2E5644C6F693FECC5AFB1F64CCA65DE08A89584B90D0B6B5C5F4CF75F2C2B1CFD0D32B2B -F7101CE6BAEE7D0E845E975D44FDB3297D0944B9268E367A2608BF4BABFE4142B692CD16 -73AC17BBFB416A37580302558CAC6F7549CD60B75C9B5960A86E050612E9EE6DEAF19EE2 -6219E9C5D28AA076B3FA2504C1523269F093A0E00268E765CEF7DA0DF01AA3DAA12926B1 -A89D9BB8ABEA16CA2D2867790C7553E1E87F8CDA07810A4D94AEFFBC15FBF4D543BE0967 -B11D2FBD221D5BDDAF28718E4042000F5FBC07CD343FC7E6D9A94B8F6E9EB3B02D5BC584 -9AFA37ED5AEFAD28217ED06986DB0F51D4632CC5D1E2A49B950C3666815FB44BD4059294 -7401269A17539E88901FCE325629E59AD0CC15D6C3FF32D2497DC7A9797582D88C7F03CC -F2F230692DD463F4A471540737E6995FC32200E7BDAE53AC1465188312C2FB7B52ED98F9 -FE530B8F1CF8A6675FB9E603F58BE9CAC46585B6D305D888822806BC5FF084210489FB79 -2E511A939E01E69AD152624777EE98EA396DEC7D2C633290FBA60BBC153D9A0C1DC5A269 -740EF5CF4B2879A839932E1C8850D1EF95E8B5A0D719351EFC71D7AEEF92EF29D3C41D90 -86DDA4AAA9735908CFEB590E365B69B2D2FEF8193FB2CB24113859F3BD2E99F01F2B1B4E -080300193B5AB6F7711522EEC833D74A13F8686A6E585E7B6315FA28EA544B4EAE4EF62B -88B781FED5741046AC84484CDD1B670017F0D0D2F19D3EF24E984B14CD052E3B38553850 -6307817BA3938801B9E1D137447D979B5148AC1B822D49059EEB945AEC4DC1EBEC2FF6CD -DFB19A0370A02F9CAA30B6725A6CDCBCA72242B805E6559BFD292668FB5ECE523F0F44E0 -E75D483645B6988AFB0D5E8EC5688CB56B69A7B6A7F160ECC40894BAE45AD555571CC25B -A86E81C5931DC238346DACF3EA05C078D309693F1E812BA249D84F6AD605D073B22AC83A -F2749BF32A32C9115AC414D58A78D96A0F480C706266244B6A668486F54A16973E7A83B6 -36EB03E66507A277958C19D9AD4DE66BEE89B7463731F724DF5650CBE74EC300665131C4 -01BCC4D03891C6ABB61FADEDD7C83D56F35BAD5D731E0B3EA4F9C9A07FE5D3DCE21B5BAA -1C8E79B19E38CD61EB802B2C2F467D1A8129D45788B85C9F7B53232501ABC0768CF3830C -308A87783868ACC346DD0141702B517E5C07B5E29B238E55549F98EC3BBDB67EEC173ACB -0DD4B3550D958C7E777D39F9C21CAA5B51404C28DE12061DCA1CD427089D2AD99D23DF19 -B0729235CA955CBC5E4077A0FFBF3BB64ACF02204B706733BE9CB2EFBFDF21F62E4E7ED9 -34A78E626472A53747557AE2C209324D1F8278E31FF96305F0BB41DB5B165AED08AD9312 -F1FBF368E09C4A4004649E40D578DECB4A1F82EF4EAF76BD8CDA9C4C61EB1E187E7E319E -03EFEF18E4969C5DCAB53D8CF41AF5D4DB3D9CCBE23D1A126CB60B1864DEF1B702995622 -9BDFF2387711F1F06B807841406515B774B970666855333607B4DBEB4B670F6A452AD43D -FA2F83DF711AAEFD9FD74A307335AE574B4097AF88C2B4C928BDBF40F822BA98F7F8CBE6 -26DB9AF8DB0B6A309680C026E9FCAC9A541974056EEA1A0F9F71AF08237DC5FA78D8C38E -5E057DD2812E4591CA207000DD62CFF38CB97C8049B8CFDF0CE6BA900CCC85E02C758C1C -27B00DBC3FDDDE584457C872ED79218368C8D8F36079045A6B9AD62AAD7A53E2ABF1AA60 -4AB15BEEF2736FC7AABED55B17B8E665B58D03CC42F70EEA4AF5F1D82B4EA91ED721C498 -DE4DBFF06C3E58E0350BF931D27189680C68C68D73555F02B76F1A786B4FEAD6D6FF846E -370790C8529BEFE512A8AE178689A55C747FB7603D3F9A4BFC36FE91CF212CCC569CB895 -7680FD2D466A1C057C0022B4972841AE7746C47813AA324519B461AAACCAE87134DAA64F -093742B7B3B691274EA2148071E77E636AE14ECD0CC3C9CC7C18ADB23954FBE043DB23E4 -DA069CDD55E908173D71582A774B57793F5228274CA43C4EC01FE31CE14699656A9EB6AD -9468D7CA25467349B9F56CF2873A09467107F6B9C20147D2095B7294FCBB671EDF0B804D -76F6E1AA7CE9D7CF60CDF7F85AD1C410422A779B908F3E6F6C8571B6FC4F7F012FB99FEB -4292E9F354A3E9DAB81E22D4C75DA3BE9C8868BF2395D815D097010EF8A6A58CC91A6FBA -C59344E785465D4B91F7633D1718D16852CE793825CC4B422EC90C3216999A55400FE0F7 -CDC38A0F6360802991885FEB799FFDB3C1C87C0127CA781A22BFB9AA8A6D6E414DD2C31C -CA6304577E4D617A5388657632349D4F49D1582152E43683200FC465146137FF942F1888 -44975B7A2E508083B0261E8EACC54747310FFA32C00A0DF9B59F77A360349E259D9DB841 -47ED76941E8C8C6F053116A004C3998B7C84D94B60044480D048AB31F355B8F6768C189B -E4A024183988E8C3717BE19D29B4BAA4A94A3624C0DC4F8A7A99121DCC71EA32D2B8D6E3 -B4DAA6B632E8D64717D32CC76C1322BF2FA82D3C349E7FBFAC44BA0304E4AB4A8689D819 -CC3A0DD336BB7E45CA84991DE87CA3C615E3DDED468DC67E402BAFE01E096C61E0BE0645 -AD50A227015278116EAEBF7895E5513E4A811BB90E1D2E204F3E0E656B3F75D25008E84A -9FC4AE44628B7B38A484E23992C2C1EC229EE966480FCEEE199F0892689FA18B489F2C31 -F2F2196620809EF6E0524D99A86C627B053EA195870585D6B3C54C3B55C80E352482998A -2673772C4524BB4467A867FD953C07504C6154201CF96D422D0A3151342FC9C66DE45FD1 -29EEDFC9ADF67374A4C1CD2E76048EA9D4212A32F468E74007A6C3A8251DAAC735228DA0 -5C245346BFB1903F217D62F63087721672EC60B846652D9CE8AA2350919ACB2D8490C6B0 -5B63EC808D611BB1D7AC1CB102AD7350773DC8248384D1FCD72953CE507723529CD4202F -AAA080F519FABBFA48C620A1511A2FCDA8BA96E7784520AE0093AC58623AFCDAF0EEF6B2 -5DC8813512254752576AA9608DBADCA38F319EBF5164C1244FC3B6DF2523D8D8F19D23E3 -53C1C484FA52DA7B8D84D71100B076BC3082DDF29D6A14AE8BBC72B1626F882C1B98EB3D -F31DE2C5174A0AC1E5F2F82EB3CFA93EF6741473DA694CE020EAC6E1EF41636351E12946 -E3BA2B1D0246D059563F2BEDE7A67648AE6CA534F32E52FE7F4F2CC936F9EF70C8EF1597 -A073E36D237BD34A3CA8BAD7D01C54BA5012C690D680158A694D2CC0362B7FFB8A888A39 -F2CB418D7FDEC46B0E5F104A032581415B083A992D6E8CB4D0E9FA93ADDACCE7BA34D919 -9E579DC050DA9032B1C8ACE46D1E2D224556FC0FFDC35FED173D86FFFED1AAE13734D1DA -D2F06EDFC4FD311FC2279A79783B7C56928D5EA6F8FB4560776F99BABD3D228E8C62CCE6 -C06B7A122FC441CC5490C9085C8A469F524403B8ACF9A607651464467DE098CE068FC171 -55ED9489C819F31A3BA4E1EA3C728212D8C40CC1FDA9EC60AED881A93A411592719E4FFF -B035AA8F25B9DA96D536969496A96B05BACF2BF1C7BA6EC50759CE388EB3625683C753E0 -E3383877F4B2F74B1951730F51ACC3B0107B6DAE39AD2B17E78B4194F5C8D162CA37104A -E00F81F7E254B4D1104C01F404F41CEF92CBA628122589CED905CDE34196FE690EDE9CD9 -AEB0B9D7645D051E78CDDC34B58A64308A2CAE739A825F18525688E03E6138F5DA8D8898 -539F5E4BFC1C64DB496A16D9542674AD655EEA6DAB57AE3FD9058532AD0301CA47AD0B4C -6998716CEF388E0B2FAD6D14578958FFA3330E3759FB8EBC2C25C61EF372235135D2853F -CF308CF00441DEB973BB742C7CF4AB0C189B9FAB10C7969777928CC525D9C122781AEFEE -8B82537EB27D7B264F5CC973B096B13C688DA097128CA6467997A5401DCD797F08EBF73F -AFB5EFAE784C63F5D81CB073FA5DDA3B8F78FBCB37AD0CD54514F07C59B6FEDF0C86FC6C -C0C5E03D5B75B147D0EFE4A484A55555F7FB840BC2DDC488A1AE3C26A22A7975C57090C5 -D2A8E484E6E7831AA47BAD43DF7C1D5C92AFE866DCE8E0B81E5D36DAA24FEF28D44C5E67 -18B277E8CED636116EF9EFC5DD3F06241C40F23A6334BD4C7DB7523C565A669C19EF1578 -329B297AE7F4EB69E25EC5F9BA77635BDED28ED33E3D1FCC4EC257E4BAEBE188003E3AC6 -BB930837230D7625415B260E4CAA348690646BD20F33E1022E1926AC163A59CB3BAD761A -CF10756E27B6FF79801478D2B3F1CEA0B64835439C60AA4D861B7C4FF471A169482B751A -C64854226AD0E38528F72B72FD8472D83909464F26AD09804D05D3B6DFAAEFBF0D0AF345 -CE1BD364299B1646141C294AC917E55458DEAFDDF0A9734218D5F5685F0ADDEBE6231377 -006D9E3FB3FEC843050CE2050D818396BA57EBCBA3ACF483A42EAF1C434B35216305BBD3 -F9598DDE9BEE0B47A4B8984849063BA638D97AEF425CE3C5A82F3A4B2CCFCF9711B77599 -32D10869BA44FD4DE4D9EAA863C811DEBE27EB910C265492A45BAA73973E3D8849218608 -0B6285D62F797879D6E118341BBB8AA44D0FE79DD91FD58F988D53AD07C17AE0EDA91C84 -8F2E83031A8BE1569D1E7FF432BDC605E434CD52BDBD52BDFA689A6A52AA4204BBF90ED6 -5A206B03D55B8E275755DD2853D6D944AC74107C3160AD7E87324BE16F5B0D6FC37DC819 -8259AD5C06483BC15F983B4FA914BE907B9AE230E655EB1FBAE374EBFB84553420C34D61 -AB2523A8C838526A9C88A1467E0C27AE1C3DEC1B011D156C8D8C2AEA0B7ABDA324656AB1 -AC7D4F5CEC922426E9D5DCAD965E0D4D0C5F4A223230E157A22DDFA14FFECEB183168421 -CB6462B3109211D59D9F00AE30827E55F27C17A7248446A21F4107973B0BC987919E692E -1F76F7F540F7A4C440597B265290601FCCEF11BAAD4FAF3DDC4AE6218213F42F2BB253BC -E6B0EF2E6C3858988141C626DA7A65D7E48175E4DE032CF76619736AE7BBE01C026A3970 -EC79C5DFE931F076DB5F674C163E5367F03AE6E2E7271B273CE5EF0004D7AE89B63DB32C -0064FE4980ADCDE7357820F5943FF1B2AC49DBA19B2F124F15C7AEED84CA6F15C30A9A39 -3C7D492A0460E2000CDA313E9E420C5F5E47F959CC2329B6F8A1B7B818F0D44A2A176614 -D847F360F445A4168693257AE71D832577FD2E432EFF0E9322B3B4A404EE13501645466F -5CE3B19EA1016D089DF6F96E5377A68592B981E728FE3DFB2449C7F187B3DED6F5DB1D55 -14FAD8DC06D95B6B4377AD1F0BCF7B744EC490328CB734FB1A45506F9B6EA2B85E7CF093 -742CB10D1D5FB7664A9A7DA82C2C2DA07F43A95CDFD02B9EE4D954B2BBDA540689DE8A37 -62219CEDEDE4C78F7E314EB519996C0610ABD85C749012C63973AE84DE4BF8B6B1333024 -BB6E856DE3BED4C890DA1B7612689910607EBC32814DBBDBF179AC0E7C8C0A31B19775EA -14DDC7057CA38E53EE24A11CFF34A4E78672C14B215A8F7B70F3B6231E8C9E2206052580 -902E05AD3FFE970ED2228053898E3EE2605B4D4B364D463F0F3ADECA545BF39E0B14E0E3 -A7E5429E661A9718CC86D935E11FB2DC10FB436AAB75BE0AA27B8480AEA99AE6ACC68698 -7D69781BC4791A2A202B0289BADD16C29FD7A5C7C1146E51B4441F1BB5CBBB04D54C336D -B0AD62057F7F97AF8F7BFFAE47D1BD86D2936B8BABF25E91E41CD8917AAF282949F0D9EB -1D4ED2B89478BC159FD71E7207A65437B20D18144E4BEFA99C89983FBB71240EAAB20E62 -40E63F517EA139D1AC71946470F28E0BC26DFCFDD4533FA5BFC0C663F53C42BBFC16CB96 -8C0E61E2A6C4DB7B688ADD4E2F9D1010FA4B4E8E278236C66C7C1E5FE6B3EF982A970C22 -11006A98ABA967E7BCFA17176463E2509AA6218FE0A7CBEBD9F9151370FCC669EEA0AFA7 -265F498B879C4C94AD02327D680059C8F7A388260D1013DB99887C5BED8A68925C3D9E0D -56335F93A402BE584D1798266F41C5FF3C647DDD2C2D788A7A56C8278303C0E9F20F8595 -4F6B47B79B6CB9C6FC80AE76BABFEC2B750B5ECB267A6866AFC68A51F6FAC54B84B9FDE5 -54165EC7104F5626108754BF07116A75EDE93A35CBE84FE778DC3BD50A8421A959B512D7 -E7881889E5AD2DCAF9CEF64E86A98BF5384D4F341B53CED94D430F3DAEFB506EA693FA23 -6830EC178791B015ABE069A44CE20752334986A43EC06F8ED44B0796FA741F0B18BA5821 -10C4D7C3B9B681047FBCF17DCAE103ADA23C9D41955B2C0DF276D5DEAE83A941E8241B51 -DD9FAC40AE8FA3B9308470CCCE30E17C1C015019E1A69BE8A054194A1190B956F414D473 -DC5605BC7284C0025F01A715D7282736704B3E824BEC160772EA327572384DFFA650A292 -FEF417B2C4B395AF893BCA339134D3BDE3E4A8CE7D76E2556C59D7292003C5487DF76D55 -4549FE9977FDDE5460389F32D5663656528C257C2057EA3EB5D70D20F550824C71DE3212 -32A29241C8BE67ED9540B3F461A001C8F63898DCE28423A3F5CE806DEE0B50E8F5A76C86 -530491F67C48B8683996B6BBF6DBC1666BC6E9B2BF4624701A67B52F792333DC12CC6142 -B2568EBB0ADDD4F9F3443D45204B013E098E62C6ABE0FB14C2158574A7C0B24EDCFE3557 -2C5C30294889CDA3C7C1C67558AA3C05D012F516479DEFCAB7ADB890F9E96E9615634176 -5E8BDD3CA8E85DA76443A538AD530EAEB42E6876FC74AF2B6AC2526F64C8D323B5F5CFC3 -BAE26A4F30D4477EFBDF054BC83513705CE5830AF048CFEBFB4AADDF2E7483A4F1860D18 -7D318914C3622F4EA58942D5527484D2AF2D0AE2DF74A1975268F9ECE82E364F5A3B186E -39A4A10049D6358C044B6B05E9B90217D0A3BC0EBE473DF1A7CE2A4DA8D5648DE7BA58DF -0335B7A4C4DB44B2BC583DF0394BBF14541329B64142B6FF4E37F523DDAFD8C1067DBE8E -4770563B8AE958C26BB51920158795D0A4DE9DDD3C2874A572436749FF5535BDB59E8C83 -E421F605083516551E89A2FE34FB9B4AE55036A3D7ADC71F64281A3C54EAAC2670CB34E2 -AE94E71943719DDD21B8AA335EA3181896301B065FB0519AC8160BF9FE18957E5B72396E -240ED3A9779F04FBEDC858B2DFCA71863A17E73D53958AAC58CED0DD0026D562BE9F395B -49C12C0C29D4B84C28881D17B10F5026F8B208BAA6DA070F94110587A76E00282D3CC5BA -D88C3A9A714C063F8B325495644DCCEC332257733448C50A40DE95BA8E5AD73FBBE404AE -EA1B1F49DE4F9F1770B73ACB5E9CC4B5D1204A97335197B14DCB3DA403DA430EF0C2CB46 -E050B1E17FE0105A619BCAE09A33CA4DD54E84B8568299C1F2EB116C16D54DE40D9880D1 -B2FE45706CF0340CD591FB94B130BF0EEEB3F1EA675B032AA0A780F0E0E69A63E932E01F -43EB43DE97EF02CAD65BD2013569695789971D843DF14DEE9A32A1EF22BAAD4A4468AC40 -588EFF9BF91CE0C09C30DF0E2504AB95E85E70F6769679C12EC83204FF0C5CEC67A26CAE -748F530A80ED96E3C6D28F8F12F5B3A7A53B1BE5B096B0D186784402A3CC1D4EE4162128 -D0FF956979EF79DEEDB9732249CA150D159D1FF502E33E4A305F066A9617BCB637DEB999 -DE15A2DFCF9297E2E93F65D90A233B7F512882AB88439B26B9C672A08EC301262BD37164 -37191838D992F15154E96EA15454E4EE9E9D4C01CE2090120620F5E5A0849036975EDDE7 -9E207B17DFA344C8300D07BF024C89B9621F8FDA10A5032197BA4B6C127FC68C3D1397E2 -88219E9F151363321807084F8596DB0A24A8D6E41732C843C01843A9B4D9C1041D28C7F3 -F4DD289EAE019B6E8A3CA2952A8BFAAE3CFA6F0527BD3CC9544196A0DBBCAE1F095C3674 -B34358049CF212CD96530B9875DE99D93BFF4D87E544C7FF8E79F757ACBFC7DED0A8FB1B -4BD53D1E76FE95E930E3F329DF6310107223E4E576F38CECAEF561B5E95CAAEAD603B792 -F1B1BB7EBE2C73E7144AD8D50F0581AE74C9A811A52E986FB6E249F9290E515639900754 -C8FBF4ABD9F642970190D28CF4BEEFC7C39D1271DE2A357949A69BDC6D8343487BF6BD25 -1C1DBC1132B1FA6FDB4D3233ED570D9310F8C9DD92B7217EEDAE942A25DDD6D5C24BB4F3 -9809C658BCD0CE41C70709AB8899E4956D9615C1A2B1A627E47CCC17DA3454291667EE26 -AF97D99AECD1F7AAA7AEC910734786FC797D819AA8D539D10EE8DEF86E4499010310E241 -C9FCC7F3E2B0FCC692D9B2D8346717A5781E6AACF1A891E2E6E65225F35026AE348E0E16 -7475CE6A9A0C14FB588A483B9483AC475043907935061B48D03677ECFEB8377235E44F7F -581F02557B6F009E964A4C345494EF9EB4427ABF1D2DECCE71A87D55C57ED6E561CFB835 -8C8A38E387531A6D04AA87F5AA92D73B2DF8C972402001B9FA67DADE45F803540AD55272 -AAC3A49F23F910EBEE137F616544F86DC7E33CF672859A545677018279B5D1AB673640DB -4EB45C3049D2BAB6116D34B3CF6A88ADFCA5A657E93C32EF5912DBCE65C9527C068D03D5 -A23A29E934391FB4317CADA46B7CA8A4F0440CACC958028D20197C1F1C0D3CF39F107548 -5928CFC10177DC70FB5133A7ECC5C82C978858DC1CF44A53B4461E85B6591131B19806BE -EB57CF868D200A7F27567F124140D712AC0DF6D6FB8045671207AB0CA4735D4422EE8133 -3E0143072416E707CDEC20286F72E3070E374D79D95CE144AEEC86E6DC9001B991F15CDE -9EE7E8368B4BACF9DBA6E83848E5A3088C2858C71BB5841E990BEF89DE5ED42A6EF9F0B7 -8127DBF344A29104E9272D0ED77B5C32D245B17293C54F8D939E314350B42D95A3A2F4D7 -6FEC437F8CA935638E8558D7919ABD0DBD6323F83AF703B38E8445FDCACC8F1919D2BD4D -808D18FE28285B62FA958B34CFF05150BFC884F0A323F67CBEFB98B393607F500530A1BB -CD2E2C93D25EF97621F872091C13D1BACDCE7DF636FFA29B24C51111E7C10F0FBD250FD7 -0899B2D370B955A7B467F9C726CCA0C1B05938FAB3357BD97FFC32A78589BAD9B54CEB88 -E0C95CDF9387637A043394276D50FD4E6A6170DB7325B11EA2145BAD3643F51114332630 -229198CC4A68C207E61284CE848E0CB6F9F7FB24E72D5D0877F2697F39F7F9F713FE2360 -A199760E993836E477943388D08EF210C1C782E086639B507CA9CD5428FFF902EA82B280 -DD203279043B62ED9C93150CE5D365C3ABB3C353172273AFF2C75BCB68FADEC1964DAABA -777D83401AA12D8B5173796F691D8A2E9BE7FDA49421AB46A014EF1C566B78AA4889C684 -D45B5C9181DCD1B12D4BFCC354454B6A85C4FA25E74D55A1C6CCE8C4FB9ECAAF885BE22C -A5DBE8ECBCF909D4487E6C64DD9B489DF6BF4B1F2A38B7D18983B2E41696D55446FE1261 -11A0940EB96A23142770F5A17CD8D89E85C6CF269F6041B0F32467D1DE4C0335F543CC07 -492BD7BFD0209DFEEE502FEE06D2D0EA9A0F81CD36DBBFA8E386BF486338444DCA97AA8F -83FDC85A8A88A801854C22B3849467A660173E5E81C055E30CDC869B1BB9C367923A3491 -F51197DC9971B477FE060AAC5C91FF8D67677C3B08705254972D8CBB0DB05A10771844A8 -4391AC7B60179F20E345D2C9DFDFE1C42D947DB12F84F1CE05991AB56FE498345230BB3C -7F92A3AF86D20828D86E931BEBC818BE595D2E17D3F9E105E39649E89E13656F9461087A -36E1DB0DCD850BBCD07249227B65E494CE8C88BC106F7CEA5EFE48E482F66F5F6763A766 -0262501535FA5FC71CFA87BFDA2F8FD2BFF0553D2008EBF081BC56BBA010C00081EA5D80 -190C4FFD7A105FE500915F6F652A0A00FF97A7C825E8617077473C38B5D820C24F78E387 -A776A8904C265AE4CABF3D1845011DB66A4D732F842FFD7CA1F5FB53714D0EA9F43AD20D -280FEBA87134571F5405A57094243FB22E12635ADBF0D1900E93684D1D8B5EB04D9D01CE -A3CAD54C9B4666E336DC6EF82DA6915CEC1F11C89E249B0A5C460BE552BFB4AD545CEE0A -3A97B65EEBDE82FA1893442E7446C901C50838934D82DB73DB7780946506B966CA83A142 -5D1A82EA07C3941EB1942325E258A5F39BC9D7B8D84F7AC876C9E47B854BE1D40154A54A -DC42BBB5E5D318A6E8B2B985F2F87F5A2486F261CCB59F171111D04D29E38CCB692F21D4 -E5909148ABDA6CE4FCD577E3EB39D8199C63E1EE22443B0176D84D2EC501F16BD5B01826 -67DCD1C99DF0A8B3F27BEDD2917BB900484171D2AAA6E0B39FED994DEA6FBA6877EF4D94 -F552177A83541F4111D1EAFE83A5D102A011726403648B148DEFD8754E91E52BFA9A5F80 -273475A427EF5C5CA4D981A2D98AA00A4BEAA2779FF342B5EC0A452F860620B88AFBAE3E -1FFC666C05647B3E73CD54BF35FF47411585FC84CFD702FA116EBDEB396AF5D9C298C3CB -BD97E8EE08EAADB0C854F18D2AC5D08771ABBCE5B70895E8F04C3CCC49525BBA4407E081 -62A272E0F623578EF4502FE2DD325DD87021079967B1FD01B95E8A0CC6E65317D947B340 -7B42052106F27ECBF69B431C6D73F9CE9220BE91C38E1AA2F9779E128BDA6A76ADE5AB3E -B9744A6365A95368D5F7C9C297F5AF8C0E21B16FB8B8DDDE4AC3EE393BE599B2B3E3698D -38C84A69DA371E8C323EA53BB232F07A761473580CC3F0CBD5C73FFDAC3BAFBB1D9E7D77 -1CA641EFBB2A190E8DFCDAD040736BE41D29723711CE965926CA4A56C6E4C5FEE60C6634 -C3B3BBE74BB0ACB8BC0FF9C426679D863DC1745AC462037444B6631529D8A8BB22EF605E -53297B146FC90E7A751C5E151545E89281BCBC7271731E5B0362994090B2560A8E62858E -860FF9644008AD601B15FFD2BC3D25D06FA0D78F003AC39D89FE621C1E368BB9221E2C59 -15A56634D5EBB299635F48DFA2BD37431E224E38CED95C183604B9CC3C8B153434D6DBA9 -CA955106159337D2709025F848B5440990957B0F12D416F823A75EA2567DD02849BB9B98 -FD5F32844E8F24ABDE050C333DCD9C9E4DFFD97C22C0045740B6B3E94DD8964F1E601544 -4465655844C809A51B9658EFBBA085489139EBD2344E68FFCAF99BC6C50C68C0C03EC1E4 -0C378E68F1CD3A8C459D732377514B1CF1594627569C16F9441AB05F9B4D7B1A6AF79E5F -E62D1DAAF71234F31509DD947BF67EEBFA0FAD13B794D4292516AB84FB96F5DD8C6D65C6 -0B822B78E917D7BF5BA9F2A4C90D94625B0DD2E31AD0D12EB3AC5F882F72D07F88045B35 -55AF20B6AA3648EFD5CF73798F3CF86B139C909D1D253FDDCF78F0915EF8CEFF7FAD6CD3 -C784BB88B8F31D1DA52FC67500D064DE56C233C333CAFD866D102FAFA71A2B2FCD2715EB -47C5B65909EAFDC5250EDB78FDA4854EF0706F226C1191ED8E1ECD79A43BAF7154547059 -D567146000900625B22D3F7E356DFEBC00D4B6E6C1296A4E4038973B9156D5D748B6C0EF -0B82B459E24670C9A951629E57FA90935E710899C37A5310822E99AD7D7B32018DF94FF0 -E723CDFFDBA6BE5DE8FC147C794E9FBD12D3CC53C5E14A328F6FC6C6FA479A0E0F760253 -899B220E7ACFB537262764F994D680BD4A48F618E7FFE9E92FBB09ADA32A7656B14E53C6 -B43774A908AC61698B44B4FF91D6BBDA42D53DDF348CD277A2A07A0ED439FF4D94F769D7 -6FAFC6F19F7A307927FB233796CA701B40A1C3E93A98703802B5D41F8A57F0D699B7ADEF -AD6D130B06C3D34C8D2414A21C75D4FAD9EEF2791AAF7731033336E141E15CFBCD7C3923 -C663CB78D678F222738BB970C5ABDEC1C983D465F71D8189A9F1A031875460CB9E46FDEE -A4074549FDE7A01F209409850C6848DBD1C9EA058A28D224363CD796F106683166A00DF8 -F5239AE3288F9D0C14E05217849FA07DB6DE17148462C0AC9195FF3C20B76C452DC58273 -3B81BB7526C69124C4AEFC411FBC581C29E01494C28F40A9FA088AA7B727E5C6D8842122 -79BC38AF7593B2A53E8B0FAB585CEF88D5F497727EF2342F89EA4901DD5FC97AFC1BB805 -817AF7C8FB9E1055D8A2DE3DC09C09BB71A999CABB055C4E2600D91BD4A0A6FB2E9066DB -CDAD3FC26D0921B2B9ABDCF99D74CEEDAE954EE6AC80E6AF69EAD98BBF0F14788D973381 -5714B6C0BDA27CB3E7235065ECF910CF27DA939D6354D3CDB120FA8E0E1C28E48445BF7F -06CE9F6867641A9238175665ACA110E8908243CB693C60D369E1C12D39ADCB6350395F6E -7ACBB1FBA75E91D21C141394842D6D107CB412C754C0068DB283EEBF44046213B55C2BC2 -5E403DE803680684F0F5E2054548D3AA52D5EB1F4E8D32279697818359850B50DCAE5559 -B000B4D74C97AD069101159A5FC03C66FD88F44824E0D28681870E6FF118DB32ECD10A88 -1540C1B63BE33ED8EA640F50C47055797C2E6A04BE027BA3A2E8F9344FA48BE1EF0D3A58 -59F9CFF0FDFF085F78712C711D4AEDA295775AD416408D226C4DDDFED69F5FFDDBD3D6BB -590EFE0CBA5404FE99FC4AA90D53FD3CEA35AB8042784717D1EB67529B74825206798862 -08D744892CFE8944B9EDB4452072D39363878167C371C3BE4816955959F7773BB66AB794 -2A2EB43BA482610A388035F9542C3D321BF1B1FFE827812A6C9A2F22B17CE0D04BB34653 -02D0F9331F41370AEA4F1B09AC2AF71F588B250D4B777CE024E9280CFE9EB36D9CADCFBB -4C1BD4CCD1C035B15D736C6F49AC229909BC877036E6F584D4155E0D20AC99E41040AE3A -23A0645A1B3C8C9553840388140AC1B49585231B98797C1C19D483A6E69FF566E6DC0AEC -71807AC1F4D3DBEBB2F4A4F6576DBA8A0B1B8643C9BD1D97A912E90A737268F6A91E0A70 -FEE73DAEED851EDFC631701755AC7B2EA3EC8990EBFB3EEB64B75FF320BA84821750BE74 -F2F2C8097EE95B2402D6F4C31E1BB947A5F86168745F8BE621289CB65BB1AA299214F52F -80950D6AEE089AD94BA4D19B9767B4B3D3CA631DBC1B2A37B3BE026429532E717BCAEF7E -8BCE17D47F40F3665C00A0BD87BB6033CD56FA275BF4BD06CF4F2B0ED24A061064092815 -9D73667E820E4235F1C4E629610A1C260C43774831CD75A5375399644CA9C46BE2F516C6 -7B059743008E82085EC673CCCA702BF07B8A9F57BE338D2D0F8D2FF6090F3AA1BA20A9CF -C02EC2471992118F070FEFD45B3C0FC0B55162490FA9D9DD60A6732532F1AC45A4D5ADA8 -DAD9ED5D24080E2C94F6A30ACAB0F075A50EC19544623D14A5A9A783A61A75D6F6E6249B -7B4AD8EDDD1154ECCA8ACA427736DB27758A0D7AD3F79745FAEF53B171D96FC735281986 -C4214ED6754154011F4D0B1BF910142DA99D3BAFC74D8F2BFED52422BEAA5DE0BD18538F -1C8CA315FBE5510954227B90718FB84785E0ECD9243B7C991690D2A7ED913E5080A15D27 -927BF869EB1279474726B8317FBF9B77774B2A97C294D56D02C40087DAF596AC35C2BDBE -CE3CC534DC34CB2042F85F686F4FF4098890439464D56CD011FCB85BA87C6B51E9C0ABCC -EB9A96152F5137E6590DE02C9E9C24D133FF585394FC59779F64E1AEBED7A007A269482E -E8943604DD95A632EF16B0888DD6080EEDAFE8F386E05427DA25E6D15E38BAC599A57266 -C416F20DB2B81BFB7AF0F10223DF1E760C2B3EF6EC37AC447833E8220604CB3643CD2CE9 -53FD9E2D22F6053A7780F79DD161807B661E196C77DFED2AAA7ED10253943A7FA2C25602 -3586BF0508910EA8C688036557439C183A1E9B9165DC2BF055E58DDB25672E7E701B3CCA -056B592AE84DA9278C95328EEDECA8E7A4FB521D3646F3195D9A21517DF98B334AE2E201 -BC4D0D3162B6D0F53F801263DB7AB69F1D2998038804A2A8E96E588853D7BF448C3DED2F -CCB995EBD6520A2C6FED07E13EE3E546FFAC962C6C30F570B8BDE1ED758550150515C927 -2C6760A12A097D07A6A8AC10C5FBB66E29BF85A74AB804A6CC99FE01946620D14C3B8B6F -FEB0C74E4EA1A225D5B9B5DD45389FCFCBAE9D45AD3C7F3E875C0FAB231F7902B5C860F0 -2B4A13B39AE999E051B7B8D05BBED72B29ABF13ECC485FC1EBF0DCE452ECCFE6F230B2E6 -B778E45197B80EE42F4ED63DAAA570C4ABF8CE4B30AF7B694B70780F96BC9742F7F1D3CE -66AD5E473D8CD8002A436B078918949013B721329F9A931DF6F084FA5FB7C66BA81B6980 -0CC79452F5EE2991BFA84EA8689A5B7D20AEE04B0E5B0FFC03B8D8D1DF4F1D3FA29BD6F5 -433809C897B31F184AD02C8E9FEEFCA647EACE79EEA1DB444269C3F88EBB896B2A81995E -9030FD059C48589B1FECD0F98490152F1A1CCA7929F19951D345E342A805FE72B4A1B4BF -F2730AA22A41D1E07A890AA61F2B9B6607191C92D052A673B15FD49145611AF6754E4F32 -C12533BCF702626D7F1E44A7D7150640F09819CEAA1C0A2E2E8FCC3CB262CF29232A38B7 -F0EF66086AC8197B5226C5D69A6F57F16733BEC14D8E7A47509BE951DF1B810CCF6932FF -4DC57D208B13AB86C0E22569A6C11661C91711C35C61BDB6268C82E08AC53589A13FFB3C -F5EDBEC7E7A41CB81401DF66295606B544A9DF4924416423D6732B4631EB73266E370083 -16D0DA6106AC038C1406A5B6F8639BE3EE6C880F9DDE71085C6446F9F2815E2A6ADFCA93 -5A7BFDF4D5AFD5CC7C8C487D57B090A5CB7A7712E207FA7000E39CCB41AABB32923D5E1B -C8D7F2C05D9A3FFDAE5AB0BBA940A8A25114CE99B207FC2DB264D44472B188C5CB9F41C1 -913B880EF8108348BEB174712B2FC1192F37175C5060C9B1F63F729A4E94D0DA524E2DDC -ED8C1F460B782DC62F4C23C6C0FDDCFFA7E2F918CF417C2A4ADDDE53381F65E3DB52D291 -C72998809B59818B71BF922A04C053E2921679838CF482AC654E982A60D2C097C4A5B134 -34657AA08F5568536FFD2574AA4A88873C762371971480ABF1290A05AFDDF9C072DD721D -EF36CACA75F4AA4E28F965AC02A54735E167A7DABF06ABD1FB339E34848F1CEAE16D4744 -0107AD4A526B99C6396BDC4426B858BB7FE38037F46E180E3F8108C79E457904E0AA9BFF -6D3E9B2A89D3F40ACC279C87F0A1DA1245AC6E766F7FF56A7F7DB7352673036D8162CB5F -C666B6F2E944E19F78EF0B87EFAEFF4209A5F83A563A6954873F88B2CB402462804E2850 -C1C5379CF747707E54B6FE28163C31E581B5951E1A12169B1496CFFD8D862FE0126A0460 -7435B53E7E1453255BC1BF14B67D8275CE9DD068529E5314A28087EA792E841448B2720B -FCAC76DBA06A85D1FFA731D06757170CFA16D6758D5E371655C64747E1FBEFDA27115923 -C701004B5E38E32E4E9FFC294639B67A0A8BBB44D6050AD78A41747910AB112CC7D995CF -004B43B8C0AE28049672D0591392A2EF95A8021F2AB281DA86EC270D683060B8D9D6127A -CD4D5900209C117295822A9963D86D5B85D66E4502E5D2E03DF43DF5A162F502C454E971 -09A24B58B9BD864D5E11F8818811AAF0FE432527F897C7B9B1853DD7E73250BDC414A83A -85C6916FA701AB3B71AF0AA8429DB2A9F85BA74E49DDCAC5174C927F28C1970D0FCFF89B -ED30E83163D21EE4741659EBD12F2FDDC934E812ABF1A0A0CD1D2AF47DF045BF6C6CC15B -4E61D058650AAAB48CB9027757EBB21398C5899AB5876F13E23655A7AB3C19AB2D3BD7AE -55F808B6F4409012629F99A24FA15581F9EAB68177DD80DF8A78F0440E5FDDDE882A0976 -076F1B708C63FECE076193E53934681157F1EEAE0DB94A68289A3963775E0793C3FE3862 -9A6D3161E25A76A5CC1017884136E801A9EC1958AEAEEEB543BEE46B55FACAFC0A8B0814 -9121CFDAEDF975B4722D7EAC6768779DE79D4031D42622D3B2EC0A8DB5BB117DE455F37C -7E5A948088828127F042301446E89F67A6748440460844A5DACD816D728B00C725C771EA -647896AC27708EC7F9C858CD6E5264BA8DE4D1B2662CD161C0099FFA627070C7A228BE5B -F38052CFE6640BD91780ACB62158ED53E83CB21BB2DD3C2C40B70CAA21FCFF4BD6F07220 -67A644BE891798B0FCEB7FC5365ED584349903AE4BE36990F66113C3E3E2A12A2B822A5B -D334342AAA886A4C3460598A6D2C6C120369E27F5D8DC14D2C79C7B5215F0D6D0D7D7F69 -AD2A561C66C113DF9F60548A6725826E9C508BA07AAB59F3BFCC74D70D3D00546745392E -FDF15D348F0A5E36AD6C250CDD7D4AC53DD79991F36631371908BB9CDCF2089F4E37EF58 -E9A5AA78F3896AB9769C510A5965BFA79E40083388A56649126390F24312A4AC2D05C2B9 -A5CAA54F62628212354D6EFA8875F4B424732598FD8ADD1DA5459243D233D95F8840D51F -93847579566AE17644FCC7165E551BB9BFE7666E02F77CAE781D41D2EAD5388553E06363 -99653C07C45F603D6C017AC9DAAFA14339F25210A4A91DEC0DDED2501D38C15AD3371153 -CE2CB9E7A77DFA80BBAED85CD46D3495AF1D3BA9246885CCAB880908970E87B0BBAB6447 -A611956A2614BB89323FE3546868CD7C558C0BE2DF1F3649C0190BBDD38C8168DC698555 -2E913FA8BEC47F2ADA8211F4FC25EA75F5BF578FADF6707F051A0DDE5CC99C83DE55EAB3 -D81F40A05370B3609A9EE133982CAECB4108661833572E5360D31CB29916146F3D43C127 -E1DD71CA9413C462AEF379BAAC990E9C3BCF2C22E90F15AE7CF1DC3C52A44894E123881D -B6396ABA0C77AA2EA0BBD78C7312C9B9FC36271B058DAD3F57C44F57CB825908CB62B3A5 -CE1BA60AD20892AA2A559C53E8A883E9F9CBBA38D13E8E71A8C008861454A58087E729F1 -C50723854AE1F620D3E2D716697529BF345A269ADC240B8EB1593604E08A12E8C184EA2D -A26B206A5643EF0071D752A3D4982A507246F237880919ECE1538E34EFBB9D991129B948 -A0D37A10321F792A35C6602F5191D34100396E0E89C0CD41CF82D1A3E55FBF6575DC08EF -59485DDB2F33B1689738ECA78A59501F8A838D3BB960C025617D8C50855F31044D02F076 -8B5B1E6058737389AEC850E66C6F478F96C5C1D2F451841C30D6C1EFFC5B780D26A3BB24 -AA555A045DE634041EAE5F0572AB927AFA68877A77FF3AE277505B133BEF87C2899DD7CF -A9275F03B6B8461DD1791D0B0558E2E7A36295DAC3CAF878BC670E6B005FA34E78938F50 -DE3B75424769ADD07717737AB4E965A9565C1459C3197B545A64A5F22F7F3BC0A0641122 -85134DF7405EB961B367250242455D9896F92FD1B784AF5DF40C408B0F30A4689168029D -B522BFBE784FBCADE1D1301EACB5EB09DE63E20D5B313D2D04DE931862F08309633401FD -2117426434AB74A5A8480F6F9466E93FED5AF4DF1B3C81E5ED77DA855D1DCC9803DBFBEF -79994E045DCFA6FAF3BF1DEA57EB30FCFD0BE7A17855D82DEE77AD5F61C08DFF00958DFF -B5604F75DC8CC24623F582BCD220CDFE0D340A1C476D09289C5213DD812A0BAEAA492E8E -AF3436C2D490FB5104DF3139BA8D5DC7AF08BD1C9517206FCC738B626C3E29E590E2883C -30A4C745F59E54463086B20B76628FA4DD6E295144B43C87311DD11B559472034543C376 -65CD9B874ACEF7028F342E2B34CA04260ABF8C8E6193A64B94B6E1EA6DB6AC39FF3EC27D -A41A460DB7FB38555E272E1CDB792E682E887EB5C5AC5C0D4037C2BEE840A825AE864D34 -B205B65BA9E9B4D07A16FD1D285EB96E172E89A1024E5C0BEAAF1E37861ABE6767B98CDB -50C786E66AFC82AC474391C08F1FD549FAD7401F72E04B3A9A6C52C1B697E9D4E3E33122 -EEE5D0C72B03CCE96FC3D26966FC06C9BA4B7B838076796DC95CFA3FC222B3097C43BEE6 -251843EC7E8C81377481BA2C5F77C47C2BBC53FCBD8305C557C2FF07B9CEA70184E9DB31 -98CD10E6D6B9D3ECFF62AE429193DF88CF2A6548766C2DDAD04C3062D17BD5F4AE274043 -07735A6DD95F65E3CB850883474E57A0376F867507756D7FA74D0ABC7AC4ADD08E0AEF53 -39B613F64A33F92ED360B7C0A65F8F81290408D0B8752B7C03796629304BB83A455D51B7 -4C89ECDA38CBE83C5FFC54A7E5CAF3E2636865BEB3D6092CB7E4EFE6B13F710988F1B492 -9F4EA0676EA6B8495DF63F8BCFFCD47EE238221BA37F1C53B40A20D70347145DD5A04858 -4F1B55173B2808416CA7BDDA7775DC4F208742F7DE0382C97916342A192E47D3BE4454E6 -A2F80C8B72550D55E9B463299A2008334589CD4B5C19FD948BE6F9991EB7988F004E3BB4 -EDCFFD47BCF21276935650AACC3169B54109D8C02EE11D3B2670A7CD006DBC704EAD9F5D -3D1678C93199034AC92DD1959D25423A135441DAB773A78739663959C3AF3BE598102B4B -504DE19444E3BBACD584E15F6BB0D6AAC894FE5F86999096DF225232AA65B122511D3D0C -6AF2A7B25273CDCE5F4791416BD85DF4841C49ED8179DAA39FBE9E8A5D0A1BE58D67A0CD -CED550F9E02274A337EED7DFA9C3E23AB6AFF8F782AB4DBA173D8D0DF5A687070A4F8782 -DEFAC64D97487B10BB114338A16A081C64853076AB441E0598135A79028847D19229E650 -E96257DA27FA1C78F42302D996744BD5DDCAD26FD13F21B2D31ADD3878493ECDEDF6A257 -CA47BB5203286AD59910C8BE7604244C6E0041F3AC99029A5C61CF29A105FE4572BDBD01 -8B55B411B4CED2FB4F793F842CE40F2F8D07D8E10E79587970FD254F4106278DC7FC6E86 -6D7A1729C01D612A7FF65A63CF1C27CC79AA57699B0188285F474BA5BE90322DA6F653ED -3BD73542F9557352A042731F7448ECC6F931218E6B25ABC903E201F61BF1A7796135506A -DC2091CC49E8776202498C3C779C5A0DAA64C92D65FD3002E359062E1051FEC9DD47DDB2 -08AC3EC609544FC692BC2638E17AE95601E0153EEEAF7FF294CAB662116B455AEFA27744 -FA0AE2C7274442ED99491738BF4E832BD2991C59C2D94665FB6FE9EDD8BBD65EB2936F9F -8855722E84B50DD6EE83331138EF9779751C13E8757A54DDEE891507D2D00289B8667C6E -D9DF722391C9A4C7BBC146C735253EFC8E7B436134CEC60EE2ABC2F999EAF00352F141F6 -B3203DFD0FCEEF69B74CC180714A56B020B8832D291F17398E5B219300AB472699C5FFA8 -45878442020D780E1F2DD784AD116221769CB0C92A8B9864D646FC6DE853C19AFA0C9034 -6AAA5ECF81394BAB6F82035CF59E4CECA428E4D9513C5DE593D9B2A9EA127510CC68B5E8 -43A17803AC404DDDAC646E6E73C63C63001DA49CEDB5630B2E5A4231CD3F21DCABE8B3A0 -3ED509459FFFFB2457F1D5608E09448CA76E516407057805B82CAEE2B5FDF19BA480D93A -396EFE8199D04CF81E08E979C2C84EAEBC3CAD9DCF81189FF9A1ACF3FC19A88B30020EAD -5DE7A2EB7804FA0DA9BF71A339C3A304F51E47F11F9F0F754B04473A3ACADF6FFF079CD6 -C6F6B58A4BD5B340AADACEFDD5140B637EB3209BF8FB72B493643CFAF4900AAFC63A4EAF -D7B9A4A241ED10FC7CA1490304E2DDE4B22354B33253B41438CEDFA00E5146648B219E4C -E22D7BEA2EFA6A063DC8B1772371E3698C243C48CA4705352C3996DA94B1258B79C0B4D9 -63E69A95DD8318CBCB338354B91AF6852EE956A28F0DE835004D7F96C0E149DE50241951 -0621F7317209D1E1FD2172242E4B079FE328941BB0720194EFB48EAA04E59196EE8611D3 -325D1C12A3947C9E8453042F5F6F4B7B381BBDD7D927A8FABE70AE7282291265E7AEA516 -8E8D1BA24C71653323E26AA6344BC0D9F1717255E81D4C6A8B4AEE128C71F228D5775ED8 -257434AA754C770309C9FD1E8D1B69A12A78A726C80A9F74136FEE214D9EA87DD2E07F79 -53C78272BC75F22F54BA647413B5500051159EFC793BF1F44A6B8053414A331AE9AD43C2 -9AB2FDFA1107242078E6B581EA6DB98A73EDFB2AB8D733A91F8137C92E27ABB2ADBDF87D -E8B9086A12D3D9F7F5CD98D8393FD4D55F8FB26E849373C89C5FBE982C59A13FD4C655D0 -DD98A9056D4F4C36CF1611CE5B1931F38077D845F1D0CB9A32FA9E9560F3DE0D90B922E8 -EDCFF38CE0F00B53894EDE37276432C4786665233C4B72A2E770C1A6B137EBCD8275F64D -F1C19140C3A4186408993F112C44EAF2EB0D97FAD7503835AD56965D66B85B037984B561 -B125093AAECF14B8240026FD89389E6B1485C76EF24B838E1E67ACE175054E8EB18DAC7B -9FE59483EDB1EF741098E13D72AE7C263A8102336E6AA6492DF4C098FEF95D7B73F90CCD -3A77ECCD01816353DC819A90AEC7F58CB524B91D861D24DC8565ED19C3E44B91F6FB76C6 -E34B107A33EEA9BA30E8046DA880C4F6C7A5C3E58E45B4061E400F12F63219DB2DB438DE -57CB2ADEA50CE263FAAB683A5F993657C38A7301C8F0971A258465A2A03915341AF17D89 -B60A4A6E35153F4089E7394EBE36F3FA0E52D561C6954E60080A4CD4BC3DCB8C38E2F835 -A4F7EE9D8CC16A8FB6F205B4B9B9052517956A19D11038ABCBC28ADAED8AF15A274F634B -D4EE6FA279A872A087A53486CE9F0230F464B877E9CF8002765094E2E3B08F2F479F311A -A80699980FBD99914C09E6677161DACAE71884A21BB600BEB151D1698CBCB8F3C4CA9222 -8BEC63501DA8BD9819EB03006A427402FBC8C702E9F8CF2B0DCDC7BFCF0A5081A47BE7F6 -56366881FE8FB14E160E786A080B98A9CC17E0B52F93E31EAEAC7AF0FA0379C64F7EFC69 -5B80F3EBEB7745F3FABFCF0B4FA1AA56CFC3485B50C09783DE242F277D1054891CD9E78D -C67525BC2308F66F9CA11AA6AD31D48C3FE3FF0346ECD3648F803C50B86DAC19B0DD85DD -D09CA881CE34034530BBD51EB6075147CF0077AEC54690677B17334DE7DE56AFDFAA80A3 -D8F9700A9DB28A760C5DABFF102D5138EAD1E697D050D4BB9E6DDD28F0D2C669F0713049 -29534D421413BC278180F1172594DEE9DDBF4BACE639DBD04EA2497A4E72032C5C981038 -7749BA925E3E46CA02CCF1AC8C2931D1F538EED1B3B725C6C4AAC7D65DB7DFA4F86257D2 -69BA6B0CA4902214C3A37D0D2DD45E2427599F3C55FD813840A251F96DEF09C7E72D7007 -59A90A9F65B1DC63CB2020CEC0BCC6C54F428B8AEBC5FBA51EDEF53D88378F012C780D7F -A904DF1DA8B7148308BF2175B11B83281E132FB20AF80ACACB781EEB48894FE148F5FA96 -3AAECF094DB605BE46AE4EECDB1B8C1C64308F6F21239596B12DF0CFA846A09810F803BC -BA672B89004AD755D201D19CEBA6C99873EEDEC4929078513912D0815566BCBE3994F345 -68151B5B3375936A8825CA58392851D1A873DFC8BA308C58AC1F9EDBEAFAFDEE682C071A -BA64798C8486AF1510073C04773B4CDF2B77C3C4E3A3EC365FC4E08FC93B116F8F183947 -28029EE89EEC18724AC9D36A2BE1428D90F85557C4D2AD1442855DE6CF1D06C0BA192F79 -2D08D3AD3FB804AF6B68B3885556ADB4A4D11CC336B1B998344083129C66446868CB7657 -E8946E25AC33ADD0BD39D1D3396FA15B344B4BBA42C4F6265BA738A58FA31AFEA589A025 -428664B136A771A9B63606A6E63A29376255DDF52E89C2336454C3452110A4D0C73A27BD -D2A47D47744A3B9A4B84BC63349FF5C75A6CE2010E70B24A053C9BC8DB1089F4CB4047F0 -D102860A352BD4F0E9B2FE00C730CA3620434DBBB5180092CED4F7CBB8021E705F4C13BC -759B366A4D054B804EA3A8A9604674EC0DB26E93112CB244FEB1DA9CF920CB24DF6A0E7D -7F3B117B9E62ACAE126303EDFEACD893A8947CC822D84757FDD6460A0A344E31D1E8FE98 -FACAAFB39C49EEFDF56DD8014572563FBD5527097CC805E6B03066A81E6120337F83D1C7 -BAE66253655316248F0CE35FBD61A2372D7B8A1573D34211AD49C592716566EAFA3FFB23 -50B54A4FD1521FFB1DE011FCD82792B93D87788F8409AFD40C7448DF74CAB5343D62C534 -26F0120A12C601E35C4A17788FA6086B3B4C7C70F1043198C61E3EA717533971E8F78E56 -17C84A3B5EE522B4C7C33FB5F1B93089EE7EC6D3FA90EB7C886D04116C3C0947FC5F3B85 -45636538CBCAA1DDBA880A0D5A30FFFB07401B25CA5572D41426D4A6D98F3EE01AC1BFE6 -D40C58F4A2413631E59140F65AEBC0990A76BE20C2996D00053F353945CEC87AB8970B88 -20DF8527A018548EEBC55906E04B0A3A498877B2D1ABAEC069260F05541301AAFB158200 -DCD67355FC73930DD4B47DE9ED0501CE7E38823203CE6D714E5501DE6C9922187592236C -E424564D6FA776E1EABC1000B2A854D06860F6ED7668C4D5DB5CABF4E89D9E05166CDCBE -D679B2E1645790F968D0F12843561B95FC90B8CD75EE2D053CBAE61E215082E5609C1146 -32C8B81CF298E477C0427D4CC68E6FCDB88393BE8520CA93DF1E3B519980FB3523BB18B1 -99F1626457857CF7641AC66E257634B349B2D5A8728DD02A890391BF2EF8C6358E4BEFE1 -6A214068AA175A1E7FF734960FDDC28989AED8261D18B4D996372FDF4788AED732041886 -24521DBEB9985BECDA0A6CE64DEC42A2539CCD4F55323057B8AD70BBD5B05872B864FFFF -2D627668ACC1D8D1908C1E3E2C76D45DD2058C717C02D279B0AC4B2E526C657FF7C5DEB5 -3538D1B2116AAA957A6B16F0CF83430395996462F8183F71041D543C330183A941CC5E37 -8C348ADA81F946090676425EDD0EAD6EA996CBBDBF83B606D78B08684BBEBCFFED1D0875 -6CF352F872A71DFEB693608F24E3F4D663E53661B35A0BBEB3B630489FBEA39BCD26BB90 -0923FC711CDA89442435FE3A491FA23170B6223A577282C24FB7E895E2A0715D2B78F20F -F1F9B06AA9D754FBB32CBBBA06663C59B7A8B22E666B26F2B9D8C55179953581E756BEBB -82CB10E21A7F590C6569324ECC4C34DB4BFD9EFA84897068199ED8344A438A1FFA475534 -0EEB53B8E087515ABA25BA2B1414EE4F86E257387D4C0C7D010888AEF962069C57450925 -6C3F0625BFD6909356DD62C01875C69204C843E6BA873049D72ACEFBCD9106FD45B8E9B9 -8CED3AE42ADAE6A7BEFE925BF6421E88540D9E599CCBFB9E8DED2C5DE0B7AC4B331EAD42 -DEE8EDC35312B1062CAECCBC903CEB8F67897BEC2305B6C333FB766D92C6CDBD77CB4F31 -F63AE1C04A249361D2EF6E0BAAEB7FA3B87E0BE0E1E50C1F480AEE2DD2B6B4D7DD89A020 -8C9B43ED6F46F3883AB7E53869E3C2ED3DB0DBB1A05B1629E48B3D7F420F02FDA6B1CBB9 -3DEF237CDE1F7BD8C80AC7AE5388C30335378E0E374D0C41EB824BAF001A4C47C399F301 -13B442A2C1B27EC161CF528FC2B256579E3C96AD5F4575454449B3B5E1CBDB300A364C7E -6675B6B924B48E58A0629E729941C3830D23968002C56F84F53CF124E771FC83CCAA3363 -5A130FD70D9422B524BEBC6FFF2369A71DAABD932B9D4ABEE240F07A4DE04C280D9CDC39 -A52D9B09799279368965C40C32771BCBA0EA9BFD488BFC3D154B8E421391BC7081D27262 -B40B8B953C02432B8074CE466299EE8BA9A0BF0D47F797EB5A8300B1E80EB44EA0C0D51F -8577BBEFE06C2C31199B4B4483BDBC10B9821B7CBCCA73E4A96932ACB5DFA52B2F3F346A -444EED0B3B0E81E8B65867CAEC517B99B84F574AB31FFABC2E0DA312F12E549436538E9C -82417153110E8060C80101B8AB8955FBC6FCB64499BC6AA18EB6DFB9406304B2FA5A003A -650C15B78EF641381F9A474623E69167793F9896DC82AC4A01FE4E267E9713507AB69A60 -DA690E3F3031CB836256B21FC26BE0B340FBB84AFA550F7ED8C3D0DAB80AA2FEC258477D -6576F86E6D8FFB91F99917A1EFD4902BC12AECE66A5EBCC6585ADE4D96CDF5A78D10EED9 -4D543079A9F60B3650D17C81748189C5A1859982574E1E821E943AD2C59000D8CE586E64 -178DECF669143E9D12131FA2AB2516A3472C7B41DBE5E8D2812FC7DBBC2415055EC1EE77 -A1BC7FAEC22051FDFA79F47C5D511C3F55DEC0369CE994D574299A9E3AB915935C654D71 -F3FD4988F5265EB95349304260ACFB633722F5AE8F43D3EF4ED5A0D333AB72ED10C1BCDF -30A2C85CA9A4B10DF95613BB465C2757CD153E81A1CB4B6D6B7A723BF5FBDB791B38E900 -EE8CA0F36399A767FEEB1C239880F13643BFF60481776C3856A033436C14768B09134DD7 -2C79C88DB4A5E7AF3F76B4806DFA232841268CE4D3D6D8FCF5820EC52B713C9ECAF0320A -5E94C45E93A785D5F4DB8E5A1F43BB8AF4218EBC91BF88D10311EC6812F42BDAB8BA486E -77AB14763C2E489EED940D934AEB3840BDEDCB9307830202AD02B3E7E27E0358F8502DD0 -F01935DFA95F69B68F5CD4F90ED84AD59DEF5E62508CE3A5AF67B2FFE39D37C59E5251AB -5E26C96C0B08D593BDB3F7ED93F9BFAA609723BF87BA135847B8535611C5E4EA0BD324F8 -3B38289C3C5D54713A58DE72FADFB4B89E7F4C40261C1779B97CB9F9570530D5943A00EF -FE435F5541AA079CC0E8452EF366D9DC18B0A6A0454FF9AFF47957973F77B9806373C9A3 -D048558F532788AECECD659B8B2751958B3F454011DB88F3BEB0D50053DC70B0244AC1FD -20D70C444E1CB00399EC559D6A2513DBFC001689156FB89CCEDC3EA3C9B70BF2FDB3A1C0 -9CF814E7F1332B7C752DA6B2910663D3E0AB53E89A236ED66418A280FB4A561DF005B08F -885D58BEF1429418D81F67A00403D87E16519FACA45298D16ECD5CE1839D3BDBCD784710 -8622BCFBCE4C100602211E6762998BE4F6F211EB916468F587A4DCFCC2030FA5FCFE8018 -1299E339E35ECDC494D4314368270D837927C46EDC1299FA541480A07F085D583F2B9390 -EF3B4A2A8ECA8B28648D8132A0D5B37E353731056BAC85AE7491369809C4A06ED7B0CB7D -BB71404D67DCEADEF47603F7C1A3337AC93CA5510F022893466AF4C74C24428275C44E23 -0FFA5972C9D36359FCE3899A3D60EF63920F154DD39CCE56BA57E540C1A3497B3EFE96A5 -EEAEE028AC28D81A541F833A62C8F7AC492BF304C632A023C7A170F8B3ECAA4284CD01A5 -6F74B4A41F1FD464BF46C890325D17CF9C8ADB8AACDD9CCA20015374111DACDA8744BE20 -DD6C99E09B51AB2287016DD65383E8918B5557B78578CECCA7EAEFF8E9BE9E1B13A24613 -C953C5BB45BB74A5A935F32E708927D5FDC1805B5EB9745D35654E25BA50FBBD7DB58D7D -6F70E102C640B771CAF3C1C138AA9A828E79F377A1FC8913012E5547D3602B22B4C365DF -269CBE55BC4AA79FABC53F01EE7D809481DDD3EE602A7266B7280DAFDC68259CBA490414 -84E4EADF0F8E4CEA8A8CFF260B8F4C9C5A3F2ED699B4CC72DADF932F844E65C1BD385CC0 -F2EF81820D16CBD8CE2B27ACEC225FD1DB77723EA0F03B1CF07630B907C7494EB4CAA725 -18144B1E15B0B34E8F3890269BAFCAF6DF4EDF3861ECB5266C285085BF4E1C6FC0FBA7A2 -6504467B734692FC2C9797D1B6536FD42314CB0FBDC0B104EBCA6539F47A97E1C8974876 -9BF5EC71AF381DBAF9016B5A794EF38776FD9F811F31EB98010FB1FCBBF23A00794E2FC5 -9637254DF49FB9C0F459FDFA0AB0C8C040AD780D6CF3C9173472B8A6F041D3B30720C1C0 -324B977866A3F892FE9A12DE84A6F0D723ADC584A17C055F07F4BEC7486D6B064885E410 -B48509BBD815C3BC2D57F23515AC82551CE3D334424F3456944460013BC5B7B43AB19D7A -62C9C2431CAB250705DDA8CD0395FC754AF7E0B10BEC12EF69100A831CEB62F5C016142C -32B8A41F852F57BA1DF144C2A534C06559BA009A92E345305589796697EF28E097DC06FB -8465A9DBDE8F5C38BD9D0EFFC3712F9F070F1FD50BF691811F94E12F26D47AC350C01C96 -BDC13416E1272D457AD210AFD2822408337E8BA7E63FF468AE68983966BDE984F4894F2A -47E982E29C6855351180079ED4E9D53912764533F5EE35A93B31A4885855A31DCC719522 -8D266F9C539DF45036A97F920B717D08ECF274B66EBA30E223A49D67975E8962F617C107 -23261A6FA71061BF91EDC235B9288E4D856FF764A5E65AAA044865D0666523B24CA1AA3F -87A58577ADE42B6DD75960840BBE46C584818A5C7E4E0FC13D41E9E1062BF50260E86A39 -09C5C59BE2E8301ED90C22A42CD5DCC436AF0A0E8987853B1FBF316986DCF54BCE866D05 -1992116762A7E54B08DB4E6126604B30F6D304E3D1B8FC6E602E11D791648C024661CE90 -7A6808EEBC6E3E2C0CFF9A9C6DE679F7E0246CFAB927F1D1A642958267645432FD9861D4 -92DE7CD99824C0A7D93A27F279C0D9919E4D14BC0855F4B562447974B2ECD1171B848D17 -8216047A6834390D7704EB2D6B16EC16A478C69AAD1A4F766FDB6D609628AFFA7F34796D -0667AE68EAF4D3BF8C7316A99E5CAC797F0220A930B7F3005EC0C72A2A925DEFD27F2DE0 -8120030CD29A9F5553E5609363E34A9526327EB61AC707C48F -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -{restore}if diff --git a/fonts/Monospace-Oblique b/fonts/Monospace-Oblique deleted file mode 100644 index 932292770..000000000 --- a/fonts/Monospace-Oblique +++ /dev/null @@ -1,2706 +0,0 @@ -%!PS-AdobeFont-1.0: Monospace-Oblique 1.15 -%%DocumentSuppliedResources: font Monospace-Oblique -%%Title: Monospace-Oblique -%Version: 1.15 -%%CreationDate: Thu Oct 27 10:50:21 2005 -%%Creator: mike -%Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. -%Copyright: DejaVu changes are in public domain - -% Generated by FontForge 20051018 (http://fontforge.sf.net/) -%%EndComments - -FontDirectory/Monospace-Oblique known{/Monospace-Oblique findfont dup/UniqueID known{dup -/UniqueID get 4136343 eq exch/FontType get 1 eq and}{pop false}ifelse -{save true}{false}ifelse}{false}ifelse -11 dict begin -/FontType 1 def -/FontMatrix [0.000488281 0 0 0.000488281 0 0 ]readonly def -/FontName /Monospace-Oblique def -/FontBBox {-239 -1034 1512 2105 }readonly def -/UniqueID 4136343 def -/PaintType 0 def -/FontInfo 11 dict dup begin - /version (1.15) readonly def - /Notice (Copyright \050c\051 2003 by Bitstream, Inc. All Rights Reserved.\012DejaVu changes are in public domain\012) readonly def -% Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. -% DejaVu changes are in public domain - /FullName (Monospace Oblique) readonly def - /FamilyName (Monospace) readonly def - /Weight (Book) readonly def - /FSType 0 def - /ItalicAngle -11 def - /isFixedPitch true def - /UnderlinePosition -213 def - /UnderlineThickness 141 def - /ascent 1556 def -end readonly def -/Encoding 256 array - 0 1 255 { 1 index exch /.notdef put} for -dup 32/space put -dup 33/exclam put -dup 34/quotedbl put -dup 35/numbersign put -dup 36/dollar put -dup 37/percent put -dup 38/ampersand put -dup 39/quotesingle put -dup 40/parenleft put -dup 41/parenright put -dup 42/asterisk put -dup 43/plus put -dup 44/comma put -dup 45/hyphen put -dup 46/period put -dup 47/slash put -dup 48/zero put -dup 49/one put -dup 50/two put -dup 51/three put -dup 52/four put -dup 53/five put -dup 54/six put -dup 55/seven put -dup 56/eight put -dup 57/nine put -dup 58/colon put -dup 59/semicolon put -dup 60/less put -dup 61/equal put -dup 62/greater put -dup 63/question put -dup 64/at put -dup 65/A put -dup 66/B put -dup 67/C put -dup 68/D put -dup 69/E put -dup 70/F put -dup 71/G put -dup 72/H put -dup 73/I put -dup 74/J put -dup 75/K put -dup 76/L put -dup 77/M put -dup 78/N put -dup 79/O put -dup 80/P put -dup 81/Q put -dup 82/R put -dup 83/S put -dup 84/T put -dup 85/U put -dup 86/V put -dup 87/W put -dup 88/X put -dup 89/Y put -dup 90/Z put -dup 91/bracketleft put -dup 92/backslash put -dup 93/bracketright put -dup 94/asciicircum put -dup 95/underscore put -dup 96/grave put -dup 97/a put -dup 98/b put -dup 99/c put -dup 100/d put -dup 101/e put -dup 102/f put -dup 103/g put -dup 104/h put -dup 105/i put -dup 106/j put -dup 107/k put -dup 108/l put -dup 109/m put -dup 110/n put -dup 111/o put -dup 112/p put -dup 113/q put -dup 114/r put -dup 115/s put -dup 116/t put -dup 117/u put -dup 118/v put -dup 119/w put -dup 120/x put -dup 121/y put -dup 122/z put -dup 123/braceleft put -dup 124/bar put -dup 125/braceright put -dup 126/asciitilde put -dup 160/nonbreakingspace put -dup 161/exclamdown put -dup 162/cent put -dup 163/sterling put -dup 164/currency put -dup 165/yen put -dup 166/brokenbar put -dup 167/section put -dup 168/dieresis put -dup 169/copyright put -dup 170/ordfeminine put -dup 171/guillemotleft put -dup 172/logicalnot put -dup 173/sfthyphen put -dup 174/registered put -dup 175/macron put -dup 176/degree put -dup 177/plusminus put -dup 178/twosuperior put -dup 179/threesuperior put -dup 180/acute put -dup 181/mu put -dup 182/paragraph put -dup 183/periodcentered put -dup 184/cedilla put -dup 185/onesuperior put -dup 186/ordmasculine put -dup 187/guillemotright put -dup 188/onequarter put -dup 189/onehalf put -dup 190/threequarters put -dup 191/questiondown put -dup 192/Agrave put -dup 193/Aacute put -dup 194/Acircumflex put -dup 195/Atilde put -dup 196/Adieresis put -dup 197/Aring put -dup 198/AE put -dup 199/Ccedilla put -dup 200/Egrave put -dup 201/Eacute put -dup 202/Ecircumflex put -dup 203/Edieresis put -dup 204/Igrave put -dup 205/Iacute put -dup 206/Icircumflex put -dup 207/Idieresis put -dup 208/Eth put -dup 209/Ntilde put -dup 210/Ograve put -dup 211/Oacute put -dup 212/Ocircumflex put -dup 213/Otilde put -dup 214/Odieresis put -dup 215/multiply put -dup 216/Oslash put -dup 217/Ugrave put -dup 218/Uacute put -dup 219/Ucircumflex put -dup 220/Udieresis put -dup 221/Yacute put -dup 222/Thorn put -dup 223/germandbls put -dup 224/agrave put -dup 225/aacute put -dup 226/acircumflex put -dup 227/atilde put -dup 228/adieresis put -dup 229/aring put -dup 230/ae put -dup 231/ccedilla put -dup 232/egrave put -dup 233/eacute put -dup 234/ecircumflex put -dup 235/edieresis put -dup 236/igrave put -dup 237/iacute put -dup 238/icircumflex put -dup 239/idieresis put -dup 240/eth put -dup 241/ntilde put -dup 242/ograve put -dup 243/oacute put -dup 244/ocircumflex put -dup 245/otilde put -dup 246/odieresis put -dup 247/divide put -dup 248/oslash put -dup 249/ugrave put -dup 250/uacute put -dup 251/ucircumflex put -dup 252/udieresis put -dup 253/yacute put -dup 254/thorn put -dup 255/ydieresis put -readonly def -currentdict end -currentfile eexec -12D37711F3EF58D4B0160CA0E8A8B30BEAB80C582DE4028394F513096550F71FA11E0919 -505AD6B7CD35BB9BC351DECCB83DC12688E510CD157D892C101B29A3F7371CD20D496932 -3EB249027679D3DB7582D953F033C85D9B05B2E5B9E3F8CC14BCEA62C23DCEDB24A737CE -0B749199BDC0ED14B3F80C24B773C7D94E0C32CB6CABC70B74F04C589AE25F78DAF2C485 -03C9800E9816B03D596C6E3855892618845E5102FF46233B460979463BD7A820DDD6835A -95C220225DFE27AA6BB31E99C60F679AC7C5A3363C40EF4C555EB47B0B8DB21ABCDD571D -28DE4719336D102E1E7D1EDCC5B3B0E60354D35EB856F234AB60D3C84342CB01D8747F93 -73140C128A546250AD327045F7903E144A248D16DBC150EBAAE66ED529E3E69214BF4A15 -12C2CA07FCF9A1CA5DD6D5A3577FF552FCE29E2CE9236A470FD258273428609693228B91 -5420FBA3ECF0A2406B4484196374D33A6C4ECFB322185AB88BAE99CB4FF8147A0C4D3274 -29B1B69D3985E21294AC5BF3777F72FD8986BCFF6374642612A36E01B5F19A4C313C684F -B4A10E6D366CE685E4D566655263E514862031506A3B886388753592B0F9A5D61EE9C644 -3E5E6BCD8E4FB03ECBF8955C142520D0F71F7E4DC8C45E335345B990BE35EEF99170556D -05A25CFF99E21151C7C1407675D515921EDD3FA3B98A58FBD14CDF1AB6AEFF424587D2F3 -CCBAA445F12ACC21F1AFB0EBA2D9D9EFED2C77A01C7B4FF0042E9BF457442297D0989DE2 -DC27042B646D45A9BCB9D9B80AAD373DC283EF83A52BBC4FF0B2E17194CF18618BEB8CCB -BA24F7B836924BAF4DA12D018EB41F3307ED0F6B29C51B20D92FE58C27CF5E7D8A3386EB -04685234F0D2D1704EFDE3C72CAEE80A17BFC25C4ECE7DA8A4F9044856A19794E13B9199 -279CDE03A30495084E75DB7C213CEA250A5DE3A17D168335FEF9BE57291A770F53502F9F -78ADC6BAA3223B013B120789D9672B286D7713F8AE9802A4424B889344D6D06B280F60AC -A1A81A0D8ED436C84543D86A866C981A4A8ABD3488FE907F39B32311E4C2EE313AE91061 -A1FE81235477F816259BA0D0151DCB3F28B2F59518B09E249369379B19E5DFC19EE63BEA -CBB0636880CB367BB50ACF4767E2A9E9BD7F0339D4128C54E622D4C39C5FB383438B4A73 -9BC3A717D1E3F8A8CE7AC4FB789C7531FCDF82C32E4C8591C3D707E6CEB702C2D210627C -558FB139108437B8E9D99B2F8532F76709E821391A07BB1A9305F62EE8F9E1EA1844FFAC -C5205E5428D155457F451A8177E75D61195BC5A9F564297E4C36C9D3F730D1ECDF921096 -C42A26E66BFDB9AE5682CE255B0DF1265A763798CAEA7A3138CAE6A7F6711899EE2FE701 -D825DF705F2BA8D8C6A6FC077C7F63C35D0CC5A183A03EEDB7A81D71092717E60CCD03D9 -D7EA295AE3407BFA22C26CF4D7689B46CB49FFCDC43F3BF5B3A49E53387FF86B4267B880 -361199FE0B20B7955DE33F541FFFA0DAD7917CD64ABBABF977ED46127DBCFCB179757EB8 -BC08D07CA46AAF440882C7ACC9B93C575C363FA81F381CCBA6B3ED329D349D8D7E3E1884 -8327A19CA6C83DDC89005AB7D6725D11AC8BD6F2C7CE8B10131F7A82484D03A3C6D854AD -4E173EC6852F0E46D46F6B85B2641AE69CA53069AE2B330F57223C297E09358F7DE81F08 -CAE980A507F685FB2156714E7E9E88D88FBCAACF86ED25335647B1238F31BDD5D820EE43 -821F5CF2F7D9A67586D99E9D4931AAA7C2D32FAEE392CD9FA4DB8F69D76C3BBB48A10CAF -BA3E78F64701913B414845FE6A5F78A24CF5CD29097FE21032C5FFB34F107F51B3D8C848 -2100FE54272E0E17B79419FC0AC8966CCB7AFCF723A8F721B06CC80CE0B07B92DFD20E93 -BF01ED0C72F6385A49524A7AF5EDF658FCEA7475FC6CA315926826FAD3A90FEB182B6651 -B1966E20F7300D288DB7A53402D5D8D0A748E3C0D21B9DD078FE8560B40C06B2A7037659 -A8603518F2A67C62BBD9A29F452723A8EFE6CFA2C356EDFACDC8AE936533498DB168588B -6B96C1FA3A2740E3BAF4470783C49202FB9D1A9A9DC3B375F1187CC1DFECBC616584EE00 -BD76FE39C6EF0B7A7ED422042C1EBD392A51BB458F920DC197915A74CE8E6635EAA0A772 -426427212311ADCEFEE54E075B8E03ABF3D4F7939D35809F0B6AAFFD9C08562B9E6BF8CB -B6E3303A1B3851920EEA8EA61B081D22A585403C8D25E645987434DA4A16E57A585B4097 -3FE63FF99E2BB9B860DEC906F8FC183A6C57570859D7E381A6CEDCECFD566DD50CA67801 -ACC6151D9C6D7D5A3A19C5A283EF37F1F418A469BA10E45EBAB0432A366C1549CB402F12 -DD99AC7F802EB9D2B56899BEEB60C65C6B22EEB9A00C680E94E8B190B1C3A395B6535C3A -3831D857819FC23F840B273D3133F1BF243EDCF846D8E308E04F6A38B5C73502F34C6680 -0AF88F2E920E39CE4C31DB700CE6A2777048E4B2509EDD822FB0036D888B86ADD2A01C8C -AD1EDAF950AA9EE999B4EECA0DBF02064602085C18FFF27707F09511AF5611DC76220CF9 -FA55BB850E7F4359A9B597ED3E3298B765D9AEA76484DCC7338551FAA0F1BB8CA3D0A628 -5BA8BD8E8342155B682CD6C8FBE6631D627C4616E80114385D6B52E2C827D5E7A2C1CDE2 -B32BF8686B1E6A3E8689D1C2191C6C3E9697633E65521500EC357746647364248682F2CC -37AE635B876025B85622049F99B824C32D060CC599FD4CDD9BB51530FAE7EA750DFB07AC -A3226EA764D547F7158AD27B0187FB701626E7364C72377402A88754F1D3B5842031E319 -9DC3FAB04D7A3C1FF486AC03EDE9CB78A5E911F56B06635ADF5867E64C2871317AA8B298 -3F0FEB5251C244D589A8C9BE5A9C6382F9B409CE2D4F19AF79FDD4157C326A43EC78BC27 -FA5384398C5F927955B2B67EE653CC6EFDCAF7C23C0D08B8C3DC41CB5844E057EE1A277F -8DC7FA99594391BA6DFF30FC9FEA550E58F39934675E587698AF82F00F428AC930567362 -B401C42AA7B9B4FEC9443E9AF5FB3E999A94ED088D97CB11E6955BC9E561D59EE34BA1ED -A6C9217EF560D154BA8F19865CB8C913F12986A48DE78E9D284C0885C8B69DB0CB47560F -D88FC212B29C91E004D18376A09A184ED29866DC4A179293A52A1BA548E6F8439B326A16 -2FA0CE6AED75A05FA30EF09A72CFE06124BDF8016C638725770D529A0163954177D45382 -3A74FD8E44B3773EA1280431E880CD2398A944C4D045AE91138244E0BC15343D6AD7225C -20406C0AA1A4257FB281C2FC949CC3D215F827F782F9F4BD121F67794A8F13F19FEA800B -6C7240E804D6FBACC9A2CDB6E7D24F6C61E89CB47C94D8E961ACB9355A12B42486447C02 -7AF9D7B1C4F0E4CAA8E28BE31684D721083208D76482B9BE451A4F0426F5DA9A2413D98F -CA9BFC29E1A8680172ECF33C7218D796D6447FB643974250FE831F4D5F0ED8ACD2B0E9E8 -DC6479E203625F2C5D62F96244773D954ED8F9B4D74A0D8426A9A61176EE6AA0DB4BB3FD -8E0F9F49119F2F2F1EDFAF9FCE35316F718A3DBCD0DA416574C87366E3321DAE1798F437 -7FF418523E807C3D80C80A5057F16781ED3CDE4EA1AF173093712B3F76DA73D0FE64E273 -C4309D9BF5CB0308A3BFCDC1D7BF1830D22C77414BEAF5868006615536737E20C438265E -74B43F267E748B834FB03691FE68D944561F1DEB1CA295E442C6EBC274B6D9A0D4C2BCC6 -5D6401049EBC97F0F7A5678389267B0D6C10757954FAD66FEB12875BF4349BBC775A0804 -00E25D70A165C7ABE5F5F4427DBE548C9701E20CE28356478DFFA5F08C30FC08228CD6F3 -C6B030734A683BC5196F3D29C43E80F96D4EE3DD54785633987F385340098B5498A7DC1E -07D42614FE6F1BA7068B0677345C695A494BBF150C8E4F91EAD66E387856CB09986439A4 -03A2EA248EDD1D00A4D490B9DC4BD11E36E155EBCA715B513D991A19548B417539B36308 -0D7E8E3ADECC1073EAF675C90D5897E13CA0AAAB196E8A48F867F0F71E5E5E24C36D5492 -E476ED92090842D327E4682E483F082FF71BD290542C19242F596801E9B67386498D3855 -BD5AFDF1A0A6AC211B38278F7ABDEB586EE5FD5ED91382EED8677D8A1792B270A46812DC -BA8A1379D5E5B7413CD43C6CB3E447E49F35CF2E7BC2E99229286B2A636F83C16BECF6E8 -63E23449DB08CD8FDF0F5F8EDE5A410131B866B55C6BBA8528C17072EAA042662D855A3E -5D164BA81ECD230EEFBD2A37F823D410469B05F3198B56400B89B6637BEDE2A19465F240 -338ABE767699529CECBBAEF4879AC00A6639589927A1CA91298FD051FF15223EC94FBB3C -1C61D1611D05E59ED9BE06C0C9DB3C311CDA93CFD321508D1187007207A02EE50F422383 -DCE98954FF609844A8AE9C29B56C1AAC1238D45FA35A3DA527E3FB618CAEC32EE156BFB6 -2E8F66F6FCA7EA0B9BCF0A144A05FD8FE25BFF681E3AE6784D6A670FA08776299E0ADA1B -A972D1E35CE0BDA9F06F8A8B96C8750CF25E24F69A0A49C65F7A9716FA4C5F3CEF3512F7 -AC82BE0C5F21A6876F73880FC7CEA205B4286929ED2513D38A5695208A5CD4DE401B214A -BE67DA7B8B2C63F5B06BB039D7294DC883723FB83F736A5EE8A02C9F968FCFE5556E52D7 -9E070ED53CF85FE574F52C9446E61BC83DDE8C5AB547B08E19561E6F4B84D422DE6DF197 -3B2572006AAE0CC1F19E342389DF278FF04BDC5CBE51E27FA51D696B123DA5B342648532 -FAD98EBE03894533AFE4BECE638CA5785DDC9D7ECEB71E59B01285978563920DBF542794 -6B13DF1BD0C0D349B77290CE840C17E9F71A7E34F3EF3472AB04E9DEC00BC4C258F522AB -15C73CF78CCB3A83D7A2047FA52A4C7196C4E750C14D77EBF5C799702BB84B646BF7F9A1 -2A6D27166F7AC9B7A2D6B6062627331C8435A64C04096FEEF7867334828680E41990E319 -334217DE53F32DD9FE73537D000A5493EBC0B5282FC1D72E0DFEEB51694F6B2DF87F3E80 -858DADF97EA3E4A864AC9AF980B1BA0159E7E046EF395143D2C2AAC26A0FC3A8F1ADB37B -6E3AF132D51D9ACBABDB4244AD14C837A30C3B9CA47CEA267845DFD9FD5A0522BB50BC0B -CADD7730E893A06E8F175DF29B4092EDAE7CB28F8FD389C14EACC8FFDC815355B9FB564A -F8C33D5871ECFC0CD0E33A0AAFD6F7323A3FD696B4EE641249BFDF82EAC73D0D823A5BC0 -EC34C42269F5699F129273CC384C8A17BEDC4BA4E384BE7D6213EB49FFFC5C98FBE27877 -85F64405CA64B5F2C10470B82BC1471F59C8EEEC668D88CF0441451E275328E3903A54D9 -216F0F70F63DCE071BA66B31E59EF5731CC778455222D441C0809C690AA9E70AEB6546AB -6B6D27A66004E67813F7509A3F2B2FFD717A77FBE48A7480FE4F2E0E9DF61D378D817928 -926F8F202341E945DDD9F747F6AA931A9369326C3AEECFAE75D289691683E6635E215E10 -9C76807AA3B71450BDEAC4AC8A55F7B6B7933745E2F3F2F3049CE858B10E17F8C236B247 -FAC04A7C3E6298C1A2036E14EE164AE8478FA4AE6F24A9E542D3D2B450E4EDEE099AA693 -16E89A308123CC5DF3E4822A5B57C7FEC21271BFA0168C3309ADF2DABEA0610FB18ABF69 -5622E7A1C371B3EC501D52A1DFB94AC84E30A500449867BEFCB5A07DC54A2F961F296DF4 -9829E92B8E0928315D60103EAF984847A6FF6185F8C1EEAC3A114F7588AD864F3A16B94E -3AE4E0738E13B6190AF3A27427DEA99F8A6491CF60C2F8F5C8A524CDDFC5AF2F7304DF82 -DD8E2F273DC82A9F0F7812297C485AE2B330DBE5B0C2E91922484FAC56649226FE104F57 -E88622612FD6CC084725C3C717D6B04432D13EC9DD5BDE98FA56EBFD2C7FC973AB611168 -C43379538659B695DEC62E8D58BEFCF44F9F0F52273D998C6BD8766BF4B26E479DA21563 -04B1248C80C58E7A9609B64934AD07C1945F03AD258D32D4D47B6C1A95D44B135F380A64 -C7ACDDD22D510DCD056A38C8400F21900F1692BF2210F6B161EB8C6E7702291C0CD2123F -6EDA46B95BAB323A99784F32A3FAADE6599CAF43F3CF39D43776A205B6024F6DCB27349E -C394FD27D389C1CED32138732AF2EDD4215A8E81A058BDF9797E0EE81D13B7773897EEAA -B71BF9D0D6D913DC0887442A470D5878766BC30C065E64456A88F88F754C3B6CC402BD8F -BE60B69F6CF942EC531A6768887DC1D6C08A690109E86D08D9470B9A684D751101A2821E -48805AD36D0E6D3BFF33FFC4994645AD2B599188B30649ADF04EF349B934E99E3D767C6F -95DB404233259FFA5BF4CD809B4E08F51653D72C2C24B7419B49585672244128A45AF33A -82BF11CF4B402B322D7DD20410A85B28CD32DBBCBAD192079514ED52996086747DEDB275 -8C8CD1F05B82B0BB80F5A0BD1C7A2F726B29F6D8DBDC9E199C494A8682D3A12F3430388E -845B4878CF87871AC6914DCE0E7AC20407F04B3A41EA5EE88C23AB19D61E5446ECA0CD77 -0D6992CA5DFEE0265BF81AD4EAF93BD5C068D1A0FB1704499AC8F16E26754ABBF318E528 -D7B12C0CE352E4FB67A1F6DBAF06C9EE5C0A04A926EB75A2E76E1050CF4300721B0F130C -E912C53166696D93B131CE8D487FE3B5A8450EC7A8961479FBF29E63DA9B03E79F2FE5C7 -14B57DAAB035A0D2A6A9BB5FED68F49C58360E5E974709D12AAD0680E1C0145526CE2C88 -36FC489C50D8D3FC5C0AE2C517030391268B306D231A9BB1E881928727235C693FC86B6F -A9A62D337FCD128CFE1BCACDABE9F384B90C10DF4967A447D53828F62E753D639E4432AF -361F680C212BFB50065241FD8403C80D5FD3F57A60643D586449C76238BAD444D1282943 -FBF39869CCADCDCD0815A484C494FA16930F3636FE854A1530277D1232303C0A86365066 -89FFD5E3C5AC028CDD18A3FB360C8973AEE50FA93127D6C7B3F323689F3075CEB2017BF8 -BF827381B96044E245DA2A845A536E053A1D5B540A8A27745547FF27CC9368EEACA827C7 -A47E56107A68B58A4ADC9B4A56C69C16A061F50C79A7034D317FA0F61A123D749AE3A140 -4D8A29EF631D5F925C8116256B40B81EAA31C326F4902BF46D68C5D6930EC624F3F50587 -9CB9DE9740CA93D36B8C84FF21E7E2AE48FAB457A8973106BA5A4A9D35D19AEAB1AE1E2E -8794C96BEA993A03C1CAC00697D95BF3287D7B14701DF8EF79683F2771A444D334E7074E -0B1602CC3D08293FCC6815946798BA56470783A0BCEEF3BBAE34D9ADDD47EC0E23E63505 -67965078615B540448EFE238DF5F70F1439123534B37B01D7189DFB6B21E783474B476F1 -9857F50753D49ACB4EA73BAFD9727E3EDB0ABD056CA73046DD3743451C0C2E54AC8646A9 -C1E269B570605A92E28FF146F6C9E49FEBC2B0D1946D673064640F610FC762ECBF415845 -E80463295D0EC0F6CDD35852CC9126E08DA99B91A75CF7EBD86466AE0C381E87E9D99BEA -1F6D35F3603AF79212C5146712B20727A4CA38A6CD684B5503BA1C18590EDF890902448D -ED527E7EB9A15623500BDA827261BEC6E0AFC5D644DD384BA6B3BBA29EF93FEAC2BA6C56 -82AAD04CA8FEC95DC915B8566A268801A7242DACB08C0A47122DFE37EFE10B721CF410A0 -471163142D46D3FEA4282739312E53BF815FA207F0DDFD7200FE6F7730D33F25ECCCE770 -2765D198251988F9D85E4828719243D6275E563E439F7F7162BDCC0BE33CF25EDA87DB8B -D51D0B64335C358ADAE488D997D3ED523C3187A50D1E287E00552844DC66F3417D145635 -3984699130F9B7E860359DE4B14195307288A8EED3BE2AE04339CE84BC1C1D02861C32BA -47C050474FA44D746FB2BCC7A1469C9246DF0725F6B854FA1AB68D68E96228E2CB7834E8 -01684DDB14552974A23ECA2254EF2B6D195650ABF1E2BD69B2BBE1BF520CA77E748C0152 -FC5665C36AEBD0002190FA221DD3115ECAF905114FA7222822523711E48DC71EF5FF7BC0 -9BF1C3DEA0283B5868357DBBFF7B4C6F91C47F941B40F03259AD826AE6FF057EF4B07B9A -058C4B7BDF58C6FE1D71FE9F5E96ACEDF8DB833A4CBE46BDF8009F0FBECA3314AFBB162F -0545C10E45F1F697A2B895849DE0EA02F2770349317E43BE527A3B1D808785CA305E06F6 -84935F0E7AA4E015A8A4FF3E8F7E6E5472D161EA42B964F48D1450F9E52D5CB33C5D84B1 -4138225527E6680BB40D7E73B2CB4BEC73EEF10629E9C614DDF422DCE8E4B6F64DFC4ECC -3C48660A9E1983F4A84E4EB254D5EDA7E1A6736D98D878502A6320CC661E4F47418B4D4A -9D0DD2A9733C000A0AD41583095DFF2D1AFDCF6ECF69C85E5C9BB3F202BDDFB142E6C18E -60B07D7EA40340938542A5EA036B354AB35FA8FA0B9391765A8C498B85F454AEC3F177F6 -8A122FFC8976D4AC99A370B3B7D706EB1BD36B3AE5D51C9482FFADA8DC7584795E8696F2 -81A0F0E3E9912BEA16AA15597B801EE5571F4BD4FB95052049A663FFF72DF8FC6FA0CBFD -A15889F230C5AA3B25F4DA1500DC0302010956C520A7F73E1A7A938E895784C05399030B -D4452FF0BA27AC1563BFF0BA19B2C5427E2E6B8A06BBAB6137DB007FC4692267B0D10ED3 -1C0341AAA6F3BF586940AACD797830468685029B2284346296F1500FE92FABCDAB796F35 -46274B8A69AEA68FBC6E1EBAE3957865D7DC284EA7A6CED43CFC91B1CFA4038F413DFB36 -491FBDB1902914D92F2E45BCE9EBCC1484C97058783BA2C17F42B57A180C0F4E35B71090 -CB0A51F6AAD0A5B01E9AA7B8E69FA463B54A124AC05B01A942526B070244A2ECB6DBA5F8 -01DB459733371F92936CDFB4F35F7DC4ACDFE02A4002186F98A1000FA168B6B409D152ED -D5BE9141CBE10E0EA1C17687E011FFA488E8D9DA7D75E847770AD67132F8DBA4DAB8E567 -54CE8BD5B72DEA699E2EDB0BC2868B71E012E631C747F23F5C221BE43E034DE187BDD469 -E712F4FFFF09597BDEA4E71E76693FC639F758606E99774C1FEDBB5F121AB9B0240D1AF3 -86B28EB0024E13C0CCB25457F4996665A9F68682995960BBBB9622C70E1910C36BF19E5D -AE05BA5AA16E07F1E26F00C5009F6D5BF8B2AB9A3A34ABCC391B1EED111BB98B0A357D67 -91EDB58EA4B24336B4C0CD8994CD552E29288AB0A7FBF948891C41639412F0F2B70FC00D -2C509270C53B5EA1306176290600581E0E7A793FF3C6A085B9C627F941E36C4D6D31154F -6CD00209EFB60C1AAE01636B10484C673C58881FF8B54AA1EDAACC309F1C72C434247C7D -ACA423249AFFC2ED1E53D1B862FB553E583C4694C99B6116AE9F6BAF64D2B512C9C624FD -EAD7A00D757B5526D4AC98137C875D0E0E051ACBDE4996DF3B4D5719114C22D5DCF02A06 -4DBF81847FB12C931C2D8F6E9C557666DD6AF7B28E7E763DA7BE334EB3FB89DC1D5D8F12 -6ABFCDB56CE31A41E098375CD932B9ED53E5DCFD6A943A983F071F8B6EC1C35DAC748BFD -32B8FAA674B8F902B433BF12F554D391B56A3C8E36B6AADCD9489CFF80136FC575D7E64A -957656B2C4FC270F23AD3790BCC95E85894C61108A9EDA8EC4D22E9846ABE07A528583E3 -3084991834D424B8D52EA04CF93C1275FBAF578710888BAB0E447C395F0988035DBF6B79 -D65169437CD509EFFF8D61A333C909BAD589AA1069281E3DD8A266D4809471F65218DFB9 -9CF1D4A6C4C07B0A508DE36F53D506B25268058512AADAD9E9EEA08EE51C0B12977CC9DA -DC195E944C659D2E847FA471A403D3069BCFAC82479AD29FCBEF4EF6C93EDEE4F0C0E44A -34F25718B7158938A3A9CE183D707D4F789A5BD28F331C23B3290AFC5E4504794654A814 -BCD943F786F603E24C01E81C1E8577047C3E85BB4D861278CE2E7E32193D1849A9A310C8 -419214AB037971D051A9355EADEE4F56DECF0B20C0AE7A396797480EE47FF822F96DFDB2 -39122A3C8F8A83B8B3E105B3950C8E5703BFC5E591437422FD417A71797DCD2872FDD9FF -28EFB8E20B2EC948F0D4EB1C67E7E16CEA436DEDE1B17E0C4A11F1E91D3CE839DEC8390A -FF3C58953D098B24597766D01BD59A89ADA6F1040482EBA4157EF2FE71B220551809013A -B5B47CFFA33546A676DFF72EC6D1A04D82750805E38EAEDFAD935833B94133FD5FF8A58A -5A01CD5715627E74E0856D1F8455F6379F2E8256CE604480CA874DBA0D06E190833A8015 -7BB75CA24E95175821FE790DF854F15E7EDE318E0C0171FAC8BEB5390B47D5814E4D1F13 -0FDCA640E0FDB9D0A5068E98158FE775AF2D0C7D9136087E00E07B67AFC8FF6DD8FD9CCE -ECA3ABCD3DD58DF9F14C032941B13E01BF6EA44844D52FBC037A47BD94310EC47A1F7B54 -B6BC07C7092D8946CF949C654EC1AA520804F8531C1534BFA935FAAD3B9D7EC925BB0C4E -2C7E8E205C09104B8FDD7F8AE970107E94EC5C2D5A7F28DD7C0BD6C911CCAD24CC303D5F -0C6C9A4A585247D5EBE57AC01E7D8E3A384DAE4803718C1C81D3035324BDCA7BB452A030 -89FDFEB64728A25EACA1F4AB96A6749C4BFD6DF72102371863F719D55825AE83673701D7 -C5139567073180C72C6CF38A0CBEBDDB043D2B412BFC25A08CBB18FDA0AE80554DC1082D -E4D70908AA0C667073F0CEC5655C947CDBE6C501B1E38BE843A5A8CB02312EB04CB098F0 -638ECBF704DEB82CB1AE8CFB27B368D95A72757162884704BC4A74DC7ECCCFD1842D8957 -BB1AF1B020A97A149AAC0E0BA7699703E9879E49F122A838BC7465161E9C4C62E02B38AA -396C1E65209428DC112B08AA731031B4198BF48048132ACA9B40FAAC94A236BD16BEB9C6 -83A511F57E22ECE0C6C63C0A3C5366FBC488DD3CCB19CA471ECD0B895B644C2735C8D008 -945C02FB39F91ED4D633C151251CAE4E82B18B55D978E6A7DAFD6F4D5497EFC807AE9AC4 -2BB5E96A8630756DD2EF1A7529AAB9DC1CD2A98C9F70ECC97D8D1F920A5EDAB809C7BEAD -04B8E0C3266E1C2601FCDC61B73007294ED1176FA5C5E94075A95BABC2589B04B2DC6A7F -2A244975EB7CED7636A6216A7CEBE34CE405D1C2BBDCF3D30D0B65AB3F92357B9AF56455 -2F36A611924DBC9C90AEF0F6DA64EBB58510AA8AD7BC633B8340A942721C69B39A01A69C -28E44C520708800484B236420555098D369EAF3A1251B128881C6A71F464B0DC77B9D1B0 -68B476024784DF5B722667126F0ED991F123124FEEF22BEE19DA1869CA12E0C94229BBA5 -B2CDCDE1BAD1DD53B2A713C4EFBDE270F0C8AB7F9AA27FA800DB025FA10B2FDBFE4B8A98 -A1283CDCF35BDB1A6291884C494FC6224B965B55742FC5DAC852C0D014CBE5D8E64406AA -5845853F669A1667A543E64D5F86444D0CC1C4F796B0F51C0BBEFC8A7195C72566851BFD -01D5A7F44A707448E67D202D89994F2BDA312FF16B5287D1D13E4FF8CA905D012B2DCC06 -42DD1A85636EE7981F13C099535D935C1A1FF5218CB190A58BAB01C2F502323676ED3AC6 -AA4485008B7D142EB15455355811F1FE8B7FBBE5D93534A4936308067A6F6C1D80F6A287 -696606946C8D61C244DFFFA6FAB178513EC0F1724B24B3F26F1725471AE031FF8E15109E -A992D90EFDEDF8796BE5C16425E1E1391680C229067BA9C69CDC20077C02364C6E62EEA2 -CC5A7EFAE6A9493FB1FCC5C93228AB5DBDA8A2BF8161FEC4492B02B4F29CE42BA9C5ACB6 -8708C055BA56CF6210662112EBAF899E62CDB2EB8A685EFBD1BE151B4F2CCA5DEBB90B5E -55FEC92DAABBFAF7C3778BA79A59B131682568FD96640F3794EB7C57A508DDEA025C7120 -89F193118946022A9024289B2FD5D6FBB8B8413B0DF5F65227DC12E99B7B657F846D798B -F5E74A3DCFFF1B9E1EADBE5A22268846CB5749B22A96CB7C2A7E1BF47E9E8F5FF7354314 -3112230BA9E8A3218442BB7DDA51AB8641BCC1A4F6D25B53A4ECDC171F1B384C6546F6D8 -7239CF09E6C8573BD593FBA1ED2C42443F6090EA7A5F4AF4781270BFD801F57F42A7C51B -AA65AFCADED310E6F29FFF5D641C2807B8CC4DF05D45CA5BB072F73E5A7364851C7DEFF5 -270D676F9F86E425D14171E3862B7FAAC43E181CE165BF319EF549BC8B5C3D3EC51017B5 -8FCC9817F9E527D8DD01F33C9B99A98F675312D26BB76FA0DFF8B239A1CC7AD1A5AA9333 -8AC724B6A4C9B5CADFBFF718A5593C51E476468BBCF2E5E77A151DD9DA236E5765CC545B -AD8D10D62B238BB574D665D0A6CEC479D1719D587C1362C2AF7C04793B2A7B20C297D5AC -0F96F6019E1648B603AD04F8817F6A6F5E568A775850DEE71372303059B137BB129580D7 -D10134DECD6D801AA62089EF6A573DE96E0958552DE214E3615A306B798B6D68314DBF57 -4305E2B09CE8816EA4515CD6D2FECD2EA452FC01F62464E73FA7006117556487B6F58197 -5EE9CA6DCA4480FB0B9450FA07B5FED7528ECC235BD8D3A24CA63382B0DDCADAC78384D1 -E5A6EA0646E3655E6C86C323CEED8F76A53677A70AC54CCFB97A3713E5209E1A0F9B6863 -289A62261BAD054A7A495C3D0F883735284B7ED4A624C39C8A03B93FA9BB91BB396C0E4F -E3A173A5100CC25ACD1E3967588C56F6F3E70AA6E9F5621E4B9F3A25C0ED1B89054EE11B -ED849B16F521BD9A143D0B29796D66BD57B4011EC290045DDE9C4800C2D0D1DE24501859 -50DEDB737635EDE2D1559E0BA7C0B361BBAC80FCE4E4B35746B8865813930ABAA5BEB288 -1D820EDA6A683CA4A94EECDB1BD0415D0586C844C66736751640C5E8055C6093FED9F84D -EADE6273926A863D231C9B461B41EFEB4D945D529AF5BF494858A5E5E0A0BF1B179B697A -F25A3E29991DA1DE79DF293961AB7CA49846941E82FC59B1C06B9BE8BA005138F6979DF2 -7909F57060DE9028ED61B1EDC811A60090CDEBD7781D628BAF2C540FC7B4783BB1763630 -96B50637075013D726F9D0EFA2ACF762929C06075D5992B5E386496B381858B6AB040CEC -184571C870023678728ED7332630969C86BF521693DE56D09D6D8B0B37511C7D714E9932 -6DD501DC3AF262A1837BEB8AE03DC161F61251A615103EFFFBA7757615F60F7AF5DFEE44 -5F9E832E4794299721776D643A4395D21F905685BA9038521F05E3C3E5BD1D3EF9C229CA -695BCA0132C4A64A71334D9E76C48F6F4D5901CBD9DAEBE194071FB0FE7D2C5C395DF93A -C1C64AA36EEDF18B1CA6E2B510E52A35091AE7673924F36F7AAEB981B9957A3EF3123C5E -05AFF67CDB142D00CD16E03754BF6C68CFA2D734333AD69B3A3296EC597C8B76CC3232AB -45ECC8B2C90253A7001485D49E6310FDB5DAD3E7EEB4305BE7DF36342C4B1E11E0945B5D -EB63198EE676FEB7D3382D0CA6EC11E11E8130AA9740FA070EB518CEAD8C85D8BE693FC7 -15B31D6CEB164254D322B7032075DE964C94AD8B28BA58A3A30EA9DE79234F4DE0CCE216 -DC09F22CFFC1E740B082DF65F10F9D9D173E1F4A996F16D5DDE396179B4CE389A555C3BF -BA3B9059418EE567C4DC661C151F9EBD8F2E006288A6CF3B86D8F260E15E77682FE2976F -14D4E69ECE6B15C1042EBDABA1D24D9758EC60EA675421D5556C26A83CAC3B003F8426F7 -98195AF444EE55CA608A69408D69B7B103FE873A1CBDE862A7F7C4B27E778D4ECEB1F596 -C4796B37DDA26AE61A4579506AC65F72BE3D01C2BFC79556913780F541E26E5316F6A56B -5C92DABA9B7B9A9E80BDD4FF1D3F27559F83021D89CE8497F665F2CF2FED3805F8CA7D36 -355E41188F853B192CC64320849EA08D09BC87D24DEFFA9196F75F00893DF4A069BB4340 -A9A451102003DC8FEDDDE6B648EE1675851310D15FE319BFD1E411DAC0402698598396EC -9B01FAA040F37D13D65D9F88120D6212C7BE51B98FECC29CBEFBA669EF8B73A39EF24D86 -8C692FBD3C55724FCC7BA3912B87998A4E50566ED69BB2742FCD60FD3BAD55EBFAAA0E9C -8BB15FD2BB7BD82D65E722297E9173E09D8C228A76755A3611170CE15924D3F2BC9FFDDE -B0F2CDFC4CE44B6507B03916E334B4FE336473D0DAD959DBF3B11684D09C67872EB406DC -E8AADD34D2A0FE88056B2184D2B07825749A3131CFBA4A6885CF4D84D914DEA0A4DEBD54 -F35F031C2B4C18D2C0E5DA80463FC86645A3B63209C53BD98B394398E506D8E34F0637C6 -BD702B6BAB0E45F12EA06112EDD4983034410D96D3EF907D32C71AD4953A8C90FB289510 -70AD7E985BE69AB6D180E110FDF29770905DDEC7DF995FF72724A275CE8CE825B9322B9E -B301DD7E90A6075123279F9EA89333E39457333EBDFC5F07AB1563003D0E766A010F2342 -A5E210C256CA182DF768439CCBFC43477E25E15BFDB3A224BC1C9D67B0A0EE160B7142B3 -58330DC30E49446C18969AB491CBEAA64AE611F587A3A7F7BD3B206CD034D0EFDC12C992 -4FC9F60EB7A7B7BDD94E900C5A58AAC8C17B3588A95D614197E1D5D1013888DCBD84F7C2 -51DDBDB5E1EE146350A94679DBE6A67BD7EFF924C402C23DB55C00664754CC9E4D3B1422 -16AEB7A712CE85947C4680102B651F83DFE71428028B258E722D827C2C347CE087C741CD -F0846675E34D56EF99E21854CA02AE9BF9B41B34E58A1D5144A6E9D698172FC2D8E8DC49 -098B77980978D67285DA23F821896D3ACFE7ACB6FD5DD87AE6D07F5FDE7AA553A869E594 -BC2EBEA2E0ABDD5E747FCF0F7D1381F9E121E97B11456F80215AC688AC777CFB9419D95C -DAB35AF315C5C83114FF51BD583F17EC51A911F255521B3DE63C5B0A016EDB98722E0B15 -FE68117B4406CAE3F29DF6CC813569882C169070F6F499DAD42E1ED6DEDBFD464D352B53 -0BB28FE2554FAFDD48FFB9E1A433E94681A5B9DB2AA285BC5CDA48C1BF7AE7999E5A6678 -D9ABB9A68BD4A60756C13ED1975E2107F6D1FC4FCB2E18FC25E68DD2E53A623D15B95541 -31F1DD74E82AF748119B40F6E4E703DEE1856BACBBFF672DF548327A95F3B52DD40105C3 -604A24047CD989DDDBBCCA27D28F3BCD681CD55AFAA1CC5F29B39FE1D6B59FBADAE71196 -CD83F5329C9B969A5BA06BA67AFC193C4BDA78A275C64E2D82F373EDB713498ACCA9FE26 -9FC4736828D55A98AB9FE487AF40164FC38085F9DE01332E3710F22EA52DA9CAA28DDB5E -3AA72EE9444F818DB13EAEE426543DAD3C78D48B513DFF77C18555DA53B33B04C8887199 -7B2C9E86E12E94AF3F379D196532D2CDB84741211A584B7560DEBA3C53CC78E240186671 -8D295EA11162384F00A727EA4B7EE6527DD7DFBBF5966FB4372A35BD2FA7BB7A6FCFE23D -AAB6570FA52506E3EF532E7E7930298FFBE47D48641C0E26D1BA636AEDCDE13DDFB3C822 -DC32C43759F016752DE8F256DF5B57EC3C623C05037F1E41C38C66D18A27610CA8BC0E5E -FE4FA49EB0E287E855990B9C83A103A1151727B192496B318A0730AC902D7C4B154155A9 -47AEF1B7255276631566EE5B995D9596517E42DE25FFC666FC0703336FCFCAA2B97031EF -9B95FD714ACB1A47A249DA377A6EC9338558939C6327B90B77249CFB4CE6FC947BF1E88F -17F20A194DDD37657E8D5BC31F624B6976A0078063FF707BADEF04391782C6660BCA4623 -17BC929F6411D2351B9DD2F67CE4BE04D251829BA6E5ABE574FB3D3D8D2858AC7B87F3E9 -951F0FAD71060D85DD3BF22DF505778932D2C7CEE2BD318C0E9601D085FD258C6ABC091F -EC3F44C639B2852EBB31BA5522AF78BEDDBBC52E804D5DDF23DD119B951551695BE44C23 -5DCD52729FE0FD451F9CEF413EE55AF45128E35BB451D654496CF1C8C2BEA6C95F87040D -928EE96A22AA91E8166577727896E7A26EA5298620E50832956DC5B4B95986C69079A1B6 -8F64DDDCC518AAEC30D9E908BEA76C19D54388435012C2F8ABAC88BD1F82A1083F729569 -0A4076112B601F35B1E104720EB73D88E0E62CC0FE278EAF5BE953AD8D44604C35D05A14 -7123538297A5B80677AE45EBE1620302B8248F2B0CCFA068CBF76C863CDCEDF677AFEF18 -F4934012F795C9CD39EED5915DDAD4F640BF75DC91CE77E4B449703C1FBED867745F67C9 -BC48C987BCE8B838D35930735744DB987AA4E8EDC83236D764D1237028F6AE8A6CCCA003 -692C28CD708F1C9F4B0468140AECAEEDC465455D8C69159ED0AD0D0B004A8B51ADFDEB3D -82220B8D2DBCC5E1CC0F550E44B83FA668B30044A2E9978A810D4EF995490065DCFDEE41 -E94DAA51D26F13EB8218220FCB1F0F32D5B5C15E715A4FCC605B2F8800F44B82633A83DE -FA4C3430104CE6650AF07AB2668E751DA4845205FD29B7B03F46B51DEDC3B6DB3E534E15 -AA0B33BD6E0D2C5F8442EF326828B9A3188EB15DB04F301A98E00710AC5CFBFB9B2B99BD -5AED103DE636341AB7B03E24016228C0DD81EC95D5A8B8EE1C44944858784C024BE6C8FB -D038801D2423D09711C5FAAB0E16C87D307B53FA9F874E6FBF1004E47C6A6907DF86BA73 -9DAAD79101866EF02234D746C72BC60A69F7BFC111C5C26B87440D836432E283EB0CB8A9 -39ACB06AF4FF3857EEC12A1BD1189514CD518060FC75DDB601F545CCC37676ABE3EDD86A -7FA54DA5C33D42861E585D05EFD8B41D42F7A9A904F48FD96E30EF9C74433B35B1EC9F3F -15607376F04695749F917ACA32779CE1CD986051E43C2EE748542E4C7CD50E3C30DD46B7 -C6F809D1051F977E7D351C67403B913BE5273A97429416656D83C0BE7C08CBEF00BB4651 -D0D5CE1E8885A32CBC72DD26CAB330BE9845425E048B1EE1AC7591F0F0CC9F73E1EBF665 -76591E3DD449304DAFDFB6A44C7BC4DCD9202AA223C9128A961792E3C0DFDA3515BCABBA -78F38651862266E779C228C596BBF3903F097765DA142C99E5185BE9DE2F01AFFF441965 -198BD1FBE9BB8D61BA6C685BEBCBD4381C20F71F8DEBEFF62D7946B04C7D357E54ECAF48 -A49EEF2ED25179C1C3FD45268363FA20D07A84D60484C712A43D224C57551FBDAF4973BE -EC02A16076184E3108DCADFA44B93710DB3388E633AFA06AFEC76802F05EFAE2CFC74A5B -AF3600A46B026AB514EFBB7184C75BD39FE9427F6F0F9D2435BE1B26BBD4816A72B8AB67 -DA7A6960F5A7A0E7FB1F83DCA6E3E8E8F1BB11E22D378FA743B7791E981D117A2E8126A0 -F3CF5C9B0C35BAF8B66211813FE63B029E2A3913CAAC2603AA4AC900EB8428FDF58DE83C -D998B69BCB6ABB67FAB1647806FE19FD695372D671EA0B6566719938456CC79D265C9791 -725AD53DF396BFA79E945F4AD42DEE0C69C995EE8DC3D8E85BF383DA9C1256AB133CECC2 -49A3BCBF384F53AD50B3A58606F4A92D68DF6C072E66997978A92EF5124DFAC8B3938E60 -94C0FAF7556D0F75925FE99AB3E80FEA8042A977931E75635051DC896059C30D7ADC38E8 -90131D3472CE1BBBBABF231728199245250B618AA5F830D20C8B1117E4406C97F59A9A76 -205946764DECECD486D1C217242CF8C58263535485E89344DEFAB9D94079EC177AF6DC31 -051EA610E81026B7569A061E99309A04CC3977C9BBA45E88B6AAEBF585B5C79E42548C23 -060E0E103CE6EA0897B43EAA35366DEFC5B1E5E673424D707F05C770F31218BF56855627 -8C9F75A113F5DB640C2EDB7F9D3138A5C314243030CE2BC58F4EFC9B546E407A1764118F -F9D2208C6219D088CD8A214CBC0C1DF55772A04DFABD89E08F7C98455E8A5F1F82BA749C -7C5C5E6CEDABDB9B3F6E1D717ED97A50D0906BD4682D9A529B3530F29113A35D5681980B -8D099BAC264E382DCFAB0419F3313453A080795E7CF66860ECCB8782191F4CB0EB2D2965 -F14D28EB35DBF1C95437674D84C1C331F4EE99C8DECD6946069B3A4A7DEEE0E48E817AF3 -08C28DF99E67A4413655CEB10BECCB27448530B1688517F0C5DBDB97A17C6F12C6AFBF55 -AB5AC791F5363E56AFDC38DAB07B7A47B9FBEA91427847C5EC1D584FF56E6F2735FCEC80 -DEB8D89F90090A11819D08591A37EC3948E36AFD44237CAB16533CFB51B50E1EBFC4A6D7 -BFA520FDA738662AE6C0214DBB2723FBFFC986E9DD47A493FC0090575CCDDD6C38EAA038 -3858C077F57E1DFDA8DA95C9A18D9432DA2C86DE069CB675D9C8189EF01C567CE476E0B5 -31FE688044569D34362235F894E746E6306C03E76E615571D9CE6FB31D63BF1DAF29AB76 -27C0D02D7760EFE583C8C2FAD4AF0A90AE91642F2F20725858CBC2FABB5A5A36F19A3C6E -455DDEBAF968A90312E83193605CE8E5454E396C2C59557EFA1BE1E0F8A0AADD060F77E3 -C642635484956025266155DE24655C44BB0B4D07099D81760DD0823EB9EBABBA27A559F4 -8803E6999B782A4D91C388B46E1EBA6E8BF7CE9080F46B539A507F5DD17AAA05D05A551C -B57918F3AF43390187E3765548F4E5A3360A95C80DD6AE1B26E1F90B8391A3872ECFBA2A -087415ABEBB9119CAA1D411EF7E0F0737AB30979A30B2ECBC8EA42F38B41421CFC94BFB1 -FD30BAEB6AE340D043A15138AC4A7FB12CC0AB80547DA81D91166B09CB56A5504C048DF4 -D4E1E7083B5EF010A38F4BD375A3918D25B05026FFEF87AC25AB554EE74AEED323B4AE63 -0F1320CC97909D2819A8EB0A90AB5F1147DD888AEC5D42C8C5F2B2728A80AE8673831189 -D76571F665756C2C01AD4F936EE0E607C27FA9B8E38BA5C67B52E7A50E09AFB2D0610A00 -863C59F7A1BF14A5D3FF8954CBBC3D13F709B433822DB8CA2E64BA1FDA4F9478A5AF24FC -A4427F49F39EBEDD3BA9DF9B2ACE9FCB01BCC9153A7DE685AC5284427B0C573A6E5D9013 -86834552B2356F11011083B65724EF7F8C7D7CA259E0C03793B9EEEDA5B6DA8376E72EB8 -033A415DE664EA5CF53B88655FC02AE5E530C6A90F443F740444956B60F6ED760294DBC1 -9F492DB3A5D4E532D0DBD9EE8139092D3E89D7CA7490400FA4EBE56334B1A17C9826AEB7 -74749C9193FBEE0414C7E7877E26B8274283F14A14AC7CA27139CBB8CB89A6D38DA283DD -3D421153DB2D917391215433E356E64E4A07F6D82EED542FBEDAFD11D0BD4EF3041C6865 -2ACBB1FE71C6B7B3850FF45176850FFD64D18D4D55BA5E74D037D3CDFC62563CE2929233 -1E42E636DEBE14DE81804C1A15903CFBE782409A1E8684819BE6AD86F1C0EABC03F4CCA3 -A959E0B6C57F02D29062A6F0E3E5978C4726C01F607307C16F5F64460E81042B8E2F6524 -EA16F9BC21AE861DEE4013959FBA74E40B750AEAD9607FF6D15D96F6C28F4E9398C70CF4 -1B654A2A337FC8AEC523F27F6C5F0DA4B2D4A3758A0DAC65BF2167DEA823C3D108D3661C -CC47D80C948444701335BC4DF8A8A8E433776FBBBDF0C97E985DA1311451CC85AF9E5BD2 -FFF576BC8E4A79C92A00678761D47D093A26796DE0316A80BA5CE0BB69E188F4C38E7BEE -45C8DE646991071844CBB503847613EC82BCD6950F44D64D8117B52E3A63402C09931410 -D7A1AA9A04F9815D52C3BB9FBC829F9DFA76ACD77BC751475979D82275B709AF02783A64 -A633CD8F213DDE9216664C22E9F9AE3370B282E9098B86D4FDE991FB9D16D04C0C7F5262 -D539102F6529D73F20D1996061515A8F1219B228502590166332AE7D27CC822ACCF92861 -5091818F53CE6A7F1C5A68CCC3D6C7BFC81167C3C2294C9591B71CEFFC88A245E16484DD -1080375D15B6A3BBDE47CD198D0BE312AE1F5F6EF6DE4A2CA38A717D7104466509C8593B -FA6B5DB6DF788C6952A28E25CA9E20D636EF9E84FE3CE4D3A4647464F79111A610A1AF84 -E0BD4B8F7BA06C3AF012C74C91DEC0C597E6F4C19546D258D9E53E7943D6694EE85C74B4 -93276817411892299BC02A2CFB065F5655DD87E69743313801CAF098FA1C56841174EF0D -4A7F27B2E91762069656895B9FCC9434434ED722BB9A532606688F303D0C514B31D179CB -DED0DFF008F09184FA548FE7C276989AF46C9C63000814F90372A1295717CE87B2D9EA55 -34C0A4D467A0F6A32482B8139AC4240E3569476BD4F8D5CA5CD62F28BD2FD820602FB678 -69D696EEFFF2C173D2C7EBA377390670908EA07A7E90BA16790314AA8A923B234C8ADA37 -25888BC9A631A4A5B308378369C29B79966AB44E3F4DF846B0438C31B6143C9C3A003C86 -A2119FC5FC1509BACEE7A9A1EF43945214A1E37879CABF18B7A18E8BFF45E9C5E7CF05C1 -81F2BF236310B0AC2B1D45E0F6E3961AFA34CD8597914B6D503F7F5BB964B7DDF195A95B -FD5F3FE49340767491F213D849B3299AE439801B84A2718489868599F29DB6849A5471D9 -043C6B4BCB4AAA48DC6CA3DCDBE782D3113463400F09399DB804AA81FAEA98C6C7FF513E -1CEFDDD822C4A5ED4F0EC1AD96EBC6A713BB82FAD69C3E914AE2CE2AD2DE8FA301364658 -0987D4836813D3DF7BA9A77601FE3DD487408794D7167D6297BB19C8ECA466D56F130AB5 -E0ACE40D575558A8221EF634AA1D43CB10B8CB8ABE6EB2EBF97C8ECBCA498BD740A73DF4 -0CDE64C2C0F2D1468C01047ECC2320A9FB6D965C83A2CC768323CD1FF3590D6DE86AAA5A -4ADF258AFA132E8D8C04AA614E11D26466CD9F265AAE7D8F3629857C73946C1CDE7EE21E -15C1ABC4A1F591DC1CBC14B66269525A664419D0C9AA2C4713790AF5E23B566EE38D0530 -886A48F041B8B009C5522B55E63813023C763C68545AEF0FBDF2674C94219D0233EE3D3D -165B31C9BD4B9F27649B860D935D77557035BDF4238B499C5CEE68E946454034E4841914 -987B718F237862C350178B8FCBFDDDE9E184B3EA11240ACAA8AB1880410F42E0C66D7A2F -CD1DF1A3E421353590D9880F7A5A0065314D2E892D45090526A1378ED18A694F6820EDAA -5599C2EAA34954D28B021848397DADFB07F7529EE0C975F5AEB815D91BB7CEACD2888F3C -9EB8BFC41EEF2883618CCBAA18890E36B6CD9973E0A0665387DDD9829DABD9DE59C20652 -6608C3FE3D5033C33DF477762D37F080E3CC292D9E18348B2200956458F0CE0987B39876 -733331F948C4F15C818AEB8F829C03DA8BE6EEB40AF79A1686AB9A289FFA67BE3A42C396 -D5D24246959921707E84C9D4BA448BD725D6DDF0F735C9ACA2FF7CC28B75A81100CB2B6E -05B75DECBC1204C68ADD1B324CD24F99E5ADF9DD3A41CDF704184E27303DA98C72037B29 -276445BE607B12363036C6EA298E2B47890FE0C3948DD0AA3D0FAC17ADA775F58FCC520C -3B289ABB6315218DD1D5A6F36198EF93C58096B8A4A97D6B49278A7E41E0ED9C9D28186C -C8B5D8DC860505D94B5BE90D1765C154C43238EEFD91F5A385B6FCDD19272F1E9E3E50D3 -83C523509B45D8A166727E8022861AB6D8A8DA71EF875A19362015DA1672CAB7E9D80E0F -93A00867BF6A4B2894CBC866BD744013E8FED49596E6D0CE6D18D5CF56CFFB2BBC53FCBD -9F2B1D7221A7F5B539AA962F74E002DFDB8A1425A881DA6D62DB3E1E43CD9C20C4B8C0BE -FCE4B01FADC43B7406529B30BDD270098761F3BEC88EA6AC40C5143AFF3B926512F2D560 -F381B90202556D8E3AAE54712179B1C33131D52A4423676F83EEB850FD9D3281F4E092C4 -A3B402DEA3D01774B5BC9AA527D7E2A28EA9E6097064DF15F9A0F5B1AAE25ABA18689AC4 -2F1E2F1BEFF552DC96BFF8798FCD5877FB4F4B5082AF6D3F24293C7D34344959BA691E53 -8575D64484F2B36F1223DBC2A9959793C29DAC7C28E334775A1081818099D1CA68B693D9 -ED1D3163BEE2611E01B87E8B443A0D8AD12F251752E7850C29F2A535971E4BF055EF7322 -652B71CDFA987F4A51269AE8783EBD530F6180AD15739754EADD4811134E25FF8D2C6FC8 -9FB63D240BA9E80CFAEA02523BAE484EEF08045792885AD55A5D77F4A6645001DF9A596C -877DF33EBA8E728567A4C4FE3D848C7C16E8A3B156AFFBCCAE51E668656929F9D061648B -27093B54604B900461B0E9ECF73718C3B5FB199592BC7C59466F041BA9963920E2174F59 -7F943A02728D5B7FF69735757F5071904A2F6FA79DFD8F35E96DD4F92ECAF58A184CD6F3 -C05E50A25BE5E77BB2856AF8C71C69BDB8EFCC82EE65BA7841387E9CD655FDCA5707DD67 -26B96EF73B36B83362698C5945C75AAFDBBDA1ECA470512B7E11CAC4FFA3C3C66A07BFB0 -1F927E762871045195410E088ECB16884172E616721D58A5F51B5CC0AD3B3858180E1A36 -76CE2B46D4D91D06B146F81BED26358E5301AFD2DBB78D60F9F1A6185B50BF7A18CD41C1 -DD9065950F64ACDE99EBDCA136676247E455813438395B2D3FFEB24A2DE4D8D742EBADC7 -CEA283AD867A1239C224B59D55BEB159D6E4F5E588AD01DD7D398AD7BA539E6F82F8AAAF -9F5F1A7444DEDCBFD014548440DF870D701E9485467492E832E235FDC1AA087952B7126A -017E73A40F8CF1EB23E9BE25B942B2CAD61746F5277B807FFCD1C99CE3B2EC69FE5A648E -92A04C71CDB188935DCFC4D261DCD29215431D80A7979C571CB7E1CCBB7E3627DDCE9717 -148CA0E8BD7F7F22BE4ECF15E8B6CF1B0B98D55A3285DC2819172495EFE082B32E72FD3A -91986A13CCEDC5D832C77A4B559175C53EEE61089B4580FC39F34997A4DF83E427FE668C -3D89C417FE22308176F895549F6E5BCE6EB9AC04675AA645BFB2D81A22CB7B30CA206A3F -01B9FDABC7055B295236A79DF2522E4BB918AB2643351186D695E56E61CFF970A4118686 -E85A4D2E34C515D0203848CD2E92566F38E1D0DA886DC2BBDABF5B3D7B4BDEC68C5FE6C1 -8EA7E92F5470CA95AA5CDDB9936632E9DDDBC7FDDB86D4E96CCE3E8C579874BEED51CBE4 -D861D6657AE53192DB369EA930F87A9CD2FD7F9361D7CD884062870D4149126AC714B191 -1AC77CAFDD1C48686AC3474BDB9ED4B73EF67193714A392C4B273E919AFFA7EFBE7C690C -82E547D56C79ACC4935BAD6C4F333FB5774FE84084EB940DD7E002410132F4A84894E2E7 -4661DC6CA73050FF3BFC04AA8959E9C91D2EABD7447839F3B32E1ACF1482E6DB7ECF37BB -EE26C27AC90BDAFE91F8D92534DAE644CFC38E2A2C540A3868B0E16A6DDB60B02628A94D -5702C1EC2211AFC1A9F7E888B90263734588B6FA7BD2CFFF5B56F91A70633C1353885C24 -8C5FDF9CA938673645E3D320D7C5566F4CF7C9C6E86C9945386A16FCB72D342D936B0E30 -6EBECF12E4F45A6CEC4947A71D674128FB0F72C198E4F4227CF98E2F3CDB7E7AB55AE127 -1C2A39C526CDDFB66A183B6589505CA7F5EE98C400A6C760441B01000F2ECE968EBA5DE5 -102C3974AD4716D7789E07AA39A3458740D9F55D5B35DC0B557CBA9661B6588B37F63173 -7579616AB866890E1AF0B90399F1F7E95E18703E6F723E70B2C00B6640EBB44353DC5A25 -D007F285A25B3241BD80CF83C220ADB9288AE09FA0DBACA187671CAE9C04B61AFA10337E -75FE9FF0A4BF03605D0FFE41DEEB2F2DB93CF868CC7155DE51819D14FE17986BD187DA95 -96C1904E8AECA0F6DEEE83C9D8CEBEF4C0D13D5D5A13E6F3839CF955A6AAE6F7F5DE124F -0174F811324CDDBFF0247214BA4A343959EECD37D67EAB103B4B9CBDE0FB77ECD1AC24A2 -C9FDB80D0C07AFE58C4839CF9D4CE6B78A1173AE2F05C51F17827754A8EF22B5FA54F3E5 -9ADD2A1103F898664DE8ACDB89929B04776F51E241134E9A77F071CA83DEF1E04EF457C7 -56A29D540B3ED164BAE4BA2C56967BCF5BA142CF8640CD829A952063BF1D9714AD903999 -F3B59167E2B440BA083635B6A11A652E94AA1135F9E00B0BEB10B533811FEBC64C7107EE -7A2B4CEB6D019A305F633A9229121A9E1097C289129181CA5EDFDB7F9EAC133C6025FEB9 -9C9BBA2BFA67603A7790A146174C061889EC6A77DAE40C6C4E002263203BD6BD05D3699C -7C21644A24D562DB3C2CEBDABD3DA2F607458CD4EDB1FF6F9275F767B8FF38AF5DDEA7FD -A18A1CC091BEDABC7C1A959031009969572A97AC1C6836F3C24F6960ADB94D89C5FFEE9B -3391C4671A09EA87B8675CE4D3C473E3B8A750671BC95439E75243100CCD0E0873A6A218 -C8E574583C968E46EC6115266614DCF130AF7F2CB1DB978B409846735D7B29F1F8042921 -7C32639EBF476E5B0EF1367F65F0600DD11C0142BA2386FB01479DED4F8AB419AB5A82DD -66295577726A4C30D92A8972B72D0EC338487B630E86FD7984A97502583B27F5D1BA3A0A -8236ED3B99EF2AFC4018CF8EA12D89158A04353B33FAB1E638F1817E72E8B6AD3C58A86E -0DF708B6F1EAB273E746FDA3A8013271F16D3F0DBA72A07FB48CA2E0815F5635EEF35FBF -27DF180FE2F9522E57CB690E4DF7BAB0C4F07D34BB8984D569340061B64C6D1B5B5E2090 -31A81A794634F445055CAFCE9E72BC0724EE4C9CE1F94D461E9619B3CFB47B5C404D15E0 -3C61B1F11D23808893679372E8BF24AA8D6D443F9A29C2908331F799593CBFD1AC2EAD9D -855295E0B486E8AD72F570B3D768D775D4EDE2B9E48FAB6EF2C3A72F458D8B2DC2D534A8 -55FC77ACB99BDA7B5FD432D848815D327BE30A97556203F1C4276993E1A83329E62E8288 -7ABC85C17622A83B380B8E0C381376DA627C5852F0A031B80E22273170CA4D1367B183FA -169F6EA37C541C3E4EC299A8F34835D56AAE798E69B233309FFA71761469CC4736E2D627 -073DB92380000DA1B9D6353AD27DB894F3DCA36918E7CA103B60B1AEC505D6BA9B22A92F -BD69B9B2EFFD277157AEBE234B579E82D829D06DC06E67A4AF366F76D9321CFEF7DB3167 -3024556E61DD0FF006848A044D80407DDD75F123B155681F47C15283A44286FAE9549D8E -49477A38347F5AC9940F511E0222BDF46263DE6DBE16990D0975C2279487BCAA41177833 -C54F854836CD22346F409021DD7424D157B2E6DC9CD664EABD2B5352B1326C1C046D6E91 -306E84D44B798DFACAFABCF352426442DA14795EE6EE5A1E451238E946943534A0E4D53F -5CFF56D8AA689FE7E45D8974C5CE1D4DD9608AA42A873D0A0257D8766E7DEE544C350556 -5E58D358F0AB8DC7038795861DDADC8B0387D823F3AB985FFAE915019CE53B91A2666F39 -73143D04434D1B572ACF9B335F0B921E1E49428DA8AB0BD8D09B351C8BCA247A86FF7253 -4EF78A5150BA14BDBA2D535D5A46017518104E810EC678C9202699159CD05060C1C9A5DF -7421F17177B9141550BC2B2D9F2BC5DA1346AF811667AA0F5DDE7F690B366F6FC9C3A488 -B88D827C24ADE4AF85A5D5CEC82BED8485EFADAB9D9CBFA07A879A9D6141EBCB10028BDB -83DC99174B710E444714AA5D275073EFD6C542654E303D4F61826E7C505FDECB175C31F3 -455A2E835D12123392DB79B22ADCB30658228C0142B6D271FEACA94A186539740AEE942D -11F4B10B00C6DA85D934FDA37B37332E61C66AB95EBB5473308E3F2E33F220CF1960202E -5A2A81C85E8E831D4A48A7A9CB178A3F59AEFC408EC69D76722CE9FE89F5B7F1A31C7606 -32EAFE6DB673C6E76B0E472B2F0844506A481EAB5479CF0C559F02718F76D41F78B2CED2 -19D72BD4D9CFA3F99F1B8869E0A8AE58F40DCFBEB1B8FDB98032C3430E7402B9B1A93141 -74557B5A1CA485CFCF20D6830140FE0FFDE105A08DDB301E2109E5E371C2EB2568481443 -51F989472D19D12AB51C7F23AD18B592118EBB0945747EBD9F4DABE0C8EF4F3B8AAF5FA0 -34B3FDB56EC249523B1A3C32BC4A6719AE510FB82BE0CC27D6D4FA2A806941EA8E3CDEB8 -A30F91078D22260FFD25E57D8B3BF7A743031731EB7396D5E9A949039FB9ED19E38D5C5C -644696E3EC29B78591F522484829BD1A58FA3595AB26E0566838DA3ECD428D905824B697 -3FBF19090E11E99B789B61C0BC97C86C7FFB32FAB5C7FE00EECB9C8C126C55C959A6B06B -C709F0923589F9E540E746AC6949DE143744799EBEF6761AB9DA2E06127C18617324286C -874740B4B5F82DEC59585397A4B75A5FCE31AB26478A7BF1AEE14AF3098F589C1FB7C010 -ADF80512E936F57CDE3B8E244B00A80054664EF33B5BA3E4FF2F43DE74496A57C0F13B65 -A60A2F4CE599BB104E72EDBF9BEDE7B943F9404760B7A79AC38AC19086516CB33AF7F962 -0157DAD4D4AA68B8C96A66AC15C526A1711081F56738F3238EF37EF609BEB0792D41941F -6F1C7D95E0391CFF720A51755979EBE6323C653EDAF0808644E41FACCC09C29E1A210B10 -881AA79E4D9714F33A96735C3B2D0B13EE6272BD4D157E7FADE7F6BE9825E5655E80A018 -5EB33917002B5342002CE5D24859B6EA11E571FBD6F1F753974F965E7B5A8E0B3BAA8AC4 -A6C6D56EC55E44BC9D42C8A9AA29249B420DADF448F6DE76D1DC62763D5B01A4030A7D78 -28BBF81417BB287B267F64F8676174097E43E99785609F9C542ED5D29121D5626A9C7461 -5B145C86C2AEE98A127B25A990D9D73987958DF6831FC937B06AEFEEE14583B91590C768 -7A9FC1CEA0EAAD6F29FFAE96F8ADAA658DE66B8567E8A9E56D866B8A9A08C3D389B3373A -AF2D0AABBAD35D8F3AAD5D04B69CD31F7BE8ACFF96CE6DB8C42E9F842E4254EB34C2DB18 -F0BD1D6EFF4ECDDCB5E77E92CE64F20260E68903EA705FBACBDAAC6CDD7FB431948F1504 -876DCAE96AA501F25FC5707CAE2DA29E995B6C4BC6CE6C641CED312FA02000D9057627ED -14D531443C740E7CA081652087E0360C095652A1CC56A27B7FA61B3420ABACDAF14E02AC -C80FD7B412A97CE4F33DAD5C747EF14281EBEFD492468839338802E42FBF554DA46DDE16 -88D26DB26DD3613986E9D28D14D4BAF9F739F93E8EC34A2BBA207294D8212D2CFE560918 -A72DDF5A537C4571281DAB8743A487D8C370D67C0EFD1698BFAB848E86D24DA2D213712B -BA731CA3F76B657051083119FDA759A58F8CEF458085052FB1440D6938E438774FF94EF8 -896FB0AC6A92DAEA2E7C00BD76000C5BA8BAB7E5282952B4F16BB9AE8265F8637118A4FB -F229CA87AE41C6ACDF9F8D318D6C3028A70BBB245DFB2E1137E3BE90284B26E8FF4CF77D -66231F1BAFF98284128D08E8FA4FA75981A22F45CC026B1906FAB73C2FC219D3F7253831 -17A24392036B26AEBF3495F3300F63AFB9F0FA950673F5584FB20CDB57EB0E947F31DD76 -945838D69875CD1A4E7D2AF5382044DFDE866E37CCE23F3D06B1F5A941FD06CC0550D64F -312A9D6A655414490AB1B1FD54E34748E1D408782FCF8FA6A611232CC7218B4A0EB93CD2 -09876191651777FB56BE434096B02918A658A7403E45F59A1CDDAC1BA53DD186DB8E35A6 -4078C11DC0DE5165205CBE612FF365C193BA540F5C6CDCAD0255E361622E94607400A330 -BCFABF835275473D4C7767015963CE0FB7DC88B4AEB660FBE4F86039E51DEA6DB4DD229F -73D4A0A322C6D349A4C8BB304B96B32DC129DDF372FC424D1815C4EC51C9B0743D6831E2 -6BB5E28E89DAFC8845F00E47992877FD57EE0C02A76FBE2FDE8802A176E8A03509AE57D2 -0CE44217026FE28F2E06435ABF13D27875C5B4C6057DB1E1F70163C1011972A9C0DECED7 -6C8B547B8202977D802062E4189713D7F579093F4B9A72C69516F1179DC3512584977589 -461AC3D1BE8BE1C05867EF6FDC26E3B82D9CF9D159DC0CC1F9D6F94166A60E6CB9FF3FA6 -0D2B136FB725DE769BC3A8B64722456F049421CB7F863A357B318A979C3513C9065F5CA5 -93022DF125C9DBFBB822B1F84936DC5314F17DDF2960FEE70CA3E7289409EA5AE6F15DA6 -0E407C6262D41D52C864705B7DD26AF2CB813689E24E9673686ACB1970FB41CAA49378F4 -31C53F3A08AC7AF4D13F7FA81B6C3F71FF999380205C74E1B29B5A4FBD349783DF613FE7 -E2CBC7AA7B424965C42EF2CA80C60E0EC6F7665BB3CBC009F0F5C6D4E8ED5CFEF0E5DB9E -3DC006C98706723B2BEC309ED20CF1CDC60D66BB478B87E8947419ABD499CCE74F80FE97 -89041D176C3BEDC9EEF152024E3678134EDF755D8C247E3332F7ECE95E649E73A54C5BAD -228A629F5F6C8EF48935C8591910230DC5D04C395325F0C211BEC315F26F84AE8DE9DC91 -A9B5796CA0ABCD4774CC3DE12C39C2FC257165DD8A7E458E87CB67B6A487F10C351C4881 -0A636E4109845E0C664C47A2E11F9C99BD72570B26E854B4BCBB49F4011CB2CA4464FA72 -6DD8C1F05C69527991D634487D48BC554A80DC32B334D3BF6D65F1AC32D0E764825C8760 -8B6317DCDC713644DA60322D68CE38FAB781D24E14B19E711BCDB629AF7DB032CC9C4393 -195992B6ED1AF8B84AA21B5E3BB12EBA01DAB58DCC2E9549747FD222454D0327C66D62E2 -7EEA7AD48B09DE56F0968E271E59E8965E16862B7968A14078BBA821C2A4487F877E3932 -1D56C51B010AFB2844BB7E4AA57E3AECEAF7213B1C70F6EB993706C4F2A613257027370F -CCA30A862ADC2D07E4619A8F753B13B94C275A14403C97CC131A924EEDF78933502A8E93 -344E91F5A238B236B228DC9FB65C60F8888DCA6B8A1EA897530D193537FF73E8DC70B3EC -4CE290AAAABFAC0EB4C9534C7F3EDE90E840A1CE7975204FE70B52ED5576B0956E62EE25 -7857BB5DEF2AFD8D46228E9625C5C0FE48311A07CA246ADFD9BA1435340914455C0CAA4E -92914E7AF31E25438AA05FA2656094BB31855A27BCDC45683EFF1291934C3C115D8CF919 -7A245EFEFE3F7FDEC037ECDFE70737A4D961CA634AE153B01F03B1A9F72B602A8358D258 -E03E54AF79090DB322ECE0CE33377E42E5373F443E851550E5D44F06C1C513173CD04D47 -9A9E70C9774780821872EFC100F5F5F34A1E0754E037F6F5917EF5126E5F12D46BDDC038 -2D11C217839C1DFE8D34BE69124B3934B22B4E8225BFCB2F265E197474B9349BAF2C1FCA -352EF3F4AFAF1074DDB24E8A70218C83DA835CC97F6C55B6FC10C199BC9EE1033F6F2890 -FEFC3998D9F2941E350297F56B377A0EB5BA47A8195331A7CF3BFE934A97B88F18A38551 -3EA97201C200B5419E83D8AE47D6D6F3E864CFCA8A874DEEA5CADECD31CECFD46771E9FA -7B24F3509E6B0B04F8C4C1C8E27DB0F2F9E0A422988B2D525670841C73E5D11F4B1DF7AE -9AE2D8A3B5C354446C86862C687A3C21CA35FF2E962FB591310B8C0213A914278B65C7C2 -83E1CC558F6091BF4B159428BA249CDC3395D72E1D5E998C88F379A5C0DBFFE5833349FD -5C61034AC1EEA717B26646D9024C3D8763F3B33E60A5BADFB514937B9AEA89009F5F6779 -8D5D92AB0CB3D57FB123DD852BA04E3C0AE9D8021F0735B69289822FE2727140AD5B911E -376B13EAFACC44BB0F0A8DB9079DF3F3720779B5BF1C02CE47463281F6E496AB7695291F -26C2E02A026A104C8EC76E0DE5D7272A3B83A947E3568DD72E8B2DA7869D1FF74F6E6C0C -70CF5EB3D5D650498D267117C37DD3FB5870C84FB972E5C52DC3E0CCE6FA398D4807F1ED -F253D014AFFE0C5EF86A8E431D1EB82D6D223809BCEA39DAF9AC1CD37243CF73E0635BB6 -6B8887C9C2B2C740F8373237B52A89E589D811C40C5170A7B7ADC6C5643F76C4D5031862 -961B7E211127BD0F716CAC04C4F8D8D0958FCF4D420947354D495BAB0C0D2D76030FA004 -910DC71A861857B1B073C6CC56691822B8749EC78741ED8EB2FE26F37E1F9A3B36947EAD -661BA045810DAE798DAB615C0FA2B242209D8EE04BA06A78FDA985402076CB3A893E5364 -2C998BBA5F530C8944EEBCCF46B9BA42AA25E0D859953A948E85A8022C68EBD496553B68 -2555030C9336F53FE11C84168F19533F5AA4BA9C94FD120491D55C1D3FAB459F80F70034 -48F1AAAD448969D1DDC31D65619CD33070EC9BBF9B4A53C180015AB0D807744FB32AC68A -DFD7986E082D57C22EAD0C5352E86911E8088BF50E5F9E1D70241959CD3C18145B258B50 -261CC153E7CAB9BD1E723209024540E123C2333D5A5C4C45ACA1358790816CC30F3D9BBD -8453E76263FC425F7C2E41F79B402DD79552BE2C837B3048BD534F90B3AE2CB1F15A559E -C00F1E783101866534B0039C433AF1DEA08C4CBAB477327EB3A56AD0F7AF75CDEE8D96A8 -0BF499251B400B85B4D157DB4E54184AEC11547522A187287E945DBC7E31CE99E8499737 -2675C3059133BAE517DC46AE28E735C72E31B30AAF58CE26BAD1FC878E54A72D0C44F980 -4C9D5D93947A846B01F61AD1325CFA2DE62664F181557BCB92050CD697A26133B06D6C6B -2B2CDF60CE774CC5EF0CE86EA4E4879ECFE1C9B03E3EC73E35D53F5A1DC2AC8105953D02 -277742EE13CC39195503F2F5C8C29CDA7E4D54AD44DF4BAF5006FB9C081A938A5B51EDF0 -A20A005D40125960D589531F23CBA7C55CCF78C72DDBC8E9D84BC2A0C95DC0134FC564CD -B08777FFD70A0EF725693F54E8C46CD77A5B9FDC91E83AD010DBA9802E3E140943706AA9 -2FE69EC2474E61FBFDDECD7FA0641290E709A9145D8ABF5DC42285CD98CEC24BA9A7345E -BAF82D4461F027FD8C609CDC0EFDB7696CDB4116EBB91F0FD74676DD5E5C880CC9531A26 -D0256575BC551C3CB40BC4382B30302AB0B891201F818BFDF6D4BC88DA3E4CCCD97DFA0B -C01A7FD9BF8DAA71C8D18B08E213AA8FC7ED8E3172F80615EB510FCD5AC5D508047BE71E -5C0E2F8E200E2BB4A8BD0C4ACE1D5CDFBBF09C74516F09AD40BB4DCB48310BD33D28B81F -B6D0D04144E925C43A7CEE48D7772344EEBCF29D226ACACF8E693C74A0C11DA4177FB477 -6148575C305615CC381612776C6C6ADF8A92408F434717F365CD54EC0507D77032A1EEB6 -6478EC198AAE86D1DD2719CB3AB7A34757C07DAC27ED8A2EE44C55EB3F7074DBC98738E6 -175EBE6393151DF9EEBFFA3B8F5CACE947311B9CAA3C9BD0FB3B359EB30A910D2128D437 -E9216956AE6574F55D25E0E5D8A8E0C96293CBE723960A373ECE00A392D78456EFD6E287 -D57562DB3BC3D2A7E767ABEA1D7231C4888B7F7DA7DB7ADF3EDDA0815CFF72C4A40E6CB1 -2D55239788BCDC55F9F4FA9772782128F15E16E71F33F6C5B75BE8DEF23D8B4E0DFD8173 -879DB3411147841801D556A6390538919D7D2608F5140F564EADF2DC08DF0AD03F8C126F -FC49829551BFBF7EF652359414F56CBB309705B39D719A5DACD7401D6AB251FCC278936F -5A0DAE9A899AB62B9A33FCF22092DA0984A4BBC5C90C6F0448D48BF510E9FC8C9B67C447 -1271E9ABCCBB65A4D92DD146C910AC34752CE16939378F0030039D7DC4187B66257475C6 -AB2E3883693090DF350A42D3ABEDE7E84B3EE9187FF09775889B28DF0C1F289AA28E9EFC -ECE418B40D7AE3EBDA065B2C1B0AFEC58B67199E52E33FA3A305708BE5A2B5C88795617C -DA1EF1314095D09920B6EAC7FFE58978DEDDA2F17E598278DA325949A4C14C5C0EB76029 -1E325DA7F4DD83F453B6DC912C790EEFF754F69B308DAE37ED42DEE308EFE13437599F15 -406532D885197F621DD87FEEFFBC70BD47AB8FA0FAE972242FBA4F7A7F09D01628F87645 -1D3A6B885B11F74B42C8FDE4DC02F0E677F0A7132B751720464BC97DE5BD08EE4170E7F5 -036BEEF0824340EAB34A358635B8279825717994AE76928D15502BBAC200294388F53B1B -C01EDEBC38390B986B27E68AEF3C05883E851BF71A6EC8A3DA59A3767D40005DD98704CB -EE22059B92062B96273D77BA9BCDC6D856102AC322CED73033E6E86DE0CF2B015570C46F -9BB93DD4979472A4BB5DF56ACA2F9636B6A11253421FA471BB93A5561874B43C99BC2EDF -333511242334B62A0BD58E9161260561B9CB3CED25518A3CF7691ABFA61980BD4E5B6FA0 -7ABB135421400F7086EB0C4FF44E220A7FE7D92A159BFC63E4D01700E719D56BB6F440E4 -142852FFBE5ECC6B6A1A66D20C7F07A5AE5909685A3A71922C7AB0D1C18A27BB6E6044CB -B8D2C5A86785378EF5CC4167479142722523E12132F03E5D408F69CDAAFA5C55FB6E8AF5 -8EFB0D41B8448A2E30C66C99B5524AF66BC0F8C5BDEF2B8F0877C5E316ADE6BF0FC19DDA -AF9F915CF3119AED62D21C33DCE3F7EFAFF5A7B0CDC005CE387D4B16C6030F751DF94863 -99BC7E769FAF52EAD494C8154AF2CA80A6982C7F5B2206D9D4B39B6E61956ADFC144723F -99BA540F0C9D1DE18921A04A3206DECFF8D04C727FC9E88DEA9C056E2179B22AD2607017 -9A901B66146D0951DDFD1B9E384EB181D7945A4F83F2A06EB41A2459903FB0AC43CBCA77 -1F62A2E9727007042980C7FF98F349CE0CDCFF6F3447C3AF2712CA82D6828DB71C48A1EE -E331572A4591BD9D3FA077E2F29D0DCF9C68CFE2B6A71FBAFB0E02C241582E09E3C848B2 -CB8AB75D633C42598FA07F85D5EC3F577079CF2F0E68162E66D83176EF3B23291D741AA5 -77D747220835A8B966049F3AA22CFC0D6B1F55EBB917EF80B50487FF81BA7ADDB90CC430 -CAD43AD6199CF4CDE68193659F7E4860F259EB99B56C0E62390597DE3E05983AD165982B -E8305FF7E77363A9CE624FBC98626C21F6723F61352E036656B96277E783D4E6BD0EDF58 -5611C8D7BB3132B9E7C21B65B6EC5E3BF908677F6A5C5DD76BB16CDE31232CF2DD3F437B -BCBA6901A99D9692EF82FF0F8CDF49DAB5A947DC27007F604C3D2CA84455F9F30A75BA00 -71B9C36D21B4080D1C9CD31712527B8A6B5D6C39C29690E92E036D49E186D640E2F45673 -789BE4F96524657EC01BBF37F792212AC8688FCB572D26D10ECB727A316DD79CAD673E6D -2897D77D5EA7723E541C0BD23F4CD3DC2A5B9E2EFA15A024E825CDCC81CCB5B588CE4B18 -1D6E90D3EC7CCD947D371B98CC18A30C33E90EB7A5C180A6D500758CADE6787D5E89779A -067C2DEC491D78466EFC113586C71C5B7E2697685BF5AF1C6806BD2FD63DD7A5202F3C50 -93EC7D2C129E0C3A8CC8950CCB2901894B1233AB3F71CA25E34BED65930899A695EBBC51 -2F28FE435C99ACDB6CFBF1836CFC762BA9FEF40EC118CA6B8ED46BBF94082D4CB52FA712 -397BC0C630D77283AF633364F319FBCCDF6756304CB60B8A14AC86F62AC180AADBCAC4E0 -077C3299BD7486A05378F35430E5E1FB84A01A7C4A0B48DCD72BA02699B8087B5858C7FD -A52A85F08BD02409CE14EF70619E0D344612BA9971C830A0FA719F6EA5F3ADDB460C1430 -4A987565651FC9D13B307E48B7BDD9EC6CE1459E6062C2267D20D5D17992A4B84027B410 -36DDBAA9670152215FA62B5054356BDFFFA7F623EDDFE2BB20A935AED52A2EC844973BB6 -BEB38FBD1D4B21B9D802569D6255049FD9175DAFB66E7FB6E30170D872BDD64BAA1B16FE -81AC65EE9053D339A0C009DC5364D958ABF3E87D38A4E9ADCE9037BF4FC62E8D3D1812EA -8028CCA0852526736660713DA8E3B4C0CF2940659E8BB23F3B553D4FCD40EDE971697C27 -E41F2A6C0C29139B2209D091003326D69A2F081AC4B7F61BE46AC6662574D463DB86338F -40BC2640EF0CAC42C1DEE896C41DC6DC5A86B1A0E5CED10D826660947B11AA1E9AA44692 -E63082D4527C7CF7ABCD388E7ADC0C1EA3E4845469B19505F5E5FD66B65C50F9AB02BBAA -73B8EAB789D7F226365500A2E9ECD9A220BE7BE3D04635E9C95CC1196749F6B07151AD92 -12ECA4122683808000AD54E24730571C9BACE4A563029DB9B921CFD536954CE064DA5D1B -B49D74C55D08B1753124965A402A52188F44A14D9C28449C665266E999D7605E719175C7 -6070B3A4A28B6ED3513322386B2B65689A4B65788A6BD0A869468B4F3544C6E6E6ECE246 -506B988CC39625ED5148E0F620482A198DFD8CDDECC485F003B7A752B1B46B00DE60FE76 -D86911A37A0C26EE72968C5783CDB1744192EFD434CE8BF0B1C45DCF7226F120E85C800D -0C97EFC7159B9CC14EE505042F371750E32F98485337BB26D4BB702BEDA217CAF9F0863D -733B2406270DA91A556BEA4D620A8155258DB0DC3C11EBCE82561957B2AC8204DDA993E7 -58CCEFA6989442B696635B7D29AAAE8E14396E72F838E305E79F25B5AD19D4310A368419 -E3F773930F2D6BAF2C8DAC2F2C7F3420594BD9E1AC2D6CD7A185F7F673984ED76D18B836 -388084525C12BAB5BFA4844121E86E4C747B283ACA5C61E672679AE73940CB44ACB61CD7 -18DC458AA1CFB314A0769445D0D06EBA26549A4EE1AF27005D27ADDADE65EF1FC6EE7BDC -CFA6881D20F2B22972FC4357BF445008069FC6AE550B2D9BA16D565667364E1800167E33 -0A36ED921DDF850A3F993F0B00B1C378004CB008A631D30FD498D676AC38783DE7103FE4 -F314BA9168C19B0FC49363EE43704A9A119B360B5203EDAA03E7DEE736D7E6E94CB80CA6 -42C856E2AF8D68315141E7E9E9F63B48A9F3AEE965F0B62483F3C5AF47CF61DC4EEDBAA9 -F70846E660A7FED078BD46445CE45ED58C63AC224AAC16885D3F4E3F94F0779E180693E8 -B4A15469CEB06D6ADBC5DEFD221406A8C48B95A72303F54DA54B745B504DFC5F522CE50A -EDC0D27842FDE517791D8389ABF07F352EA4A752D4DB20B50CDEF5CEF9C6C8EF510FEE9B -F1737412D9CDE528A66B37A4BB9272BF9C8292BAC9EC2F66E730C3D038E981638C503993 -FF43DDA2C59AD94337CA7B45FE8C270334D4B330682344E372B08A09BF9AFCA47B68656C -1428369C660EFF4392C79DA407B29373D09D4EA1157A8A8D1D81D38034DE3E7272DB3525 -4547B81EA3B0E2C89E60992C4E95D17968EEFA64BF116B4A9A2C0C0B242DF6A571CCBBB7 -6A58E80D84D48D18C5B2F75CA84A7B7AACAEB5548F2A13D95C8918C4EA6C8087F866DF76 -46538BDCF0B13A918A64E00AEDC53F222D8BA4AA75D90121FC69AA03E8B07E1FD92A67B5 -02B9BC301225181043E987D5930FC2E3C77553BE300959CD767FF441D019828837680A8D -DBAE996F1B3739EEBCA8CAE9AEDCE3E3784EDDCFA86EC38BD460F979CFF0347BBBD36DEA -F8DB645DC277536BF8F1BA745EB4A2127CA7B71253C6539A31299156F12E07E5C9591C45 -0C0E804503F8F4520C9FA55A490F6C827004FE2413123851B780FF78743B72C9E1499B81 -77773A6788D1101D8551E12C46BFAAC185F7B6C9916796B3A351DBACF4A69A515EA1F765 -67B5A62DD9D6FBDC9574F8CC8DD20EC6AF803477B8C78497EA757DB04EEDB5F3522B1CF2 -E4EDCF923B14A6E4AAC3413D841EB5ECBA4116CE6549E55BDCA1DA667AE75F9626998ECB -5D82C4D207BF45C16A728847E952E8200194A04288336F8FC2AAD5FEDD5D17287B77882C -42E5F956B9DEEFD55ECDD8354C0CA47BC0164B2294C4B2DED139084B4C1213B74CF02E17 -C4B43FFC034A2051CFAE1CF99D72492C567A750C704AB26AEEAD7A06D3D98616FDB0C0E3 -34D99387EBB43874FC89A225720BDFE02090EFFF13CAA7EAD31827B6DE1E98E450DAADD1 -515D7A65B28AF7057C7B26720025A8918D1A6810F2147D64230FF7925FB42A7AE373C210 -5C99311C02EA1B33361D538B7742BC02B68E238BB4B62A4785B27F071D3F1AF43BEDEE81 -F7717E213F352B861562C314EA8E03B8EDF986E488A1664547CFE7A59DB4B657FAFD0DAE -15ED435D89355108E44135142B60C2FFBEDF32F28DF01F02F2DE4C3C40E95CB0D8D64E23 -672A423743DDBDD3AED5E910E634C9BAA69C8F6B33C8D0DEBF5FA56D7E6D51E7EC3A8DE7 -14DA3A104DDF5FBF10EEFDF85520ED2B71F11EB46ED74F70BA58146EF447CF88E92D99BF -681D3DC3DB4AD32D0915FD7C458D3AE35A060C59FD3A8B0B7E99A3A7F8978CBF381A6235 -D7534A4D11472936DBFDCD33844B8E36205089FABA95BDADBB0B55F9C8814E5F283413A7 -08CC3D15F487E170DD7DFE8C471FE85C06383D444F65298EBA6FC3761D7F8D6F18916A16 -EA794043EFFCB72B5837672E8999904EEA79EBE0D3464CB48E9AEDCDDD2FD9CF7C111C57 -2C280A48DC5B83052ABEF370DC98EDB610EA5E43C5A9A8BBFCF10917003E4E25943534A0 -E4D281F2CF61C6E7C0C10AAEBF23B7CAB563CE25555B82462A71A2D0C511390117AFC3D9 -3C948C1F37F052C17EC23E87B3B43B4E874A723DBD01DC97602F498A1993D8E6A5AF7426 -9E487DF83C45F7F9DE891963DDC7099951AD3E59AC9E5586AFB026A66E6FF8B3A9DDBC51 -79E697BA2B46BC285AD67722E8087F813B774AA31E66BBD187AD9876315619C33138DA8D -834BC729A8948E617CD7A4B802D0F7FB484807D09CD337097462B9690533562506B7DC80 -7CE404B4A1C2899535B13540A75DD666E1ED18CF75D95A3FEB472B7A596A007455682108 -01948D18DF7E008D8086552D5F472341BEC1A3E2856B445C0099339B9FE2ACDCBFF172FC -5BFA8A63067E9EAF13AC8D6F0FEAB24FF4E326A252BAE6F48175927E7D45F2A84CCC0AAA -1400A922DFBB601E2129A649464C417901D7EE4B66B91A6DF5B787F9B6B758E2DDF58724 -37F4658116E04EFACCADA54863E874F314AC25C4D10858A2EAF9687A4C45AAFB755251B0 -E2A298855AA83D44F254C832073A4E065694BF538C63CCC8CB0C3AE89663E24906614A15 -2DB4E4EC5FCB83A229285C1CE0B52954FB21A166142D8F82B60997DD39ABEDB4D3A8680B -8BED2755297909B1D66724FF4B556FE99D26C655F7BF055A529562F4B1DFD7A16166CF1F -75606228E96A320CAD4C2589BC86C4940FE50CDFE12BD5EB50A5A2B0223A6358FE07FCD6 -C791193E83A8B66766BA2F2E3D15E3275C27ADF65E2088D058082ACD6B7AA272B26967F1 -7606DA71E7CA51EBF5662FB025419DC26D155113947B966933287A14F066AC40D7028A08 -07130DA33A7DFA24144A05BFFB1D979252E83F21A493F7149C33D7508523CD56C09F3963 -322C64BC63B8CCCD8FE84E0DB44917107B6567579983BE44F73C9E524F44956C93D85975 -E4531A3DC0FA9CDB9916DA0432E4EF9C48FC9FC482BC9744F6D818889C4B5D0B766D2243 -B50B9EA3F0D20DE6A86F7D0C0F4B58E3B526C2DD36E01BCBC6EB8364B15909C335D8FCA4 -7845F72F203AE4FE8F9D0FD1F1364DEBF7EF7CB08D6BFA764A7E79B9D76A412D879D2709 -0F4D54A848C5EFD424C553A5CE0486D29AC6F2C6B372DFE8DF265097F184F2B88CB3C690 -052719F268460D78153B97D77F824C82B466DAFF2630CB263115406B8B91C9FE8E9AE54C -A2C96C85789610964525453B9D902ACFE6EB379887C72B472189B9E7CD6033F2E57E9C90 -206E218B9834ED77760A12FA0A5A6F86D2C226E1DDA31A5CF2D0EFBC4AA20242D662A869 -CC6A8C5E4B3732A9985A2BC6DEF9A1FE49309CF5557695B66955CBC49938FF605AB6F57D -CC7D570CC84A8F10C50D2DEC2BF6746CA9F256725BA75D273325E24D04AAF0F2DD9AA3F5 -F282773B5CB4B5DB26ABE691245BE7A3FF07C4AF6817725B03419F1B72068A5EA81870C9 -93E040F4BC52C454FD43AC24E3A7B909582F2AB3584FA66031EABC8CEEDB7DE30D3FA311 -A41DAC1CC909AEA330FCFA89BEF8D0D5217172BE25BCB3DC180DAAC52B9A95E588ABEE17 -105E3DA435AD2698CF07035DD5C19C8DCD58480CCD20C1FF529D37B5BF95716DD5B36F74 -B58FE28847962E7C3E2ADD93C91B529C48233EADBC2668AF421CEAFC5D8C65DFCB6493E0 -5A86E7A5CDAC1CB839DF0E099E67A2F8A7CB966BE497C573A5506AB4944AF2FD770F5834 -ED14B897BBAD1F3218007AB429C3250F7EB284AA16149DE1E6B6B540B5AEC33C4BE0A12A -11C3D63B8574C6B2B4155629FC9C13EFADB572BF35C2939226A90310A067B4F47A8719B6 -63035EC0FA87AB6FE5515F1B1419C12F06BF3D49393481B7F45534B71FED5E1B8F8B6480 -28AED0652F5C7FC254C25858EDCC0B92C6E6145A8DECF4CC54C822A6EA80F62122A58FD3 -1BFC6FBD5DE46F258D4215FC361C0B8BA50E3D63E7423EBD6EBDEF07696D25A6FB25F44A -5D747225006F4AEEE6EC177CEAC8DDB0A7D9F536BC69B59A5AC650AF57F92798785D44E5 -79EE905CB999C568B7DB553BD63184F22E59FFBE661535B35770A1EFB0F6530B455DFC54 -1A4CA7E19136D9F3ED1A7C8F58752296CF5232C45902E6129AF4380E677A74D06E2A3A01 -9C72A32A8555E52F5113112FBC4A2A42BCE68F7F5484D650CD206B0787C1875E7BF15183 -3FCE25FFA474F67497605D6C6517BFF948E873E4AC2BDB6995045E489D6310C22F6B4582 -906FB0A5484C4BBCE8FA61D80E4277EF0D37D09B869C0A174B97BB3E127776A0FFA4D941 -B0BC194C78F189369E13D86645749416506452668810DFB0B4011A40E60CBF7CFA855CA0 -F36C517B959FD11587B9C6C6EDA0FA01FEBDA786B36F3E21948F878D6DCAFA94E10509FF -5F8DDF25EEE7CB8E058F0BE6FB4DA87C28F225763AEB26BA7BFD8A52467F096A759F4379 -C150E63BBE70940EBD573424ED3559B16F83D22068E16633D95A0267E18EF9391B9199B5 -80A91B7A74BBF60CF13E4EF71AD3FFF9ED5604D73BD0C5A15812A439A3FE6641F2DE8B52 -EF0BC70B7693FEA9CA49F93525D29B037AA40A33FC2199C3F29139FA63408048F29B7F3C -6EB0CCEAF6C51D4AD842A315257AEFFEE6D5A02C9A56A144B0AB2837402ECDFE10B85F84 -88A87D9512E0FDA5CA64AB541E1BE99C9B89EFE7D3F17874F7593FDFBDE867653562CFA9 -C06BC81560883D1F051CFB128310229768A77E87DAD9A45810446E4E116341AAA3D4B332 -68322B7DC8984E41EAA6826393C2319424202AFF4928CEFDC24D7EFF4B64533FBC25164C -E0083FC7DBF81E663C4E1746A7A7E4D7C0EC4CB4D9FD396508D6A96CD400C85212F522CA -F4F6290CC2843E2B632571FAE0ADFD99A7E3F9831B0EE07340BF0C7D6EDF95DEDAD7D492 -DCD83D871ECE63ADC0A50C3E76E5157D3872E0F78E036B3A36459E78484C9307B3DCB831 -A99D9411C1CF4EAE117D651BE3BC04C2AB067E512F0F89A566F275DBBEB231DB42A0A197 -C301F33F4E65EFDDAEF015999BBC1FB75E1F6A7925D3E2075E98E314BCC10C94877F0B0A -007708984B326817A532F7AAE87E026AA715FE64373BBEBAE99A0F83CD0C77173DB845C1 -028F25015FC3DA0488676715D3EC8D1149A90AE16F418218404CC465D4EE8BEDEEE36F47 -DFDC27D07FB5F4EC0BB8DB4601DCFD54A2BE85A9476000D20181311F5B6F4111CFE1A850 -DAC7C23D30B674627F1A852FAC1F0437D18E6B3CE4FC7911FE7255390E0739D2A83DEAC7 -02185389034889A8A437BF74BFC3A5BA6BB8735A8FEC009D55492F7D43C5C6F92E469260 -4723A88723FD31B20AFBD42C150EE51108B05E8F7027ED40735A1D63931FD3CD5833FA1E -C77980CFA0F7A8C47164639255AD00AEC0764BAEB2045025B7C6536309CC9A38291A1F6C -141D1A42F33BAF14C5844C13E8AFF8A7CB4AEC72E6039A60CC67F03DB21AAF2976BDA0A3 -9D92A848D743DAAA36C288ECBDFB46D53E958762B1FD0F570F40154838506B656A081473 -18FF01FFBE5D17C131949F5489E4C74EED3369A496D05E0C9256EE92D3424E95A30485F9 -A00B0595FDBF84B03BC9672A4816D2D290AD1DF00E54C668DFE765D9EC28815477D7FB69 -781C0A050660946AB8AB1E29EE5ECB2C1A272591CC48EDBB5EBF26D765E24F5CF4BF43ED -17E5BBB55C55DAF106C46E4D8241E4AA01AF7CCF79176FB4BEE78D5299C313E2DC300237 -D1E149743E16081CF124BBCD7D9325125C9C9AAD57E86A94D18CF62D4E0785F820A9B7F9 -E3AE3FAF0F7DB0262BE9BA917540B8CD3421643A01CB26F81555B05DA466F1136A7F3E80 -3461C2F063ABF750BC814579689D3CAA094035CA96298F7F264C6546143DA15C6E085DB5 -2065E8ECACDEB3ED4FC0D1AA4B01E3ED36211DE438DD1B3712EC858D66BD3779C96D4994 -234A8FD8C1340CA9EA51A2750A6B0C65EE1C54C321F4D060F7F5F07B49C9528AE0A1D45B -5549FD72B0A15BF903B1F70B92458817DB0FD9F1731E82885835A717B0A1304BC067338B -1638D51E99D5C23872D4CE5097B89635C3BF28D6D2FC96BBD80C26BEA1968B8A59C278A9 -8BA49B1E59E3584E54DA5998C5E70AF167DAE2710F7656169647D2781AD1C27766703FC9 -6C08A0739EC521182A77410F2E2A788B47C745B4B0A2313F49AC8802EA461F04F3D54FE5 -58D2B21E9348C19FF519939154AA3ED07E24D3C15971F380551408C897D618749CB38BAF -625434B73061407AC05E0D7B0885791153FC0AD5C3275C03F528FCEA3BE91D9CA9C3B402 -3C931D467854D68DDBC0FBAF70D38365C0C76344472A876E74C04CEA12DAB0A55E776BAB -CAEEFE1CB7E834BEE48DBC155599C4A0BC00E6B8746D7D0B9CDBABC463D8E2688F46F126 -520ACADDFAE65101EDA0F523C6B9503D8FD1A5B9F0B6DBF0C286358D92FDE66720F5AF47 -CA87A0B6E04E46BFBF21EBD5CDEA194B6425B5ECF81518178E0259E386F5F852C6870E7E -034582EC658F59C2E07428737B36B77B9AD3BD6D28EB1742453C5D4867FE879805A80331 -C6E52C0557E5D036DB1EE67E7274AF769DEBEB23121AD503E3023A8515FD5ADEA11AA020 -2BCFE0AE826A09874CCE19AD2A2A188C7331127751342E542258D3996DABBA1B6DF80323 -5B6A223DE4F193B862224F807F99C0749994F0C72CC784AF11C411D34D649FDA1C77CB0D -BE519001F9E757BD8035A0C9AEA86609B71A4622D5C78589502CD2DD58709544A76526F1 -603F205AACDCB62EEF46D9042A2C9E76B887826827C6F22D73760CDCDD0FBEB827BD2E1C -3B5B0726A08DD2AEB614FFFD02C36F9E8B404160C909B70414BC8DE600A5D56479B83015 -9B8E61AADC8C8AA077816ECB6317A9B16D30DD8D4499FFAEE87CE97F72453A37D187D91F -A0C29A65A8F9C88ED22CF19CC0B40324449CA4E7751D77A0D76669AD420216EBDA92CFFC -50454E7EDDC5C4DAF66B67675B576ED2C90EDD9F8182589ACEF1B034D2F848D0CBFAF84E -38B7C42D2670D0A5E382FA11AD3F2FD6BC79EA02C074644F35842D1DAEF70507A361A0DA -03F5517B789C5684461F698F2FB20A7801CA9EE12981B5A793A481F48E33B596832AE4EB -7AF3681CC464F6895127CF10D14477611CF8AA88D0F6888225DBE342A708BD62EED4FF31 -CCC1ADB38DAB151C94E9A1554980B3C077683DCC0513ED4C55D57BBBA0ADB8A5E79A1B4A -BE43C703948452C44F1734F1C433797315C644A8E76D13DDF5E0296143F61FAD14E16ADE -97BC12ACC5DDEE482231A9E9145E69D63CFE889A1BEE0907362C60ABF581EA8541E36ECB -30457098E7DA18D6FFD57901AEB7913C59AF691D1A1FD3DF485F7EE669A5915EABA6456F -955F2D2F7D56CE0E349EA743B3F44ED555AAEB7F2A71711E08FB67B9738928AB842F6111 -2B9126C7474753CFB458EBF75D817175179B3FA956F1D998C52FC9CEC7217440889D0481 -CB91C8A8D1D1C6967964C7DCE3D9EB0BE6598DA5708DBDEE4EDF76CE91E128732A8CF56E -C8BA08828E9B270A818F98FABCA757BF3C3855C6DB448F7A4A6853522F7541D46AF3818D -B905D64847078757E0110C0BE6AF4BFF722FBAF5D8A4138BFFF94C7678A10F9FD850998D -B710D5BBF763B8A70491CA4D53124CB95A953B080CC31174646AD474BBF5BDF057A1186D -B083E6E762C669E935A02D60EC62FB71B6990D25BE44E949C85D1582611D826197E8F617 -CF2FC506489E59CB380E2ECA368916347B1E1B59DC1AC765676B904A63D7F8CCB1F7E2B9 -B8290B30E53B28F6FBF55D191BFBCB51F3BDDA71C7A9B1152F686191B0AD05FEDD3FC37D -42AFD7B3021D255DB7A00E6C2B3E714BAF7E61BFE8B7A88BD5B6EDE4C1DCADCC30565AFA -1E2458F35E44CB6F7228BA384CC1B7A64CE912998D42572F45A30B2C4F919BB21F66E1AE -6C787773E419E1AC1AD41A3DDC044C1BEC45CA2D0382A11C1543683F9DE1302FEB0C9DF1 -8BF8B9F0272132E1CFEB54E38A8B90C3F5630A3EF083C73C4E83BF0C312F09D5352F41CA -7C8EBF842E7F46F3D97C4AB03040640B95D465D50789EFD68A12F1A450AF35844A7A2302 -3F25728A85EEA2D9D124C4B04AFA44205E110CF923A4D713552FFAEDAECFED8898AFF89D -BB682A961D1F815C3F978B9C190006959D4330D772C884F6B0C77B2D1FF722DD86448C76 -A68AF642A08994966D3C2836D7063A59B168AABF47179CDD6D6F902C601A89FEF38E5A69 -9753828649B3470B5A03A2B58AA910B758ADCD5739611894DAE786D5AA005A5826DBFE38 -8B0F4105BC76C0437FEE9CA6C861FFB1EEF6620B7562B44AA0D29D1DBFE7B7954971087F -E8D291A0DB5E4CB0512B104EA6044CB75C099716AABCB5EC89B14BD18F5D1A73E9A8DF5C -A593BDA22FA28D8837519C38432667684C7C23594AEA6B39E3A819B72A00652C205B02B6 -F8127CA0C7381B8D433B86E6DDAE2ED9482345792276F4604A9208AD8CABAE8B0A0BD0D2 -7D0D5955C20C6E4425E295F5AF9FCA7DF682FBDD5B8B107B5FDBCBB0D751B2D2BDA99314 -A9CC66F9E92FF5048E5A6AE2B8B03611C7000B0903491DA44123CCBBC67B1D4086C22ACD -08599534BC98EDEE0A73117ED20679CF3D9ED1506774C67526D9AF3DEC36B9FF799479DC -52A70429F79C8878509E8DFB756BDA3D76B31B9BBD77DAD3956B1D951C157F02EDF252E8 -D02AD799A9DED7B38B352FD0841B96DAB3A3562F68178448DD8F1F5FE40438933F97530D -0E6C918C571B921F9F7B054B798CA04426237F4085044F7395D0E4FE3CAB961348D11912 -E5FC311138A82F470FF3C8DF00B1B0563BE81C25AB58E95CC392203F9668BF187DF43482 -BCEA0456394E31DA0819AB3E71FB8E02FDD90E05A39D0D5B4EF919E958B862C3A96A1275 -F66C689964B85C4C60A9E6D44EC9900B85245C8CAC2847882497A97043255228B8C29529 -12EA890FF254BD8C584126DAD1B2AC1AACF528564883F0C15C41A8749EE4AEF5FB514940 -060D3397DDAB08DB2113F942B03375B4A2AAAF9501734C17DC220BC97E367C2160982356 -2ED3C739164B659C480317952AFF044A4550DF79113B4F7FDBEC7B332EDFCAB7DA5B4AA1 -469479B4490EA5462191AD1B336DB782BF7A2CBFD7D4B885E2083110511FDE57459457D6 -68D29B1E31E734B30E4EE6AC28E8D74A2DEDD48BA964776BECDED8A86934A88D60A85279 -9E9C65EE342F2555ACCC0E47202CE451274D76C6FAA943BDDB5C35855499141FA589F452 -C5F424280D5863C7ED7544701C4B0660AC835D58905E458947DC5C220540D1FEBB4F18BF -7649596ED3C3F8D76CD146E5B5995F406CDC2F8D1D0D7CD4FD1BFF5907BBA5AD0B475F85 -D4C75829E57476F12E1315742C875008A96A06A76627DD694E1EFC09D05159B101C8613B -F0FA5E027B1C7F089D07B48BAFB047E4A75B101B417F82FF32BAAB877D7798A2DFA48A40 -85C47A5DA67FF503552D60295D5C61803C2700879C685494886505DB291413B22C7CDD3E -9C36F74A88E53FD9AE6E4AD73025C80555094DD7D1A171A1F85833A390793DCC86DC25B3 -1BF605ED87669F1D4D44FE035636746A80865E4320BAB50B42B6A6037B1A7134AA8B42F6 -4A85B58C318E600D80E892B337786190C009CDA82D95786A6F723408E1F79C330221E753 -F1A30D90450D9FCE6539A7E4B2AD69557746FDE8E4E6207FDC9068C400244A0CBF276F84 -A2286A98A9B4A60457D3C1C2B1FFBEBBA67DA76E0B3D1027B914755CA8152E1CA4542714 -9F709EE182D12B9D653D960F7242567EFE61643037028C97B19D96BE9F5EDA4230A329B2 -78CA496D0C8894CF6FF8A410AA93EBD0F54CDA812CB5935DAC06DC7968F1FD4DA26B621B -CB0C9FDD45A51E5043E501E17A042CC421E80413C5861941796E1F0213C02A968CB5CF10 -EEA25AA24095839B12D6C260D99B5C42B65C40824D408464B30D6F9E02E8686294CEA8A9 -39AF573CFFCAE51DFCF51D229D3753F144CBB1ACFE9253F5E36CB4199CB5768E6E1CE224 -396923C6E1C9B1ACDAD64CE0DF19C102CCBE2F7D206EEE22350016B1DFD13EC06891C41A -353318C8744A912692209F590799C99741F3656DE0110C310E8F460C3B94C7F5EC4598D3 -786D7C297707C6CA9CD9AA80A18141C9937EA927FFD3586CA76ECA5E5335DF22CB4AFBC1 -8DAAA401CA2CB71E1E97BAA78CA4D1AB912028138B9901EEAA6E17263C540958263A509C -1E3C266138BC36DFB2B82E145C794AF0606D7B9724E40BD70E3B83D7B32E32E0BE470279 -C05473C3649009D96F47300ED3668B9F140E65746CEE1DEEE623734F93E1C309B3F5E5BA -EFA93C4E96DDB8E14DB661CC2D23995A845F8916079EB740DF80158A8740C15DE4B367F8 -85B1755C69254BEB14DBDEDA5279C0A4BD93D43B940AC1AB933C20EC96B8B833DAB56BD9 -15C46666D22E72B629E97EB44CD41B441F6E079E40FA868F3D74CE320D23402BED7C4A49 -4468869683DD4BF0C4B59BECAD9706D091FF749B749DFCCADAAA2907457760A7A2269285 -F31D4D815E0AF703CF9A0D671F4637881245B134D4E25A8DFB7E58F7DD06912E6FB27CB4 -1B137208E30C0BF65FC3C078E9AD98BA6A46E3D29F035FB6A430964B84D9CE91A03F6719 -614D8F12760A8EEA1999780E00AD8FEE24095D7FEF3BD669042F0D03010814916A66401A -3183CC41D8EA4423A97EFD187FC1D832146031D4837294C35EE6E1E0E8ABE8F68CEFB5D5 -97C10241B7D8D83F281221F1B84FBA400A586364C58E1B611CE0E2092E0734FA0EA881F4 -2A8E82E9B02C0A5BBB21940EB06554D01940FE87BD2BC7D03032646D583028436B495E6C -A8F58566A946BD076D693177F13DF96B3A43C1650085A23D199A4773C717DE2A19BD8C46 -C0D6487698620D89A1A07FA0205D14870AA43C6ABFA2599A84AB5CDD18A66F6540320B28 -A1A9904402F62213DD74DEF28E2260842BA1F5ECC26C2450352EC67BC2C956C325B1F996 -4051364A7592346F0C28DD2C52BA5123691B47B857284B4862961504778C8B5E06ABD1C6 -F37E2343C185BCB458D42DA166D9479F8E529BFAB0AC782010BE8E526F5E4C17BF9A6BDA -F8BD46522BB6A877C54ECCE890C389FCC576B605B65C7D17A483FDA2C826A6E8F27915FC -9E006666AD30D11B31AEF6DD8BB9FCEFB655F4D7DB73767FE1FACFE15CEF7FB27C3ACFE3 -4E761F9BACEDC1CDEC22B0F50619FF7AED2689F2EE768CB0BAFB857680B15D9CE8AB0A24 -36450529F86FE3A7CCCCFF0287092F18AD672F424DB6EDFD50AE8EDD481022EA1FFD016E -E3B4BC8583BCFB45436471B5B4340892F390E061E0F28B4019812B0CC299C3D70151F87F -15018D49097A50B1EB5B90A736ECBD060A802A30632C2A681FF14E1ED5AC77726CC1B76D -378180CBEC15DEBD4CA283F2441B1E02CF8CC7D91A212EF2E0B1F194C196D731EF43A420 -2E0A1BAE1C3C1F060688BCEC9C24B07984F8EC84242EF6660E7966DAED4AD845FC859DB0 -71F1EA8C7E9E5235058EC9C42ABB815C699A883344E95504F9C5F6BF340DF54AB9BDD438 -B8D63DEA04CBBCE565E3D78B71C6E2C04D4E1EA83DDB824C8AE8E9CC621CC1C75906F900 -D2152DF36AE9390162C3DDDD20E79F9402FFF7A1D66377037D2A5E8F9E0889F55C711DB6 -38AFACC568A1B4E4EA06E3A3B749DF4026A0EFD2AD56BD458D9A5837F046F81ADB9C1872 -71238A54CDB3290187DB1504008362EFBB553C0167B5B58DDD5DD0788B4806D02AFDACB7 -78DC36578DB5486BFF8FA27ED2705587C3B0A471DC74A47479EF2B7F0D35A77D9683CCCA -F64C5E79F57F96DA3EE6666053089561CC89A0AD22E9DDD5AAE38F6ABDA3476E5BF7EA15 -B4D782E42F6B1E778C9CD33436D1B2B72FE8B01E18E01C6558816D0ADE36FDF34B8D8F2A -A15E028CE59BD9DE568683CFCB8ED3CFA289CDF4525A46BB7B0A91A62491A09821633CE5 -C54994009761A3E6DD30D61612EF66F49E190A2EF1D189D75C9EAEF9CD21E505F9CF63B9 -5B399B25C2808CED1FC3F6BCD950156394711567792045A8C90A10A193650379B5F44F80 -B9D3C265064754B0390963D2A060AAD443CF6C377C6DD81E4B313D94CD22DE546C56CE4F -06FFB5C4D703D1CEB9E9957ACDA546D0B327450F212252B3686FA87442CA18B2B0D2C1E0 -F91CCD54AD769C78D4E719BBC32554B6F486ACC1EFF4C8A3DEC5C359821715C2B64C2CD8 -43D25F4899375AD2011C3A89914CBEA23970C20ABFC55AC3318BB03FE1B061CC5E1C6BCF -B4E5A9488F08845DC4B03A79CCD15CA393BFF66051555DA32B68BE66DB340662F445782E -EEBEE5CFDB73AE4F9864435B828D168F17B59E9ED6B1E4DBBEBED2075911DFEECF1D97F2 -C57D0D5EB64FCDF7BD4F2F390F0182C997AEA6B3D5C5AB9CA14A3928F6358CCE901D205A -ED5C22BC9838128C8631B69B02787A956865F15EBDB937DFBEBAC70381767AA7EF592146 -BE4EC825A96C8695E9DF2490962D6A9F877E260A19362995C03E00B44DAE22F3E1AFFECC -ECF056319ABDD8009FE30466EAD5BFF178E43BEE8445C0F3A4CFADC000CB29A66736B803 -46E6BBA25CB8EDADED812DE0D7962C2C05A0DAFFE6AE2604F628F823659537651DEE00FF -795ABFB6C2FAA5E2531A36DD12AA069E8E0EAD1C6737FAA3B412F97E6D5DAB28460AB7E8 -160E0656C551452575ED47630A545FDFBB6763F61CC4BE7BD81AFD6861AEF0B34044B583 -836311C2BD2F0A5C74A455962A1991DC75DFF5BD46265C8805FCABE04238795013F09F40 -D2F2F7C5D12F251752D938DC7C9BE00E5F7506E51E0EC4A7AED0FFBE5353DD0A6FC560E8 -3FEEEEAF01316D5386633AE96A5609FBA122684608F90C54E9E3C1700ACD31686FAF7BA4 -84AE837057BB3FBEB1B6C9AEE7412A74C5EC366F682BAE51CA425FB274D17C41D0DA1632 -751E2D58CB0837549DD2296065176FEE15365363284E0F4778575C464110F5CFB186E92C -B488958079B3DDF229F4448C19B24023C1EE9F226EED46316480F01DAE2D4A5EA42A3DB3 -85E3668A3CDFDAAB384BD79DF85A103A8E09561B4E826D3079658295512DDCDB7AC7ED56 -0966855109359E217E44805FB55FCC926CBBD27D34D5D1339D9306CEB6BF3468616AF144 -765C64DBCFA2BE91F92AD7DB47DC92CCB3297AA99593851BBD29C07E7011584945C5F390 -E048B582367C97BEDC1B31BBB1D2D8C038C05DD28E3915D6E35ECA809B335190DAB354AD -3D3EF2A5E3FFC5D8F0F7A87A8EE9C6F9E07154919054DCE87D8FFE62E279CC05A4DA0BD8 -B933A49F7FEFD11E241DC1E4786B73D15FABD2915541B9019AF06EA28A1DB0FC3ADDE1B8 -A370187BC285F66D544A23184D17E346CDD21C0B1ADAD499D78EE0258279A8FBB802EB50 -887CE8290DE6F29AB3F6D0884BF63AC982A21682CCA88BBA82A237F39AC8D1EC827CBB72 -559AF2F5E640B1E43AF7448258469187427A600608E5FFCFB50D3406D453D30B830D0B44 -B7BBDBF0A5F00A33A4BA6429C9D3460BD6DCA861970E123E67CDC85ED1A304FCD0C18B1B -19CA443F0B85423F4EA44E0A31DCD363CF59630319D2ABA44E822902062C4194D1B4A04D -DF98F54946C5769EDEA86028E88DADC98D785521AB79728C029FE0515C9BB6DBDCA26033 -1B28F70CE1445AEDCC0E267903013BA6F98A564E6FB70FAD1343200A4E3AFF261381434F -4C8E3DCC87F1482C99E9E2EFC4A0D7352DAC825045D1CB8E102D9FF018467759C808D863 -55C4D25B3D1097317FDD11BA90BED164B5204A40110751287F19926A82FDC6E8216584CF -CB1B805BA9237ADA8D5BED21A89F6628495EE78DBBEC0163316E7301AAF1315E00302F64 -D22A33EE587C3116003CFBE41718A07DC7CE295DF8D7CDF05245C46893759E0F2DD35507 -CCA29752106D0CF2DBC8CCF6ABA8826EA7B0455585B26DCBCF0F598A7DBA8FBF04879EE1 -82637DB44C1FD37E7A74481A333CBEFE4B413D8AB6A3F4DFFC471A611CC70C55618499B6 -5EF14ABA68839AB4656971DF193FBC70467BEB52171F3E140FF40BA1C77BF02500842784 -4A06AD4F0ADE586113BB339DDA9FA72FD99DA3B1FCD26D25E79B28069013D8FBF48897D5 -2B92448BECA722F486F3EF5C751FD6DFD0560987137C75E466FF9F2002B7CE576A9282B1 -ED5450AF132C858CC092E7CE3CEBF5C78E3DE84D130CB8E1C9A9D08495FA3918969D06A7 -8D10750170BC3ADBB4628BFFAEDB8F47A2197D95DB975DDE5FEB8FD97AAA479AEEC667A4 -8DC0D8D44C02F7B7497A394944AB7094F3396623AE275B60F32AE74A3ED40FAC1B465F26 -6A8FE9162EA850F4DE855DC492315E3DB9390000F84363328D4891009B8F10AB08F1E4FF -DFCD0B78719F59B0FEF3F2D7990F388EAFEB85C6F8383D3E50F3317EDD0B44AB566F798F -F7B1CF7C9CD522350CD1D92E56061D508E66FAB2756999B57075108DC7A0AAB4D77849E1 -00B8B7B5690763983245CE5B96853F7E1E90D5807B02C0E44FB50170AD7AFC8CA8229AD7 -941453154232B97C0CFFB5D710DD5B4AF78146FAEB62DC9E73F72BCD539713B683311ACB -BFBC5533E9800939175CDC5634FEF7D7BD135D6347EE83118C6FECD86799534165E063CA -5461B7AB4002D1972C22665FE8F75B4A6E7CD2D868311ACC98E29AED65A9DD734A55E7D9 -43A4F53D0602F79E2EEFD38BA394581DF5895435A9E8FA35DBF89F3F7E00E09EC5858D12 -6D0993DC87BB9331168488F7B12BA780D07450007F067B824CD0D7F0FCD3EF8D5DABA99E -BFD130AC89B20F0E2BFD4F8256D1B4041F90E3E145DF48A61BBE573394B2E70CF92F274F -4639A6910E6E6945DA69476BA89E1CE00241213B739E1C9A0A9B352DE885B04A47B10BFA -4A040533606F2585F78DAC66EA103984E5484A06D583AEE68BD0D8415B0F6CE4505E571F -3A21899D8CE43837035AECF430D1AB85A8AB0080BB31D421FC1818C32CC591417CBB595A -7FB281122ACC1742E7A7B6807AE5AF3F98C94B85ABC8FE8482F5CD9F7A0A18DA819D2A8E -A1841FB1255E3F4DCD1FC2BD3E182A45AFF9E888D7B3D49F4C5272722BF9CFBA654CEE4B -09C0C9897B4495BB6D38B00F0E4CF7891D61CE6542FD8F84C2590C62C47E967790F812E5 -D0DC81571ED64FB311336B154421EDCE032F253098D7360F2079719047F9A47F2AE63CA8 -DFBF90423BCC6630F75CA70936096BBB9719034946F340464563DCA8ED94EAC3837C497A -50315ABFF0CEDC6CB3B7B1C30A8442648734645999BA94AB7EAA67798AB5407CB484344B -86204DBB56D3627091D3709FAAE6CA20AB5733F556C40059E56B42DAF823CD0F5139B240 -7CB44AF4DDC58EB2499525536E01363B4E1A36331838E88C6F0BCF423F70DAA9ED12B5FC -98C606C301616A1DCE9DAB545FA0ECDD8B967DFD1C1F096D242CB1368A7075BF72E12B91 -A953923276693A46023276B9BCD24108A524C40026E305427EFBA8D9A8C87D1AEEEA0AA9 -F4BD27476FACEB36ACE046FD8A5AFE4123B6944DA5E7BBE7C4F608EB0DA74DF816ED7453 -6DD277F8E59F65AEA8541DA98E492DFD48504D645345E957129E2A60FC5BAB29BFFE74E6 -4D66EF0BEBA0B02A78BDFF4CDA36A04C20AD552AA92BB75D52A78745C7B47F7D399C17FD -C56C1588083E04035263D46D90144165184F0E630A4FB68874E4C715A3708E84A8C08142 -988557DE1FE684AEA24BED59A1AF602A04F7E916FECB96D2D2149E71642AAFE15B0E399D -3C66A5944B4B0BA234670AE5D78380041161A606B33BD1B38D9F53A592D3C021F6636731 -6110C7E4DF35E8BB85F649E568ADFF1736A1B27E5B13AFF8C4504230D877FDE932AEFC2F -F9E0BFC61BFA1541A6F2C6F53A22311DBA8A8067D67EC1A240E27F85FC0D46C4DD2F519D -7B72897EA5B38704848B4834AE19C7BD5E19E5C65BE109EB9B02CB0376E603B1B6BD18A3 -CF63B906F8BA66BB52B1BCAAFE70BD7A2A184424DC53C91582F47173486998947B074A87 -B49FB5148B6FF3FB34FCCD25CF2940042E7E90EF0E9DA4B520F123CFDABD3B3CD2DD8CA8 -039F6CB5E379D17FF8C3E7F9F597A25201332F0062A0E6A06CA14750DA000B4570B4B3D4 -859038CCA94E63854AD5DF2AEB672F92D99F6E5B03A8A174D64695141A12F8D6E0BAD839 -D104B24B2B02F83B30910AAE4978C9558D256F12A120EFCC8BBC9FE8122DA3BB72C7A77A -F47200C9C18DC6560B9D3B82AACB581A4F3735B4D2D215CCA7046DFCB3468917E96B6A67 -865B57BD51428A0221225C3A79D3D129B52497ED727331C1924340B127752929C29EEF01 -677C812CC6AEFCBFF1E3D24594D430E0164B6B933EC66A7FD00B4E701657F6766A186BCB -872F32AB18CEEBD3E14574AA775B3A73B3BA7BE94916FEA42716105E6326C21A59B62AD1 -681A9672934A3EE224B4E634B6B4DA3EF82969768B243092A98BCEAD10097659B9264DC7 -E83CA911201CF43984F4384DDD10F5E7741F78F3013591AE7541965489C0CE0B2C78228E -2148182930C04ACA997CB303C5C096147E25E0773262E62A8FBB81351EE809D416F63B48 -615E95245EFAE2FE041D10F0755A3FBED883200C13537A1FC5B1CA14BB847C8BA1049B6F -7CFD9784512E4D2582198F8594B4B689772DAA8EC2AC7969E3B20DAF8A17D36C91F1A5E7 -4FA921F611BFEE1982F590D8BC0613CA86B0338CA0F5FA6107B9CABEE94D143C98DAC455 -F64B2D213C5F3CE2F7430673D5E2224765ED4341D8FD04864F8861369ABE41DB25207682 -C81BFE06C3513FA019456A976CD751B29F4E65C7853DC7E5AA99539926284A316DAAC56F -64767BC4BEDACCE77C7D8C774F0896034ECF9B9E418203D94B94018D126ED69E431D792B -89FAD0AD799A0660B1282C226C03EA2E2EAD24432912D2D405A7A5130525AB9A4C6BE1B3 -CCF9094EE61401F04BAE9CDE3CFB0A0A1D33054F993EF6A6A8F1E026E744F19F19F8DD45 -01199F97E79F711C1C219532B448CCEDB409AA0EA129135C1791AF1BE7FECC1C9B1D89E0 -906EC96620278EF044C18228F5CBB67DBB36C7BD10DA5378224949CB6B2EDFAC66404F22 -42AF5508383B90080331ED71451BB59A8A2B91E05365884DDA3A23C9BA8A043C9A5E399E -5A4350138459B562729D850CAF38D18C4DD8B6F9D8D69402099C0791C82FD8F1937B1F8B -05E3D4E22DF453D2E8CE4248BB5A61CAC9E36908DD9049CA1EAA4E7773D54F9BF82D4447 -010C37DC6CB5A199B0BCA9AA3743592E651B69D1D4BD2563135944545A1DD8CA0B1928A4 -93361DEE737C834868A6CC2B6BA3A44E198D1EC12123BB95103C8699B4B76D7062ECADF3 -13FC6AFB6D364ACEE2091991D4045CA2A5E33C7BBFC82149C437FC423ABDEDD7E4BCA0F7 -BD1ACA371A129F11735758E0E88F453DB813998F91CDC3428B5D8FFDBAC983213F9C35C9 -C6B5B1DA85C0F0FF0089BFFE9269AA245A8F8BA47E373D2AEAF9F492835B1A3B3AD9AD49 -076B2DA90C516B95C8D603B758D285B811C97A3B28BD0DFD924F4F4A6C6B1C1E0F7E51EB -582914400A9B2610D008D43D9623BFA18A64B6160A72606CEF0A31DF88C7ECB3327A0F48 -3B0DBF54F1A02BD3DF36AADE1A65D4ABBCFC72149DA3992CFBF54D1DA3DAC66DB428DF19 -90F4C7923A23EFAB36FEA4B00661289D7FB382ACFBB03C6C82B58A46701FB75E36E1C697 -7026DF6B66554C2C36397230657BFF069FD03DFF9128A2240EBE1B838512F48F1482991D -E0AD6B6590DDB2052564F6798C1BB88C06D53C4D4C76A4BB1C35355468B3C71547D76010 -C8902F5DF9C07A43E99230DA6CC708BEEF6D3E976C07404DE4A1C7BBF11CEAD519AA6006 -EEFD89D2CC4351FC3E72415E8965B1785AD0E29EE59032F6D0487941940FD8EB73B9CE70 -704AE65D7C3E7E30FC066DAFAF38E2A19025F628E7FE6054694D7AD21ADA5B747E54AD1D -4DD57BFCADCDAD35E795A23BAA5171B8081EC9803B8FE6242AB1B421A20C6CD6A107572C -9DA40E22D64E0D053972699180A9B5062CF460A715CF99CFDA1861BA3876047D969CD8F5 -889104DC3CD6A91E6765BD2CCF49F21BAABCCCC6984D5DDC1F872F85A45D42C490352D53 -70695AA4420AC5E6A0CE1C5B72186FD1FDFC64CB7680ABAFFB390C494FDA8852E6523BB8 -E184A625027F79620D9712D570AA5E2DE15863B222F7F5880DCB462BBEC2B5198E005DD1 -17B6867C218FD965BEC790161999B8D27E7694909828261593BE4DCE97FE5868285EEDEF -EAB74A5707DC3C7824C1D4B170F729D9E04A3891E2C90FBA545FBB6F8883C60ADAEFD251 -6453F30B02B63D0438F927ADD8CABC0F78290C5D0433A1C611E4754BB72DB7A96364D9AB -8B698A63CFABED083D9DB7B3934DA6FED9C162D33BC52D95F98632C93A8B6611C5C3CFAD -B32DE2F520ACC68788CEB420269963C96B341D7702F7830FAE6CE78D23A99258FCBC3955 -9EA5748F18B560FBB1557019420217FC3FF9E1F98FA219728C74FFB024771CAB8A1675AB -F57B229870ABE51416A8D5906D27EBF989A3F4C6A94E0B9CC383C5F161B0079868B17D03 -2C992D39EEF4FF295EE6331E26022D098D1753BC6F949C0FA5567C8CBB382A92D13881F8 -734E4AFD1E7157D9ED6DE9EE7DA0B8A08F54B7C8121D9D4A5805373016BE8DAA8B2C20A2 -CCC748F20209A63A4A7988AAC44D829241E0033FE88CD314A751EA836287DB68B32C9F5D -0808946D8706556B3E597F70857C9C1ABC8728E256E9A34CA4D88D08A12AD64C1344E0A6 -7FCAF84A2E338B6734319ABB816F50BFAF49009AD63FCF1C9A4C7889485D7D6A3804A5C3 -52534EEE795E391609D1B6500321D29935FC49B937C061D556BBA407DF6A79C3372E1B91 -9539E5C21B816C060642188482BA31D8F3C4CAF759F7710E269235EB9F47C2699CB14C6E -0CB2DBA8CA246D4F8A4D95B4452A4AA20FED42E66C415FF1FB74BBB434FFF1831BECD82B -23B04ED0C66B5E1CCE3E166EC586CDB122D6FBDCDE2444230D932261DA28CA59BA47B23C -461E0EF7AD3E03C501EDD54727F14196906C9413FEA8E2DDB9C7B955B3A7B83D91DA4BD0 -2C7FD4A96FD70634E2069AD2189A546F0B4FCF0DCB00C0E5F3527A3F0FCAD178C8D2BC4F -4ABEB2250B4EEFBA149604B1A3D2178279E28B7E91E859E110510CD6C87D52E74CAF03AE -69A5D08D4F6A45B3DA591EC6198259C39E4ABA9D417336E18E0E07CFC28C84B466F034AF -A8541DDCFA4038288A6BA7A2503AA194DBAEBF3DEEF9BE93EFCDC351442B48AA8C0C9B67 -EAB4F75821E1FD55E60757D11BA394F8F336242890254F43F598650EE6EE730FA54E7EE7 -AF00FF3F55703D39B2623C7657E4CBB969AA8D7CE187C0119E485E391F57A6A42B2EBEB8 -F22B0F46012D822C8EC9ED9FB4085AE3C5FD36A9628B07B1A963337BA95E1EE89FD3ACBE -4921FAC06134DDBF72062F31B1D351020C16B886A36CA9D5EEAA6470CF5044C7B6710392 -1577D9D5CC9E49A36C30ADF473FE06CAF00A5DDB44475F74152D2E520A1975CD1C0A15F6 -A47893FEC6BC00E1A44E8F6A1651D39BEE76E67C83B735872BECCCF0F907207778C4664E -85C7D637FD201814BBC7D1C6200038B17F75E08B23F4AD0737259F9C07C47556FAE21B18 -1A110F056B1A612375A511FDAD2C291CF389622FD073F292ED09953B11E2A6626E6A4CDB -8B50B8F9C7147114DF64C9FD8CD2E064CD9A3EB95555FB2B8D6E8A4BCDDC54E97E9F0B5D -D3815077F6A825F924FCA5821E78BBB3E493F77CC71FCB3A5D9092453A0084AFA1ECF49C -384A274B9B2CE36C0B1413C473D041B4BE0080B561F7A03F5A1641A6FCD1959506EFE270 -88ACA5283BF1D38901F2E071BBA4B2E35BB79D9CE9CD3B776C7348EE014D21BE0421CBE0 -4026C044120006AE1816528B353850C3577F4A0CD8BBABA169DE487AFBDA975B850736F9 -1345BE2B5ED8D94DC2505B8D6218F3167050BFE7E723008CA3C29E3244509D0893C580F9 -4FAE8F724DEB1EE280AE8993C9502E9F40477FBAAE9C3F9DFD0A78FC38D537FC0BD23851 -8499DD3CC9E583C292D200B9A082008E52604EE8AABDF15DB108C8D5A693CD829C8812F1 -0CE53781E50A9D234AB33BE6693C3FB59B921DB35FDD87A393F137D0CE119CE835138F18 -7F2338E0AED3D973652DBB79D7761D39B8A819BCED55B483BEA6B5E971E06475D03E2B9B -B3B9D6677636111D4725EE36A077BE72347358A1EF91E5FFB77A0ED25542DD3FE9D7BC18 -596E2DF47A12A43F324444FE90226A63DC1CD5F265CD7EF81FE20A592D5A181B7AA251A8 -0CFDCDFA15B8A43A88F6889D2EDF93093DF25CC232BD1DB179536A1E3C46274F7F36A443 -86A764B04DFA73FF34D7BCF86C0A5122EA5332CA1D797DCCE9BDC7C8516BF80532BBDCEE -A7C2A883683CC3CBBF1E96490C2B7D21DA99A3D6A0ED78252B12E1C97CE41D2B837E948E -94BAB7BD87C929D8FAED67A8FAC5AF8E73F2518428646B0A70387CF9DF41DF0F4B5E7A5E -786909F6FF0CB78649EC9F653FE445B4D588370E86EFDCB1EDAAD1D2601725EDD7CB78E7 -E815A4B76528F51FB88CF25A44B187001C63988B6E32531DD4E961DF683D794C0AE3DF76 -D0C29D5A279E668E08501979650610050BE7FAA5B67B93E47C807D22B26CE24B9BEB46F5 -B09C4A4683ECE59E931850DFB86108AD5937DA19A2132BC076AEFADF3AE07F65451E7A69 -5A583E0741864156E31C4DB9795ED7BCEDEEAE6ACD259FBDEFD4B4F4F187726A7A247974 -7B22593130F566D3DFD71E500EDCA19CD8B7B7FB5EBAD025660F5D8B3F24A224D741BB9E -84942742D9D88E771B721E72859DF2CFFE2B288EABC083FAA26D815BA98A7A9F701395A9 -7A8058CDC1CF51740E293F51B6F0D61666A365235AE1296E1C9485A0043F651DF417CB94 -E53A1D79AA96CD5D8AFA0637EDC6CDAA761FD5F4E712745FAA66F74E7CA9D4C7929884D5 -32E12C92625B882AE1B60E0BFCB317DA1704F8A9337A42A8BE38DBDDEDC1E6FA9EB01F4C -FB0BA8A2B29D02D9DBE63D2D592348A645747C55A939E94753887A853D3DBE03C0BF8BB6 -C4892B94415E60C3B7927B3B7BDCF56B45189044192DD6CF8FD192C5929C1741B6E53FE0 -7B4CD9EF8409287D791BE417165B54D5FFEF0F742984E18340AA54EC8D3E0D7A479F269D -B8FBD0671C09E265CBE33A64CA9BF752D334803C09D32EA7EB774C32EC2E2D8706173E56 -C6A9690179F2191453DA57206855397146877BC55A562AF975C3715AA39F85C39A681FBE -F83A7377E88E569732533A5EA193CCB76318E9D6ADD7400BB9CFF14D698C4179033570C6 -D00D70E5EEF63015399E5F49C4DEBF22666D76B6D60F801D023FF4EE8D63A1DC0709481D -491F88979DC7AF7260BC0EE1CAD6A7A3EB0CE78C93865884383489F457F2AC5CE0C832F3 -F4B81820F37DDDB712560F066ED63777198E3491EBF087DA503CD59812FB082ED11E072C -1C1482D879AE9F461ABBD5D4BE7D8B50D50C55DDF9C49D64FF968207614A85DF8DD56502 -809FA54B200F7DD9A6D4262AD7F0CF61F87A69DEE18A9B8C67F1CC152A8509E64211A064 -F39F3CCE5894A8EC0E23C9A557DF5FD50E2A5CAA3338C1781D04CB638A47C7A5A6FF8230 -1867BFD856A6BF11BA8DF56963D17291AA202C991F7EC97B501F79CEEAE44474806A06C4 -00BA8E8C5AC49448ED4C248327E2CD223B9199ADA618FF99F8DB84065C36A8205F5D3356 -C690D972B139D97449C080821798A70E55801EB4532D0EA1C05DC635932D1848310C063E -05BB58B016A99FDD3102CF2BF2AFC5C6FAD3C031FA24F9BDAAC454529565E4EB52F838EB -D4A61A32FFB3A5768F3B1135629AFFB808AA85788B3BA755AA51A6580803B6CE45D94581 -849CF2FA75442E759F1A544237938E831F504BF6408034B034009BD82E623AA31B66D128 -2741C8692C56E3F251BE3D582C32A9B770D5DB3E9DA9BF50A527B37DD41C425623F3B787 -7186F26937B3E04E291EE805DCEDDFA214158DFE50A3ACCD0DABAB73F5F51BFCA200C466 -B9A786E7CFF65F4B24C29D39A844A6F6D6BE41C298C2BCCC5CBDBF3C3B731121F834E230 -C8AA3BF6E2C40EBFFF4723BC0B2AC407B93DBEBEDD49CD639EEC65777A5B6F94B8DC1C59 -05040D8E4B205068BDBD5F812058D4D8BC2E16114D22D81701D36665CEC878D148AE79B0 -F67957B5505708ED3D98FA55BAB6FD20E2C8BA1C326F514AF29CE979DF66BF1F71A579C2 -EEAA176A3632CE7F136885EF3D530C15DDB59C28CC8E820F55E31667E8D8555DF76807CE -3B37007E37A06AB32A21B2DD297C72785A88AD6F45784224D29241B013663073D8E1F7C1 -DD2BF95BF7C74B8743B31EF48655049EAD7BB13B87E648BF938059202183DD2970BCE1ED -3018733F8E5B7EF9255A29ACF581426DDB9224858BB380AC7BFFA1DC8D2589A83FAF5ACB -A4985D845B3F635046887AA62327FE0B0F020239E9FC7477821F7BD43EA2EBF1DC9CCF32 -FF6111507BF24557126C3BEAF30DCAFA051E3E9C26882BC3F4915F54AF9965505D89D11A -562EA74783739F0C788D0BE3547F16F9BD13F96D861B2DAB90A4BD23043D588D9B583C8E -15E9530D006DB4F17E0B4EA0A851397C4B781D707F98179B6E212A6FD87E2509B6AE4CF9 -EEEC87747374BB2144CE2E7A70B0F2C03A69493F9DD476675AF200F15EBEA4F7770001F5 -461B9079488E9FC1FE2EBC86DFE8CA2D2ACA5F746804F639228E813C8A1D1680F0A12499 -CE56678DFCF24FFC05C80F78989CDFB4F0CDA8E66428511E9BB0ACB8EC04161CC575AEA7 -522A229C75815C78B3248031DE073E0C5E538BD886F85555AA2E0A0456C2933A95E83AF7 -D16C8F8DA487452AC84487EC764A1A2EB1CC754F517FAD18C7F76769E67E3363D8881823 -6949A35827574BD65623CD4FE89C0F11AC2E050584CA49DEF1C513A8F7690652F963447E -DC79D866F8C42EC7F3092DF52EBCF6E64D19E44CE1403BBC3A29C56CAFA903D315D42058 -A01E6124B82F1093A3027891C49FF06C8C1638563F92BA051AA5F750FF5F6108F6C0071C -E9CA1CC669841592DE89A5383CEA9207C9DEF1A4FD137847A80630FECCE16A6454F4E857 -80A9B166DCFC50AD94E332CBC546CBC0A39507C8205050473351C6263B33FD705594E654 -06B19A80DBDD061D12BB89775D6BF4933B3FBF3BAF6B287A32EA01ED2B5B33C48715EF5F -4650C9B92EEDE15F46DC093FDE463578EB377697703D7ED7C0E576001487567316B333E9 -CCD75BCBA59E69E1AB62F39D0546EE67FD4C1339A93E01951F0C2A38A994406406D2C64B -D719DAF35CBB25BBC68E6DA6016ED0AD7E1930CB951C1CC22A8D82E144969FF25FF153F5 -D7A7A6608471BC31ED1F4B4E6E58173FDD83FCAC6FA079FE172CAB3BF667C0FAA4827244 -1445223D78002593602829313EEB37EF4EF8C96129E96484E36328213B9DD5F55B731167 -FA55DBCE903768321B2F375FF1323016F7A8C0B401BF8E2A983EBAC57AA4CE5668BBE152 -E1BAF5615559760ADAAFBBF1EA43703AAC9A74F21383017152EA311AC3D3F8762E1D8918 -887A0BD9E880D3C052A48B4EDEE667370097EFDE700B49D0A19F32AA3B43C9B58A3EC400 -DED3BA2829B90F54D8F0B3BECED9136941272DC0332FDDEAABBE38A0F8BE05287CB0D281 -DF55F4E8AB705B54DD026BC09E5831A64C728D9895D21E1FBD24D198ECD475CEEA216726 -E8BB15D4F8E946B5B097CC9C89E79470F0DEE451DB14D96C994DAFB07A0221BD48F79587 -DFC722BE7B360A93B98B42443494076BA779417DA3C17BFBE69B4B547A3EFAC6552E4D4B -9B03D51C863CCB46A8ED112C0B19608879DEAC918544B43B4199B2C0DA7B318FF13E0CF8 -47612E7279C334F681AC44CEBAB0D6E141506AB98322FE9F41430E69FA2F482CEFD68F3B -1280C9B6EA383C053F9474397E8800A6DB961655D18ABB68600F570C2D02E4750622174D -6A9AB48B05DDB2D56D74DAA537A642E1FBB63E55FDCD54615D08EAC22EF484FADB9862C8 -6FE2E6C300A367EECFE4337110796C21F60F9CA9D034917B1C98FA45EC79DA8DCDB216E4 -A3DD97F0C51F7828743AA768F2E442D2264DE35D7F191AE874B856C8473ECFF241A46AA3 -C2261E74BAEC485E0602ACDF8FF0A0077E84E6C8330951209C87E117DC57D6018E7D4EDB -E79E6F59C75D8D030B442B65B3513F74610B98C40E3C2D500D41ACECA44257F8E24B0B19 -4B6C8E20C51E61AE4F633F8586B52CF2D9438958C52F7DB15B499E69FE3BDC8E983CC34F -80B57FE1279254A228E7286CE78E771BF9436154847370D7DAEA0D995D9D7FC2F0637731 -29E076BF10576E480C1D82C29648A2AD8CD36814C67045E4A67737C22B5B5EA48387D991 -E35B8DB9695290D7CA13B1106C6FFE40A6EFF1DAF1A841F3A5F75B68D441687872E91EAD -4AE10D047756DECBFBE4F87262C2008D4ABEE51A0641AA309631D7E54258182E56901E59 -D1F6C7F15E8D3FB2CA70AE578B2CA08C65FFE542A479407F98D06F398DF54DCC16FBE30C -67FDD4A3227238EED53CFE2AE0088A1E2F9AA08917947C4CF795D3E464D55987C4DFD14E -EEE7C9EABC34C4F4C77B56C8E486BC35E38DCAB4E7FA1746C5854175AF400460BF82BDE3 -C9E066F4ABA7E1DAF6C04035AB86B1289E3702FF3DFE4FA431238AE487D486150A1C52D1 -047B1663D12962B478BB1E4B750FAA1E2A09ACE4AE89058F3E2B928167FEF099922EA552 -6435952A7ACECF1650B319BB3BB8734F9F54696B556BEA7EEC47E4A77D81280415E02DC2 -3F4D9A73F44AAA9646671EFEA5549FCC9A5915239DDA6E1C872F742B28A203AA88401DB7 -00C36DD78CEA2A9293E8768D5C59721D16A41000A2E1B230DFAF4A1BAC797DDB85BCC5A5 -A38BE413D0270D7259289AD4788D1D9769234BAE6CBA1DF835601A76CFA75C005C0EB325 -6A100B43C0AC0D0051084902D68F0517C91EA5F4161961644230055C97947D5756C62F12 -C550E113B2A88EC56345C965D81EDC09F62AE036C18AAD798250E5A0A07E607F3E2D0ED7 -B889CC2961339149DA012D74F290574735CF2706FAFF605861571D78FB92A8CDDC84C83C -BEBFC000D43211962C578111F8FB8E8506EB1871A518CC7313242FA11F8D51BFC3797637 -F5E1AC8EC1435B36D98BF1BF34C960C6CE650D5115A7A244ED7489BDB7F6514BE25372F0 -9E3F378CF95A0E462C0E0E1B4E84696F1977059079AA626D0F441D2CE7F4B52A49B14FA1 -19762B9FF8966772E936F0C6BBB0B24F7846FA1109562BB57A995AB8DA48C9EDD5E90FC3 -4C51EE9DFF7A2D4AC959320FE10B800C83E9B83FC89FA220F965DB0495A4EB5EB1AA21DE -5EB75C0CC0619C9C38F942CD525ABD40EAC721322D47D7117D750325AECC9A021D1A12D9 -D439AFC0425F9046622EA9F34FE1FAE58C428311D62DF1FACA2127AA627E91F5063FE47D -F727DEE5B989E1D4A89B900FA7A9CE3259A3A86D966609FC254CBE319DBF40FCB0515567 -A54AFDCA6CB575C49E893A136D1680BA06CD3C427E1D1DD707AEF67C44B89A4CCC1F40BD -64820463144AFF0DB7CF78F08BEC8C7DB7356EBE85A0DFFAD4D3DFA0F7F4AD70E7A5B49D -9E51D73AF08C7B65B9914071A837733C0819ED07223BCEC52D623D29CFC3463233DA8E44 -02C013306E90993BB54CD78043BFCE18E490443AB6D7567FDBB9C5ED761968B39DD21669 -EC5DBB5DC7205B279B3095460CEE2273600AD169C649D846A1DB9E6524A7FD5D9EA9C9F1 -A02CBF4D9874ABDDCCE5F70F7B3F408F6186A0CBF83EC8A342D7CCC022C55BCB472D5896 -069976044EE83A88622CB1C774EA75B34DE55D618E7D22D50ADD05328B59F9AA9B683EBF -4741311B7C07541228ED36A71F9175F4D0EFE9C11B0AAA03403F1BD623F43B4E8C8A9E5D -8D2B43F240C89DECE40B79C64DF6FDA815F08D51BACDD7D6932B73F74A3486993CDA0834 -3812F920486140EE379675C07291435631EEB4E03CB5DAB603EFE0545CF4130F9D7D421D -5114A4FEE9E4B2897BC6D232ADB685C55EDF8C2A8C47814A38B8C7BF34FB777360449448 -90946A15CDE17EF60BA40E77DAF5BECFDCA9A09FFCB93D0010A161BFDD40EBF7605EBA0A -50C3BFC9B8A48CFB895FA52EDDD86221D6EBEB0E9A3D8D0F80B88DA1B8099DCDD7703C53 -0C90F979DA5A2CF528B610B5645087D2CCF5D8F639E420AACF09F97231C3250DEFF28978 -43F44E473AEE74810B77D8449877E45AB5A30E29A4E98CD78F57A47A195C3CE22A5BDED9 -1B3C576D10D7467B3940542E70A7DFC92F4876E384131982D7680FE05A5812C80621EFC0 -A2F0BEA16B3D4D9C07B8AC4A540C803246CE437DA13FE610EF3211F81CB7801C642279E4 -9CF563ADD932DE6ECA45918DDBE97DA17B443C7BA15FCF39D91F9C4501B03E56B9F6DD75 -F3A47EFA6B7D9702EDF6C79C9183F37DFC805E5689F27B53D5487767B276AA037A210C02 -AE23A2C4C89E6CCDD49FF5FC857B2E8B8A9976C238456D000DBD35B00A9401657DF88913 -BE616D0800945CE1404968E78028B727B6DB6547F5155F4C5E0C97C3FEC8882EDFEF555E -98E76A3BEEBE09DBCDA40C2C35BC1A8C7A6B7812AFCB1468D527F723C947F56B9B1B4A45 -BC11CE5C3CA9D950E4729A242866E226A66E3D8F71D9AE73F0F8740E2974CAD28FE613C6 -B67BDFAEC416CF799EABCA17EC183A0FC013A16EA73B5156AD203C2D07898D20AC23D03E -C5E4534F153440C72D3DB5DAB3EF1AF626472D039892379A39E894B10BE22EB8296E209A -8C823E4999F6BF0A1D3CD90825C752A98AA190A2E19266329A49014C772510AFB6B85D23 -FC3811B1BE5CACAB09B5D46E3813DDFF41B8ABBF8E8ECC2CB14D48632DA2E5F5F748E14A -8877B8E5F2E2621014B93A7AF3113E3A8B3BCDDB1CAB7E7FEDEB79E1825E27151E7C74B4 -CBCB8B40A82F1F333AD206F18835FA8EE49BAF6E22E851DF09857DD303CA2CCDABE607FA -78740F70DD481DBD1EE04F730B5A3762082B1B47E69F39201D42A8E21F0F48CB5EF716F2 -4E3B4B20E53CAC08BF494E71495B4E95E46B6AC1802F01DBCFA8DBD1A3ED82894A5DC263 -700908A3AB700075586F3F3406496A1DBF40121744A9A1C51D3E135CBDBB5BA68D3BABA6 -21AAAB308EF3B0287A32AB2E584FECA9A3E00E0A3A7C038C225C51788C3D13232240EADD -63C8FB02A0471517FFC82E8E2AF6AC526F0A3DEE7726821ED3627638AD691FD4B240B9FF -613B72C089D11C22C610F9B9E244EDC11BFEBEB5B1C5E4B4A4362683363B14FCFFD748AD -339C432D31744B43591ED1DAC1721A9FAB9DA2B016070D89914C0EDDA9EFC894440C8B4F -3CE96EC4DEFCC4C57AF0DF67C40575095323A5D73D671D2A716A787DDC6837A6AF455F6E -B524888B98EE8E8F48FC9443899D3CC6FCF6EA214CF462BE414302FA0B39C1DB687B5186 -EC46781405BED3DD98FA23D796D197E9CA2287D4494E876F8AE61898792E3794AF5B3901 -815FBC50E7876043D1F14E61A6F998617EB751C113739F035F4E9DA35DD53DBAAA91056D -1EEC865258540B185DF50A01862EED02EE626051FBAE63DF6D94666EFAF4ECE522CC8066 -EBEC91734715C3919932E28169F49981D7316E982C287F716FFA8D61B939F8A47899D57A -C3D845FFDB0F21BBF2AFB9980EB0D4E180B4A22A902299FCA5B157AF5DDACDF2C9DD3E58 -2AEC6BBC869919860893B9FCFA4881FF8AD0D10066CCA51A0B63D478D1DD7BFDED04DF2F -58186AF02494A6EEE99FB66AF9F3B7C6A9E1BBA52AF2FA10596044F7A9D4B0CB337AD6AC -5BF8CDBB69390F7536B977311C6C9127F26DEE4378A17CC931587F77F14DDEAD5DDEE1E8 -B57FCBE1382D9529880BEE3DF9FDDC6A3F9C6056988E5FDD101A54459F6932133871851C -4871EF219571A1FC43A42BF14E8B029D8AD6EF458B59057FD6BA634ABA8D6C11EEF4BCD9 -402F47D4739BDDF22948A9D5E7754F621D27565CFC92BEBD62555B12BEE04955923A9E8D -6B0C3D336E8345FBDD40B8E7C9A43DB83A895EEDDE6211EB1360FB016A9DC23F5055839A -9A71775D8A45056735F14F87600916F187A53C323C86CDE455356176FB014584B4A04126 -3FA11150B2DEA71B44BB130243973600B3A9204C13304853D33A15CCC111C0F08360DA8A -A2C615A72FC79C1B128D04ABA0E92A138CBFB37253EE80A18BC9D92B5845E895A7DC4060 -41AB37F3D4827254BAC860D6EDE8C5912D8DAE2F943A4430269FC9F9894024C73C90D77F -0FC81E16F618BF7DFC1AF1CB2EC0972F62B30F5B37747A8AE2C7A2C7C34595B8F1DF513B -973BE2F1ED822FD4BD7D5B07BDDA6006019700257B103BA495F9148012C4CDB2C3180DE0 -B395BCACDE2FFFBC1C64DA5D7ED1738B68AE483E5007EF90C9A770D73988849F2D2D6EC7 -734422A7D0BD41042988E4F215A81B4D2545A2C84A1CB218825221D3E33D5D5A2DA7E91F -90B275B9F73571286905C58ACE35E0FCAEA9A9BAC32784C8CFF609B09114D6836AE6315E -4943E9AFAE0905E0516603C5CC2C54C364CDF9282DB7BA8DFE921D7B4833C48A8045A60E -ADFE47F9E1818BC4F97657007DEEAB9DCA84280E3014EEBF7D4D0D1DBFEDB072B20CC4C2 -BDC4414DA5070757F4EB8F65B1DC1D8C934F9BC20F516A9C6295724DCAB93A9CFB0D75CE -A6237E7F225DB1CBAA18C679E2C6F0121FC59D090E5DED3306F50DD0F92D5D9FA2003095 -CE6C5157C569F3E5FC02D4F3FA115B9B294C74CF95DDED62CF1E5490A6FBC97065247D4E -23D1E39B0EFEC6663C27674AFCEFBEA9E482909EF6B6B8E3AAB9FC169B0DCC8449B50A08 -221406F001A4D140579FA9338C675DAD54E854CF359452C07D07EC05F28301D94FCB46DA -0D0F5502DB24BBA0364EFF694A7F4E86FEB6845CD59493BCDE8BBC61A30FA209B890F097 -5600D91FD896E6E0DD0626B4BCA3487AE1C577320E0C251AEDCB44910510CE89CCFAAFAA -CB88770FA29636576011B67C6FBEA6A310AD45A006100C4473E844ED4DDF69341BDB9FC8 -3D37F678B9F7A2BEF245F823186C56AB3667795C79EC85D68B9A34E9779E29889E67DF20 -26B22D42C423C1425A678D8868543E96DFF0EA75C3666B0EC85A015B7048F5ADD08EFB1D -B674AF6D008808168A8EF8EAA7D43F942043F3508D6AAE60CAC9C9950B81C5ED863B6653 -0C98AEBE1942E63CBA37FA6E02DA11AB27F8579BBA5220635D424AE097A88C830B3D42BD -6B7D89F6F40F63B362E5215373F943ECEF08666D86D2D3AF045EDA7F9F796A5522608F6E -3FAD8953F166C11FD0688B127AC306770C934311A4890C48ED4EA8D12D04C5E2FF9B6DE1 -5253DFA7627F3600C89884B2B3861B364FEB31805A1D91B95D2DAAE9D16538DDCB94EBC1 -23F63ADE7C1B9D48E526EAEC0FFD822160DE068723170F5B753B5C10A0A79CD09ABF1E96 -A8811EB377BA65F37ECBC966A054A65FBE686C3BE9FA4573BF86865A5D997FFB690841A1 -F273016436C3D76351BAE06BA745BF00F27428B1113B5351567C9B254948D8A91F6927DA -381F993B0F941458CE5F5189091A65B5D90FEF01051919863C47FB4EB11D18CCF8E5C8AB -3E518A0923BF4AA13F83BB3FE88A4C3D680B7FD65D649E0159C6C9151FE7959E77699105 -B8E4E1B10C0C5B56C400325D32EB5716BD0FB13AFC7A424222B970A894C7D33BABF63B59 -EF13538F526CEA62F5856F1BB23A00D7E65220E5241D7EBCD0F84C44ED3EB468DA011023 -4358E69CB5AD8C0B53F2AC1D014358CA2C2A3C901AC5B2850DF73455D690D3944BB641E6 -995053A40D4A513425BE0A17D619DF7ED39076E9FF9163282CBABEB14BF7E4A49A5D93C8 -69B9F57C9D86AAD074633AA533F5734F2B98B0CFF7ACD4726BB1CB239032FBA59B3D0FEB -3F3C169C667807380CAF379766B5984B4CD3D71975B62EBEFF09056E62917083E35CAFD5 -6FEB1C7A89658F46733CDA47E99797EFB6E48332D24C1B9766F92D4D4AC4EF17CF6418BB -CD0694C26CD6B5421AFFDC33764719826667B6F88E604F982049D286A35B5EC47E07605C -A8D53448C6A436B183BAD32E8138CF289C5D0ECAE1A2818BC3CAFA0B02C9097BDF043F15 -8625F6B756D85C81A4B42865A4AF790BE63EB95C72BE08598898E801FABABC845EBBA1B4 -4D4ED41CFF1CD460612F8C2B249B1A206656B2CFC3910C57465343DCA6DF0DCDA3F6DE56 -8D6AD6F83DDFEE9DE523EC0BC45138BB80B7315D894B27D73C4C1DC582BBA0A8917E2E10 -F94369E0A956F61EE11CBB2B45ED6027D448538B36C471D2D3BB6BAF447B60F6023F55A3 -24A5C71573438FBF1A7B40A746A73F5E1B51FA3F38DC9A2806BCA0B8B6817B1A265826B3 -27D425929BDEAC8136A91329B43EAB1AF325960D105915D185E0522CAEF00A15A2014F6D -E29C3093AFF98028F5061818F8783B37FD1881ED44D6516EFBADD5D6B500D5502BFE6A5D -908A07BABD50514A1484901A51AF83C338624298070D04C1DC09D03E565C7D25726E37AC -1D1A9F5DB891126F9944BFA1080C7906A263BA892363087DFCBF6B92D9AF9CA1D7781A99 -9DD794B3385C18AD819D9558CEEBC46F9097E9B6CE6A00F1BD43C98730CB80D48937D0D7 -36862809C16C794C4435B41DFC392291E699EBE1AA54537375B6FBB27F1230B77A0A05F9 -2BFA166CDB8B180036DB3F48E4851A538C628C8D5D9CD556317A0CF0E6C28183E07249E6 -D6D47F35F1C3220596EF0CC1F0580ACB2B029B5A5B0C10DAEAD5D3F698CFEC641F16D80C -0225611726C1D8C4482A00038BEC8E0B9EF7263C32DF0F80E01473C41307FD9C10742079 -9F2E0486F5C937EBFA48B7B61DBA9094AFF525790B61C3858F76685675BC6ABD1B9E9A8C -A17C98CF85E49D6CB5A6B7CEE52D67EC249CC2681F802C06FFC639BF3A0EEF23AE39AF5D -C3E77F63D07EC30E4B3E06F74E707DBDE5B6DC0DC1A9DB02ECA2FBA6C87CDF278EA55812 -40495E2C138BE9CD3AE2A1A427151A5EE3CDCE28421B137B1427CC48EEE8EC1355B48FB2 -86F40371EB9DCAA5E163C65967FFD4FBDF7B358463D00AB081ECE83596C2EA2F3CBBD847 -6D6EEFF31FD8A0E3CF4B6362BE42331CC2737891CFA525B1CE62F2FA4B1F2FCBA54D0452 -B77579DD1C56DDDD6DFB2DCB816B47FEFE0E84D3A19FEAD6290FBF751BAA095C068334BD -77F0F04DEB6443DA99E84D250849045DBE0ED267F2789B475127E6C57059359EB08AA04D -3FCEE5B1E61EAFD90B19668647CC52FE842FB9D5A58E3E50E4CD7A2EBF1FC9DDF4CA4B0D -29AAAFC8344627C9BC74C49BD24774EB0CC6DA70B3F3BEE134F298528373CA8B96121B31 -2C5D02525A1166E8A644D04194DF8E1D9323FE92DAC4833CF0E08C716716069AAC65A421 -142B305E97E668A32B397244555BB14653C18384550BB417C05EC9343BE28E62845ECB49 -AE6AFD50A5619CD1F5779FE6AE1C2A2C10420F0E9426AF4614FE2E6E925214E0ED5C6133 -E9E44ABC962770A4E598E8D4300F9C93CC152C5067FFAE77FE9A171A5E463D1E9E5A332A -564281F49055D0A99F49A20368EA7C75285EF8215FC37FA69A66101EE4E2E32A1A2AA753 -8EE3FAE3D4C31F96C34A74677BC9221FB904F777F69D2B85825E09C8BEBC973E4AE85EFD -123507D5D428372188270978D9C7ACEE75DB5D1F1E2988832870B7EE4F5366DE20237EF3 -E526DC33E2A4FA186A43325779EE8253D76DD1C4FB007F1A2B8E0272334A5956C488ACB1 -1D09C8399B4181B626636F6EFED9A5086BDA64AFA3677A48D13464C2E0813421D96B08F5 -F3B7D2CBF5B2875A1C217F4677B026B21A07A8C61140B1A91D552A1947952448D7492460 -FCFAB5A22A7E9BFC577ADAFEE42FB8C0EAD717071E54493AA7BFAE960641332AFF9AD94F -9FA05A94FD5CB6014FBC8D274ABD58DE566F621672550D2453ED92AC8E317D6D28F5A443 -D211A3A65005F8A18006D2EC7749AC8F57FA4142BDD1D62EB99A2C4A2EA448AD5DECCAD8 -7B54EE483B40CE76CE2CC0239B0B50C8AF29E007A10FADC1863D9844B2380052383F333A -29A7168871919497C878D7DDFE5D22667C51FFF6C2926B3D219D3A3C02EDF6A9FAD14E90 -90D293156E00F6292F11808EF0E73CA26147998707EA4ABFF7B77A5E29ABACC005EF74DA -D402BB1AACE7CDFA12F93421506980C275BACC61B292DD800E07E1D640A187E73A0B682F -0005D5BD5F6E53171C376B1573B9F1FEF247AC3494D828991A9050C2B85870A9C2E08C14 -A92632C3553AFE16C771A3FF2DE42949E1AD0665A0BAC07C8B1C9622873C54DCAC6D642C -1F050F2CF566713BC4C09E28AD0E7CC6986CDCF68D5D8DAA0B20B6310E4198A1B95BB262 -7B1816093B84234255C361928DB4BC5AC3A67A487C540394E833E3D879B3C96ABD4ECC4C -95FE7718D1D6443C84458B694AD25EF8824F947569C001931C133D999D6DB574698BB17C -B86246A3559E4E4EFC079D0BC9FBE3A8668DF9311E7EFFE4316B47C4982168D69331CEFB -AB51A1BE03A6C2CCCCAFE7BFA2A836AB5819FC8E18E33C4CA59955247D0EF9AF810141E7 -B60D58D38A2A5F4686C1FBCC929A2601EEED2A4A4DE9AC90F726F1D1A16BDCCFF5280A6D -52B626B3D927E606189991FF548FAC99C1DAC6B894B4BAA370678060B1D6CE7D1F74E251 -920D7279E493017DFB862ACA5BA417A9A975E4D6736C2DEA7418CC1A07DD3812BBBE56C6 -F3CE5DBC16353009E547376D99F03FE9A087C29A1161F2629D00206C219300B1D09F4BF2 -AD8475A269466201C57EDB25D8A458E4FF1424FDF09B1879F5AC6512952D56EA719263D6 -F8BD77D3B5C04A2D9E27EEF0FF3F42484F667DD1B3E483C45DA8057AF1C3746820D7C663 -5C363BCBF2106DC618AA1F46C34E9562F33EE3D392A6072FA236BDFED8D8FFE526694AAD -A68AF0ED535F0E1E2CE19ECABC2FC66ACB07E44FDFF7111639117086B1876725BEA99E8B -D0CD8055DB154A8A7BE4165118C104A5C1B2629B4C948EF51A68C7A3B5ED70C2AB40F0A7 -53B75AF07F4248699B03A7654C366AA3A25121D8590E787FA902D5E29516BAD7C842C649 -41EB1350B2BAC0E28946943E0D5C227326D7B1C3939FA481245B19E7959B770DB9355DE2 -E5B6FB5F66E273BB9CC91527F87F35E95AAD29D867A0D35E9E6B1BE8F1EAA06FDEF2BF33 -E694D4747D525AFFF997EC367C1E1D0B55C2146BBE47581FF99824269E43B795FB02F80F -83B1BB3222C6A48B9651325E4A6274BE9047DABB7FC9F85751DC9239E82CBC5ECA22358C -8EB9DA76B9CBF92894268C49CDE4F67B6299CB46FAF1A8E42FD584BA74C47767613325EC -95CBE6A43BEA5FF97C7C2195E970504893EAC878AAEC0CC2E86CCEC442DB62FA15C4BEBF -35D8AD91711A689415A84DA6AD6D1E2646E363D143FFCE360B3E9D282A84559B1202AFC8 -41A603E80631FA5F1914411B13811ECAB8CEF64906B0361F5F558A22026F46FC88A389CD -E0B23523E884686C7D4D9FEB4C3D66BC410E2111A73988E73CE96CC26A9ABAF3C860D8F2 -658FD13A44F3DA9B5E53E348FA51B64299FCBF16D16E07CFD4C5446614FFAED07FFE9E25 -A10696029806CE3E23582A1FFC5B83185A0411E8353BE08D7AC131E2BC7B7A8EA6B36653 -82B2C4C217CA8A09ABADE43A7A5249643758B7FD0CEAB8A9AD8E8ADF1A9D13C2E5EAEBE6 -D29ED3734EDF200A92E19490CF4E42DFEA28AFEEA7FEBCBEC1645C6A101B51303BAFB113 -8D90761074D935F9F553787C1F653FFA3DE1A8808D185F38D57DB5E1B16C1EE5B1385C4F -3C9FAD7CB2460DEAD9DEB549303502AFF17660B9330D162C891F1039B68ED4682BE6BC89 -7800F158A24B07539CA9CFC6324D52054527406D915BC0932F1D7A86E2FD1F649386CA6C -6E27C50CB7A63862D606CDFC3ED8C6328A756AFB01865C264FA74B586E5A6D34CA48CC74 -24B5EE73BEACE92A3A4D97BFBAE51EDC60643B8FCF024EF05E263C0BF15AC37665BE3428 -86F6B507B63463EB2DBBB5B2EC5CA4F227F9D5CB0124BDCE2C0AB3D4358273910E916D43 -6FF95985D564BB420489DD1A0919C8100EA03EC5702A9925C68C86B4972C118B04016533 -BD9726054B7B563BEBBCD62CCC5A08F133ED0554872DE4188F1F15D52CB5592B1E35A319 -C6E5EFBC10CEC89E9DD78884E18FBCC408378351B276FB389136ABAC62515C1F5C3D3755 -3E0FF12DC19621DC4E6C148FC4F56F8FE32CDF567DA11F80ABB91D224D4AA7ECDA2A5035 -9825F25B2150EE449C101935B44549EB3E6830D551C551E1501D7CE5B3968B770016F605 -8F0CD392393DE4576167DF1061732E9F7A42464610BF841387941487AB1BDF04AD40EA13 -90A50F076215B6DBA43231647418BDBFD39FB143D43E0B8912F36348FC7A1CA96DEA49AF -416D8A6CE75EA49395667E19CABC2B8D43543A488B130A2D85386518D86987BDF99A26D8 -B4EE1E29A4BBB8AD0AD4A27B346FB5F9E8E5F180F0D5748FD98A64715954A3125A749A43 -EA2B18CD4DAD93656B8FD9CE27E5EED5BBC369C060BBB43B4038ACFEAE8D437A354CC373 -66B2715885DDE1BE0F5DCF688E5AFE08E163264DAC1BCCFE9666B01970F2F16B47772ECF -751055380EF0002FC3877CD3F89FB0D9E018A6541FB71AA3F6CE602C4DE2920386F01185 -E2CF256CD8F8EB24F460270B6CB8982C46CA5E58566ACF504EED68FEB0255B6D58B33687 -551FACECF40487D58D4DB520A1BF372DD3B66710DF6224E9B6D2EC15B31EB4E41A6CFD53 -42E3FF218807059B0EC60B96CA5F9F4CEBDB3ADA79C16624824F479F5FFF981B0E109BCF -8C15D2254FF75BCDBDD4AFFB96CEA4968C38611FC2204054673FA7AF01DADAF779AE58E6 -8600044320439E79D45D56352B704E5F12E56ED1788E0817DB76B80F134C9752F0082CC1 -D4205003C0B2E73BD54138B10E0A16CB57A0ECBD17DED50FCDF7BDD848576E87868A911C -C5F0B1C36BFDDCE813366DED05732C46C9DADA44D71E94C3C4A5030EF7061684CA509C70 -8A242B8A39D649530F379E81A1F5B4456A452038BE180E35889AB052D14823392AEE2379 -FF3564A86A2F50AFF40962F665F3C005CFF6992FB85040E6601D20135D7227F05892F344 -2578C821EE1F00E68E0475C0266FE10458A18634B226AF224A80FA07A1E3A29FF6AD2838 -CCCCEE4E5E9035220AE9F53C02DCA89F00418FDF632653C5C64BEED2209ED102489720BB -D735B06159B60BB162997140BB6AA99CD063B94A7DE5098A8CEE9A1AC5ECCB0E0D12D399 -27FF2FF621919638D4205E39DEED766108D63938FAB0DB2B2C9D1BDFCB14517C7E98369A -7BD3E31ACCCCEAFB954D92A22209C9E825CB38C9B5A529823B0A85BAC2605864B022BE5B -B8DAA6312E8DEFE04593F4E8D0284DBBA42CDFB7C189F280FF48B79891EEF4FCF59A413B -7CFAA37EF7A154DF78808E4AB8CDA33FC51F6E389227BA952469AD2D7BAC328342467482 -FE311D122B9AFE8A16E9B6F5551CBEE36A3EADD5FE7A524A556F3D7AB3217FD8C574DF32 -083E0D1EA61A8E01E3BE1392BD2955486E289C3E1727FE71C50D1B50E4B7D945C5555851 -AFE225EAC181B0EA541AF40AE45309B4BE2DE1BC9B36E0B7849D0844330F3850572B3869 -FCA1BFDA818FFE1CB7095423D611D85890BDAC15318028FE9F3033D1DCAD9381B9237247 -D65829AB81AFB878C7EF54CBB6CA38526AFFF404662434D7714FD8A5D0800C8FCDF69A5B -A6938079F41D08E80746259C7D7D24E149E2C55424223CCC1AB2008545CB8C5B51CEB8FE -DAC374E94A7836030F536F34A55352ED405D9C31AC2F82FF072B9B885968D534C9792F45 -1BC48E942D28CFF06246597246776530F72392C98D29CCDDBD9063EC24D559437B844430 -0D2D742E08C0126F4116198C72AD9D95E83A534A6D353FE873038825687C3AB0281600CD -FB2558D70450E14684F610E144A7568C471334FBEDE0CBFE913297A657321182AFD4045B -D5D205551C6F9B904781B32529C2AB0FE1DEE6269CF6009203027C9425262CA5AF2EB250 -493B9C1018F2907DCC656816D57FE4C987CBE7F7F1BF0EAF8AA40E23B456093B3DA29C21 -5CC7F911ABD9ED34866EAEA9E1E7998C4126CB3B44F7A8075C37640E0AABFF1B9B0EF003 -96A9CA8999EFEC2FDE533584B5F49BB4DB1E121B581E12F2392E7ABBCEB56B35E8D0E507 -980457C24100377B95668B167C6E5388760883BB173A6993A88104A3E08747F1B75F553E -65E448C8188A3942182FEF0593BDFDAD67691E125012714A0B4A61F5E918980E1A167A32 -D7CC3D46435CF3F2A84458F309661A2095792F79D1CA6378DF864A308E162F1D8B35CA85 -98045B55B19BFB7D18C05B0216F5A7B75167E7866537F3F8F6BFCEC95B946B4AB1B0B015 -E45ACFBA6F4E24FFBD0FC639591A95337ACD84FCA6A164857EAFFF41D00138A582E321A1 -D6205B3E73E2A55882FD873FDAD0F9D205D47F75055FA3863E5210EF6A56F8D12397E3BD -EDBBF54C8A328E62E03BE58D301B285E398A7AC55F6E08493099CCF7A70E79CA81E275BC -86805E22DC3126C98916CC09B06CCCEEC5B66469CCB92AA21B71A49A2596076818B17ADB -301590C5CA8635CFB881832F8621E6C15EF5D59F20F75098FBC0A7E79690CB5CB3F746FD -D8B0A8B92AC145E9303ACF6FC91820119325FF5D8BEDA62446311A73D89739E628B907DD -AD9B8CB60E076AC1092DE241A56495D0C1A5EBC43888BB8DD087BD6CDF38E1DE93630923 -CD7F57AF1604A42B70D2E073935E66025F44ABB3E8B620E065810AE1D2415D7A58175D06 -B7CB4C211499F9F9EC43B92C3E93DCDF03699D731DD288C1651A62A25AA9BAEB1B79AC89 -974C233D6ABEE67B4729A746A700348845A42953CD858ED53F385288ED83EC2B54C2F416 -3D4E2E5011485D9293567429D4BA52F1F4CCCD80BA8B59B501C629AE567F24C3AAFEAA0B -4612ECA7694CBDFF876C3B9B5391D6EC38DD10166C3CF3CFEB02DAF1EDFB661899D3EBC2 -556EAD791F18381618D14F7B7B115A35DC0E8E282B8D1B4C9E68B09E9C8589837660444C -89E477BA7BD0CDB39EA9FADEA33A9990458A06660A30EDB737BD11627B68DF9445A34D4E -4993BA9E24CEDF0FD6955CECA5C9C79A340AB31096FCE9FFD84B2F49C8D504F55F413860 -7BC83217782E1A269E662DE79C67506F14AF71EF7302282256C1894AFA5DEADE51BF4222 -F2D0F1F4FC1EA7E128D7645E07941187D5CF65EC19667F2D204222C6958BF58525124ECC -17C02EFB44881DBFC89A8D5D73A05295B71AD83BD9C54ACF1FF0C542D13DD9CD6957078B -FC5F8A0BA938AB3466F44919BD38C5A0B14E899208598792AC43F532D41C6B8C4393DBE4 -472B5339C02B620F6D49C0B0BA93BEAC6373539881206C1F8E5A0F4241D0116737C4EE62 -575A47D79F1DE2569516D24FCEE9B7829CD545FE71D3DAE6FCE4BD780437E597F5849135 -D69B7E51E2D6A83FD3A8E67FDB1825D2A56E4BD7D6ABC291D052997EEDFF0DD618211607 -1D1CE4B60708315358C989BDE51C97FF5F2B2141893287F822D6AE440A811FEB93E0E600 -AF51552FE111FA4AB014A89EF562FA552A8CFA6E5CFBE95D81B7E50C04BE883DA4E460E0 -83438DF33E15F8D759FCB651B18357B40094736416124FF1D59B4B7BE4940CC5875676CA -EE4A30F059BC59596E693595CC889B2627B3392C5EB267863CB753908FEF7712BA9ADC4B -E47B18FE8807AFF106669E8EED7E0DC5AEB3DA3FFD8AD8D8B841626B800B5B82292D8A56 -D5E9FA394EB1686C441CE523407401BB4044C4C5BC448888BF122AC6D703AD6333EABC52 -C999312CB3E16FE4FF2FC8859D8662CCD6E35DA8B02BD22E776020C3BDD774E9A24EB72F -7231F1B9B3A096E4A47AF15B4AAE20946F8358BCAB1D5E3FF566D361508DE82D46038A28 -BC879A9E75016FE30A8AFBCB1F2ABDECB4ABA14CAA2323A5DA6C57A712EC6CAFB1FEDF0C -235E50B30127F62CF88E77362F6CCA0810E29B35EE5B7BB29920BAF6FFAB5EB3FF5377CD -A310FBD9AF79001E8583748164CD7C4138DCBA043B67CA3993C385B9F054585517E4F73C -C5F63F46F78235501F636BA4BB41BD0CA9BCEF79F0CFBFA446E09EF8C6B915AD718CA59D -B97A78CEA2195C968842C94B36EBA1F3DADE4872E3FD7542D6E477EE9343CE5F801BAE59 -CBE5A2F66DA2177389308B526493A523A9496C7C928F021542A1D6676CB3207979AFD6CE -2E4B37B3E3621312782607BE9F9598D470564F6C3E502FA2067C1DB36C0928D7491F5119 -72EA2A488D3A4A0BAAAFC021FC89DEBE05D7E992122A5887ABD7C88AAF0B12E3A0E6457D -E7BDDDAE5C4449AD3D0EBC9B0BA6C5A72C2EF5048238A8595B33F570FE36F1C9A3ADC38A -1EC604428BECD165520FE81172BBD2DC01EE2A923F88DF8A6CD992DE1875FE3C122B42A8 -2F4CD38D5336DE782586385878CEF7124AF8454C75E92B4AA8786F40B0414497A099F755 -F1BA0AB892066BBE83E472880AD336EA7012100B03D06E9BC9904651AA7F93B107EFF61F -6A2F7CA20240BF1D3E83B3256398CBECC74F8882E40B3E10C0535ED23A8214E19464082A -DDF3F590F9CBB75F06820A1DAF1DBBA19CA4D57B7CDB841980BE2E879E8D83E74FBB3EF9 -7D644DFCA51DAD4F342534160CF07F8822082DF31D8A6282711D849DA3F583B32ACB48E3 -0C130028571B9565E61BBF8253E97435F60AC0C91934C5A3FFECA5155B25455D59C18CF4 -66AE7A467EB5799BF2488B1568340F368267625F1ACB7FA34A8E582B0528FDFF256154C2 -F4F2D0F61A03D13A58E01548646D6B4659B4613E83476159E8E597546BD1F7902FD0DFB1 -71390A36A8389E25388391BAE75567201CD1A6225F774AF5E3132222EB969BCE588E1E18 -15BC60934C8E132627D342B1F7D780F9B5DC657A975387202EE08E957F3D123B4C115F71 -CA9CD0A5ED37C7626C8596E9A4DA7FF5A114A85E545F89C3694F3FB28A5224CA6F930538 -9B76D686F13C370887F75F88F50C98974857520DD8806736D034C188403234F1CEC012A1 -17F9DC0B03346D88401DFEA09A28944CBDF75E79EC6B26F204CD6D4F7CF02FB3066E7085 -BC35AD0CF7CF47AF38524C05B13E51A8BECD2B4EB4E9AA3A7FBF08A1E71A61B2ABBBB10B -714A0E46FFDF3FFEE96BAE962C10B8FD824E700E3ED94FBB1E03AECF77CDF572F623ABF6 -9D1AF511F65408CCCF16BFB2F1A0895D5CF069A78A3ABF523D4053F8A4F6DA0F3C6247A4 -5F2F6F21C964B50EF4615BF41283B6C655E55397A6FBC23249D306151A4E5F57C26AB256 -345B45B3D81AB1AA64C80F09C6000ADE9948C42E03356C0377EE74E17281985B8ACBC958 -EB9289159091E36937DF725063C434D30DADEDC3007066C7302D0B12F8CCCDBAFC57BB30 -261918964E42F08D1345D4018BB1E84E31B0F57210033C0EF479D1ED0AD35CB7178B173C -6AF59A4824FE5FAA88AA847FF999B3152F7C12F7258F7C5DA155B8BC0F166D9B6AD20188 -3154BFCC9E3B9B267FF8831BFB906C6CBA7D05842E95129D60B562678A322B94BC988601 -E8E32A6C507F02005BB1CB8B220A6903B4F621ECA9FA513FA4ABA25D107A39ADD5D32593 -5D8875831F02E4556E6EF278C01E8A7FFFFCD1D5EB4689A2DD86D291F473120B984218F7 -DBCFD434EAB3EF19D1A67F4EE9D239FBC0BAE239D0C634D29950EEB6FC06F0481A10B225 -7B80E1F0395CCE4C4291A54A5154FF1B0896D2E0CAF112D0E534F014FCD73082FE9E8A67 -ED23FDD4F7C37651FDBEDF999D44D9BD7D57EF6038598BCE94ACC2B6C0BCE60433F834E3 -524E3FA6028B6D5DE7631B10A2BB1C77BAEE351FC7373C175D3878502C2DC5D40596ED3D -8940052DCDC8EBE7F1853D85B06AF9114FD739E558F0FCA26F3817A990605F9C9807F900 -A18C71248300BCFD22D7857C390431356FA4BF993357647D9A094763D668B7908CA93E2E -EAB15E34E48B1EAF8082C6FCBA7DA5E9848B33BC59D6B50C9CB5108F3C356A45A854338D -81881FC425875EC59D361ED95CE99FD7A279A807671C8141A000A5419E8B9549F3617114 -6077CAF18A152CD041F94E113DEE2932F1AD09D55359B7B39F4771F15521DE58C311D143 -AFA24A92D36037968DED5FA71402B34442F9820F31D1C608124C2B50EED276FD06CB04B2 -3D0579FAC4ACD7C674EC5E6527AA352E38B35B14FD647E645CBE09C5D3EBC76D35D02820 -C91A1E422057E99A86EFC9845EBD5735B8F61A957B44C33F7CA9502E08F39E24111E73DD -7C5BF59212BE06698913B89C221944A9E539B1E79038B3E2D2FC40DC4D9115256D8BEED0 -343FFE190D6242A3054711C86A20E0C4DFE2C270375DBD1009A6ED640D505F25F475E0A4 -DBC0D9840A68F2E657C1AD8AAD7A260AD74DFBDB32B2C6CCA9A49361755DFBC09935041C -BC531A5924CF763C29DBE8F169BBE77A261B1DFBF1504A04CE7C3EFBC0E36DB1CD256AB7 -F40C272E2C3C217779A2D45E1A33E504A32183552ECB71EB562040C03D276A91590A286D -2A90E7A292B21AC7FC70082F18903E2B3246A66D95C47F7FA0099524F38018566485DDE1 -4FBB810C07BBBC487546F0C2BB295D1BEC35D797B0A6AE0616ED8465BBF239A46FEFE3F2 -E20F85E3E383C16D6F97044B6E4E80DB26953D609F8AE0FDDC92A41FF2A7EA7744585B51 -27F7D1D756487DF4D75289DC3FB822A16E1A8063D5BD6B2D7201DBF78BF4A34FD17D8133 -F8662DD9704ABE347C405D6111474E69C5F22552E4C6EBAB4A6537B46FA2EFADB55485BE -A4359C8BE0B2A696BB946E89A5AB3EC81AB9B584E6EC841BCF4192EF82EFCEA357C90039 -3AD2705B9BEBC894E42369F7CDB749E1A174EE4CB77454CE86BAB1B631899C547321C9EE -0499149D87F3FF59D13335D54177268569DE1AD675BCDB9281C21ADADDF54B32E62B3EA1 -2FC565A670778959ACB4C4A36B6FEB86B174D3FFB0B2617B2A84EA37BA5B4DAE6B7F1DA7 -36C01E446799F135BD5573B086D61B5D902097E93C9460E586BC8C5FB863507F7938B02D -90EE19C51E00DEFF3764A3483F52777644D3F20C0B99A8807F25FD6080373B09C68B45A7 -BEA9F0731DE751BDF4147C690A9E767DB679A8F51849D094DC1E8209EF159084231610F4 -187ED2875D1E93A2C977C3F1C86614B60F81B31CFCF2086E91C3A09456F376DF76F6F4C5 -6F6D96CA852C7B749255150C5C16453A84B9FADBBF40273B18FF8E61F309B649BE8C8BE3 -75F739C6CABCC9FF39CFAB9997E77507A7EE5D521C769F6A9A03472C51AF83D6682700F3 -9D1114A04992A23768D8547D668A9C1302DFE2A2011E3B0A101ECA1A41A79C2AD80DA863 -CBC5D77DB3FDA136ABFA30603EFB15F99F848F18B2B55D3038E7E7F6B691350D3C0D6766 -4D0849BFE0CE481B1B732326AB02CE44BB2C15122A57D42264349E72BD47BE006DACE8F2 -A0ADAC696138227F9ECFFABC0466C2EB581211CC0A24061CDB43FBF37A4E8BA1434A35E0 -2AF6B5914D493F64328F8590CDCD38169368F805D5B64AC0F4B996ADA8879157AA0EE3EA -605553CAEFB6D31B01F66016C64F7188556D66F185A29164AAB1ADFC1FFE71934CEC127B -147F36AF98AA9A7877A7188EE0160EE26705D1AD9B5F86D8B6BEE71C1BA240FC2A903D65 -0C3C69CCCDDF00222CB01141C0F03958D9BD5524D8C31D4554073E2DB0169849487244D2 -2A28987A82DDAA0CD060C8A8740F1A11509152B4602A6D0DDC4456849FE5E402F9ED88E1 -DDF8E5AD854B5FC77575AD955C95BD033D69F4A2D2EA6B6EF587EB16ED3E0F52E7578FC7 -F22324AFB86353B1EA4C51179440F2CC64A37A92BDE6A88B24104CB8EC78C660A40E43E0 -27E0EB69D813A3C29C9C3614E6408532FA474CF9FC5AD498F8335DF4A04BAD633110405E -EE6A5E40D6BD7E23337B1B623735BC3130720DFD1FD1A86C4A90145EE483728278C48E5A -CCC333FBE140DDBE0A28168D6B2BDB902491E0340DC052C28FEBB140B85BF1FC4DC35582 -1752E935381556DFE0A1439A0BC810F9527331CA35508E3D0A451B3D285D37A25F1F949B -9C9ED1BEF8289E5AA1A3BA045CA7CB647F1C1A528D85938E04ACB1E7F08F5ED3D18C9E86 -7AB607E8BACF757C98BB71878979DE3862927977A0CE431174DF24872B21988D6AD35B07 -42C01ECC82FD805CBF22BA02CF596876EE1E135254A8BB6DAEEBB2BFF9911EFD7C3A25B8 -55B95EDAAB6F25A31BB29BDF2B0FC3E0F4479DD96BEF601E4DF77A459B73B69A9C55A87C -D63851038A7ABCC475BBA0365C4CEF17A742D1371131397AA139032620E16D89B3BB7A1F -7B018BDC6EC29A8FC02D6C6E943EC1B1A718DB6AC51BD7C5FDCBF2BF792CF9ADCE89D130 -DC5C200FE8625BB13A02F45E06A53B7D186838EEC83906E8298CF83CF5A28EBA36D67F56 -64EC006E350266F7D2C81ED295F572CAA52FCBCA9B605E421DF4E9393D1E775838992B7F -63BA394188312C75E64F9BF0217E6E31905945D27BACA0693E0660563A0BE2868E22A604 -C901BD00FD8E9088C4255B2583EEC2417AF39CBDB672845EF9BE24901D270059E7EF3C99 -0BDCED89538A8CCFA5A0BEBBEB671720576DD349566E591ED760FBFFEAD66148F05D37E2 -0833FDE02A4E85F2CE08B0E03DCEF68D454E135F8F07BF93724E0B7E0FE769A0AAC5B513 -F4A763347B10B50B88792E1CB3E6E948B75A8835DBCF188436153A2C2B44CB18D8996FEA -75324C8973D1F0E4A3942E2A05E43B3C4AA46EF7B54039542193CF76CAF775DFB15B31F0 -41AD173F8821FDDBD7275618B37F2693A29C9A990B7BDE96FC532242929F81B1B61025CA -717236C5D41ABD690EC853317D21B20C2CD6E9701202305CC34F5855934E03F1F58A0D32 -D73602B07ABB1904173E09D799769D7127B665537FD6FCBE10E725CF814B83475FB8E443 -027F490BB8488157A4208D031ED3992E2E0EE89C5E19AE11B16E95452F86B04C3E233A13 -02B300C9A21E2D920B49DB479AD034860B77C8C1279EF314FB4073B6077625270113848F -BFA4C6D1CC72D3DD8DAB5298D5A5BAF7E832FB36B13875D241286EB56495FA62909539F8 -9D043095F5B32E10F59B8204F0C598FCD78FBAE872D833662FE913E595E3A2073A41CB74 -5AF21AF5790DFC9D3CB011FEEC385B5DCED039630C8BEDF0790C235CF0174F3DF205DFC9 -A621B1A32351499845F888DCA445879AF5871EDD1572FB6B07B52A583A288434502D0333 -FF418B95580F4DE9B2F5BA2906F074AC91F566E5E394AA7695A161D01DEC146BFDE0448D -E6DD22D7A3C0BE7D02A29EBE15AD1F302299D673379CA3C2E500C573B8F81E0ADE5F59CB -BB8E0B5EDFFE4797C763D4FF7CE0117EE17E80CAC2A3EE7840C03867DC19B51885FC6ACB -FC0EC204489CD1A6ECACA8112FC1603C254E40049812D1BA5C561C1224BA56B97FD66DFF -C43D96FDD510AC6DF46A9C7AB22FDD5E9318C4A5F598E34A3E60989577333E2CF7AF6129 -FAEF2704C1C3B997691E484675D62AFCD81F86A6EF5FA4DAE7D4F690BDA5E35D0C3EAB49 -A377A2A0B6019DDDD8E293738FA7503120A91AE095F613B3F925BB4D433A67090AD6AA88 -37979DC1DBE9FD46CAB54F1D9AB5B9E20CEB07AA93346801BF8EE52977FE36EB1CC51587 -FE57ADAB168CF8A7B95665F65FEC3F3EA5920401402D8D22A3D4000DDCB5D06C5A901430 -865872360B37C1277EA4C31B32C16C9EDCC6162049204A9A028943915A7753F72452ABB9 -901712C494B0E175E27B99F6F34A232A826ABDA15D82D4FD0AD88BA50545A5D9A4E3A90F -51987EBFFF48CC52D8E7FBF1121DEDE46BCC71F7F3941EE02897013189FD60D9F41C2F3D -86A0C693DACAA72D68404118DBE5524D07B1D2EFFA1F54EF0D0205FDECE28BB1080F2112 -AD17E04A000C581BDBA02571C412DBC9BDF10FBFDE1CB328239362BB008ED70FE062B84C -E93030327374F47D62D4740DFD23B3F1FBAEEC619ED18446690E0339D2BCCDCFE3DA5D5A -215224657F8CB4587553B7344A4CCA78DF1D955679F3C308317D8EC48269D5E1A9917E0C -46BD6D7284BA185DEC43E31CE9B148CF708C722AB59CE7429617978F678E7B42B6DAFE8D -CA1690208AF9541B8EF5C8057A459A6D6BB3F0410DD1DAAE469A71B7A416CACE53E775AD -CA8787E88CEE3F57834B13D46A5DC1215DDFF7668A9CEC79FBBA1964F794F71D7BC2567B -10AAA3EFBC22781C66B3C89B7973748CC35978F844A5EE16CDD95BD4AF3C6C63C79577A1 -20B893398A583BDEFC646E917250AFE307E1FB053C3A8EFB26CD4F65D58DAE816549C502 -DCEFE24A4DDED6ABC44FDFBEA9A92B2F78F20710997E683F8D9BDB7C603A9204CD90E932 -7ADF5B551419354EF67AFF7225026D2703874F841A034FBCB33267D8794C1C1BB9B26F16 -04BBCEE30D6D2BA30AB3F8E03E0DB4D57190A570686C420FA4775B5F8D984C4C7505DF4D -309ED3BF16BB32B62241928BB3D978E10CEEC6AA72A00F786AC72F6ADC5E1BF1A234B6E2 -06FD0F6DB21BBB5D0D800BC43197CEBAE8AF770BBFAD4E41488AE5A8283EBD2E58BB4BC4 -5DBAE530D05418381BB610F5AD1AC375681618A7913CEFDB93815EAD3006729FD89DF4B2 -39E5DE1DCCB4BEC942EDBFCCC34C46704F5B31BEECC45558BD2E2DF554E6130112161BDA -86C779B47D9E79EE1A6C41A722F1C8710C5470F02B98B6A102A962E456827E7A8E9C2527 -5F9EF9B0D3420A3CF1F96B798CE32F47C076A1973AA532ED91B44B6627D5ECDB94E488CC -A0E54247BD99B1035769E7DCBC91BA655EBC0576E42738B7BAF5F7A19EFFFB78E0DD567B -51C9064ACCF00AA9D6AA5F8EE73AC3FDDC1F501DC67D9257629C767B9AE582A1BBEE8C0C -1B4BA4D5830FDC6C3A3D164EC1B30B8EA721ECDE61AECAF5DEDE7CE02F336A22E302D711 -AC6B83152A1B41C67A5D3EF767153F5FB882D0448B39B8507ECEEA86CE74EAACC8AC3E78 -E20FB23FD92C81D2EBD9014530F0AEED1595039D94AD48CCA8BE1C77233A9AC19CAF5A45 -CE5E96C5B2A962E8DC39339A2B10975C18C5B6162226221AD8BB4307F64E2B2C4F01FDF3 -1A6DC4966C9D6D2E3D5E92F0D21DF7779E35404C97B632DFF66716FBF8993294CA6B09BA -8F7F840DAC99DF3D75413A0F417416C7FEC264D6CC58355B1290692666A47E47F0BA3CFF -5DBC8EE2F4FA068D8059C1CF153C65BAEEC4F8196600B9D5C09DA14C8D5F87D88FC7DFEF -B797D33E292D4A6201AC0DFA4B50285805501F3AF1E2A48C3493FE2DB06589B0C045B0BE -5A2C5601F2F4644E6FBA9263BAEC6008760AD7833187540BDE0DA3EC762393EA778DF052 -BB978B708C7A2DAC5D62B2B4BC6EDA8DE77E548366C34411463BF5DACFAB701D0F64E937 -F5188E46151F8D47932243856F3727904404BD99EFC5F0AC5DD895CFD4067B7F338E2DF2 -BA69A84D26FCA6DA0ADF101669B9B502DA75D202F863D2AB8F821937F180352211F24835 -707B5D821DD71A74E4B9562370F2C61A228FA42F12983E32C15B13AF9F2D59CFE9FFE1D2 -4412F40E1BC6D90E8D943DFB8D5A36EFBDC7836025D6193A8B7AFDBA1EC3455F2EC95A6C -BCADD64C7D41322C98479EFF511BD4BD70C06EAED0DEFFA2790649282EDCC5F3ECFBB70E -7D62E1184DF3A46B154DD1AED7BA74CA7841DE08B4DB92DCF4F1C2EA54738F2BBD8A7B70 -0EC21D05AC8650A7F1802EF604A9DE97E8BCA273D26D97972ED752E3E9CA7D3FC11AF401 -D01398DEF5206AA94D0A79DE65F02C3E9A02C2DEAA900017DB7C0AD39F93BC2EB27F2E64 -3BF0FA8AE458C73B62B7709AB58D8AF25511B5C3FFDC5F45C4DF09400AB5E69054AB6BAE -57D427BFC6A6A65DCAC262E99797304D660B672E72BF8BEC5FCFD074A5D1E949634D1DDD -3399A80D693E3494DE56E1D0CCDD217FC6C6A2F4D6ECB7E3636E438ACD4E6B7166B27342 -2298824C5C547423EEBAA5FAFF2FF810A73C2BCC057F7FA1E96F21D665D377F727CA2FB8 -93307ADB216DB69824B72312242DE1105C4D7B048476E64C71F4C4659F084916660CD035 -85B922CB2EB7FE0E940A7A122313A85E0AAAA7A2699B4D1227D8A2F8F59B8FA5F6CFB63B -7ED2F9AAEFB6A71D186815A0CE5816A787E25288A9CCBCFA886423F776DE6C09B17858FF -CDBB8A52CD54BDDA98CE2BBE25849A2B4B113B6B7044431419512A00CBC8E5703E5A4A1F -954BABB0CA465884524BD70CE67D6FC9E2BD7E0615DF712866788A17AF26D842CEDC9EEB -B0A3061963958B9140BE41E74B7893265FAA57FE53140658DC931F0B897D0E857AE3A337 -F04D884ABE8D8E1DF1632DCFC2BB65E4BB2791B215957D5EDAD04A4D1F4372414D26CD68 -3CD89B893EF0CA895C2D36FF87A1CFB2E9F1A628CD59432046022B3E44BF2B5D5DE76F51 -5165FC2EBB07FBB23F262C07066D215DC73EDF780FFBC54502E57C69DDFC77D9896D3824 -D4749482FDBDEB40058FBF293BBEDC8C7AAFACCBEB160334D29AA7F61F34B929F020F8FF -17CE610B0E0D1823DF605B2E145C9E78AF8396E4AFB267C7679ACB0B7BCA258F7AEFBDA5 -E49F3C3A17F0290F9DC6C5F51F193E2DB779CF8081C733BA0D7FFBB9EA3A2FE3ABFB4782 -B2510CA124ADFE0BFBA82C46A0BFC430C2CFBFE41DC3DFC070FA9DB38F0D33982127C8CF -74AF1001B096849C8A518B6CA05445858EF78DE8B3B6F3019CEC8E10775EF9842DCB56AF -982AB270C89644AA55B486BCD8616B440105FA6C34298422C994EF6C30C1574ADEBC0F43 -85029231FF5FA84AAEFAD31442120059A7A1D24BB44D14844A039F366ABCA742A6279402 -7B53DD4431B167F07AC0EFC75ED8545431371D5FEEF2E51649D1AC862FD5E8C18ED86FC9 -9639B861D2B502A2B5F75062891ACAD88D39729CE2CB515DF3C49413A974476A515E3F15 -E071A6A82D5A51036FABDCFF62659D0B54DC1B9E68945E87A4CFC0E4D285D23BD9583126 -4D2B4E4515A7B34F83A077F848306AD71CDB2B5E6F701DF84AC82CE1096B987E2DA09727 -CBD0DACE976AB94EE6B133C09B787C80F275DA36605CF5955FC706A332E3140B43AF9C02 -9C23C489C5C15F77F076C6A21DF7B91E9249E93854406CDCF2EAA68DEA68BABDF5AFB702 -CD9457BC4FDEC0251834A5FE1EBC40D1C8F21C3C56B2558E1EBA3AFD3E0B53AC7793E078 -73F8A219C6057DBF6BC066367D953F44EBCE2704D2258344AD65CA865CAC50085E5E321F -B66E4404028E313876B65E5CCE58DDECD17DE76874030B63B267639147EBDA692745AE09 -775C4CC4C0B44469A01BA55B87913D834952541CC527D6D24238A5CAA83CDEAC1D7B5449 -7B6F9F57E0AEBCC7EE2DF0CECCFFC7FDB46DE41FA6E6D41AEC58E9A2CF359F9762ADC653 -5C52FE93E9FFE3225887009B596AC2B29336E0EEFF29738D4181D339F0FBEF72D29C750D -FE1318CA42C5393D639E7650AB689225BCE2072C88526B9AF5B970CAAB8331D89B888345 -BC5E839314B671E70CD895F56D945E8584A7A956EF105BCEC436117D4BDB3791A741B7BB -5B2F0033241EC02B40B75BBAA4C99D5F48FB370569C6E42B8747476E405B9D683D2FAADC -7C4A02FCB91C654F47C80AFFEE61D2310619E72C36695090BBBBFB5E0B7169B96BDBC9EC -4E8AD00B36B4FBB0B849CC04675277733D2FEF6A6EE9C83BE4900D02B95B516DD10A53FF -4431B3BE8C68AE823BA121DBC6C22470BEAE5AF5441CA8208D3DBBC3C444704E7644F8C6 -11B0890325648B2EC17FBAE41012E7D49566E5016D94336D4C701DE2805AA001E79C9032 -C64838049D8D065A171C11F06BE58A478B9299B3A517C73CE84EF38D07F291EDE3535CB8 -D769308C2252C63839CCAC3BC9E8A24E871D90398F3187E3557E40A24FB1C61FCA55BB70 -5EC3B1ADE33F0C6340338B197654B373EF588D43E710869321FCCE8A00596981C49B185C -DA92F64E0A65CD32D9448491EEEF78E4F410806EF4D6DC5F7804E99B87E640CFC46B6975 -AD18A05C470D233D23A20B4F85E8E008301D9763C4CB53A6CB6F380A439DDF64E4F69367 -446A0B57A0E98A6ADD0CF0CAEEC82BDEA2D130AA246EA0E4FA2E8DBB4459D5FFDFD7798F -842CA8BC7458DDAE4C28FF65568617C25E0CE82CE644B3F6445C7408E257FA1791199F5E -711023E5BC7E5AB961E867B06B83418954EF9A59EAC6566D572B4E97B5C6750A49636929 -562C6E0E2737F5B9BC06EBEF9FE62D9CF4FA509A42D192482B878757B319F886FA9EEF7A -563DE61A0BABBD76B9A9FC2009A9049FC6662C32434B6C8F4E410C2F5A146EB951D25138 -47D03A64A453B748A14D2A2FC9AE56A9585F1E6725ECFAAB26E99418F8F2F944AFFF32D8 -AFED5E292F40728B8804D91737AA9CDC05485F9F7031841B12F431355EA522C674101B83 -09CF71D8D27477286DC05428F7E8443EC7E4471CF97ABB18753524A79A1B331CAB1E3FE3 -6D19BFE3724777670FA07CAA0A501E1B5524E62C15D0B888414300EAB0DEA137D43A0B70 -FB6563163E0AE68D160B96B4A71817DCBD24BDD8FAD76ED2ACF5E0CE1DBB5AD9A1AD4B98 -997987FBB15346F93053314D53CF4BA6A9FC6B3EEC4E5DE20393D00A6D69FD55B98E3045 -C27469B46C39C40B0F5BF53DC1142AF67212F469FE7F7334A39CF19443C1243FAF6B05AD -1FDC50457F06D14F119EC724269EAC946793DA2CFF0C1AE736320C5F01B51F2780277D4F -A77680C81BCB7FA34A8F4F63F07CC619DB4BA4AE94420E532E6D06558D8B0D9299DF88E5 -479F1C82178C7FDB90830CEAB719A0EC4DA5E66DE2D4B97F11113E0DDA557353222E6329 -8F21D925AEE6FAF6121AD7F2E7F805F88901E53E353152729A737C197937EF857257BC70 -0890EABC66A8DDD6F4636DF744612B2E744BCA5D376D2CE87993132742B66FEA1AA5A4D1 -0A5DB79DC3EC04D88B5B5CCC988AD647B7719AFF1F2FDC55B7DD113655F19E6D47D2CFD7 -B2BDF4FD564A6798D3696B5BAD5F7A3E8609B9D9D0DDC4F32F2798052ECF1EF3793B16C1 -F489004AB008CA729064EA7193D2AAFFA934AC2DE6CB00FFC86A54B11426A97A5E161899 -4DD7FD85144308CC4C376272E86849BDB4351A9CB9BAC62C53FF3D06580CD2CAC229FDAC -CF8BABD15E1D7D81A2388597FCF2508AF5F8D189B5E5A86441E73002DCE94CF0DD953575 -470ED6D6AD57F62FAB4EEA0EE65C5C2FFB9FCFD5F850DEF261314A155A18AAD1B47EAB24 -FB7C0408B1C3DC80C6FF2D6CAA3348BF792803DDBD9258C694FA9A4FEB1D3BE1E22562D9 -46D3BF713B8ECC1532BACC2ACA978761621A122252F5CF0A658C06EFFD96B39B7EAA7C0C -E691FFE170A91871B6DED3BAB734E733ADC503B5AF97D595247FA80B81AF8ED77F99B192 -0731917779642446DA30FC7DD5A5661F9268302D2B812D750A3F144C89038A6F573B0C62 -EC227C3C5970D8EA34781CF49E56E1ADF0743CE23940279CCDD27AFB7BB7B740F579D9FA -B7BF912D52F35DFAA22B7D182C022E2FAB7BD0D90F7B6A03D0D6EBA225C70E07CC00F2A4 -599DC63A9218C17AB08927C0AFE57C6D3F0E7E2240A8E0C3CC6CD9854BE51B7F69040BB4 -ADEF206D2110DD52D5746D0085D583E67DF440125C26EB27BB8EC054A2AFEAAAB3139B53 -653E4C82D085D35BE137B6E30FA4C81EB3F968B12B2F4DB0AC653BB3E13BCBD9994C47DD -99727A7BB5908BFAACCA7EDEC566AB58DEE6B4CA521699CB6C3C7460440A522145347A0B -9B572D96702B497B8F9C3EE612B3445781F3FA7AAC78DA64950EFAF975623382BB6FF724 -3B1078C354E6F4CFE12BB8F374100D8E9033460B5911D4A18BAEE611272EB961EDABF97F -F350744757DA2435292D03C54CBA103EB72626EC2680077B5DA99E248BC7581F791F157D -0F0A359070827288F6961A8B42F98C948AAEE02CA29166EBED6F41CC2B14274CC8CBE8BE -70EACDEF5DED806EBEF4FDB794A1A9EF45E6BB01183CC4058DD5D6BF33CB6A195DC97AAB -72DAAA73A8922281DAEFEE6EFBE9E66F1B4C6D5A72830D9CBDAF7CC287ABB0753DBA936A -B515518C6C121E52BD84359EC983A7DEC5E395DBECDD837788A01387CA0CA84F6984A9DA -4D93CB543AA1101AF32021F2D2530300C6A16C7B27FC6D98E8E192AD089E9D10F10243A0 -1403222518D2B80A79360F81472FBAAFF0348BD16D8AD6888CF4971C2B61A8DA0A469009 -45F508DF6DE8F7A061EE437A227887D1C24BF05EA03A0B79CED06821B6A53F8275C885E9 -F5891E8DFFE67F22BDFE05507F478C90D8A90424097FA970E2B5C88820520C79AD9B539A -A10EF6701499CB72F33021E5066D86EF1B2AEE8165CAC5A97E3C20E24229C072A41B515D -3B1AD941352CA33927D63A7B0065AA432994EF31520C80F4FA3E68CA9CA548AAD31A64E8 -D383F59BFEBC0288E76332EDF7DCEDBABB3E068DF02D19FD7D0FDAD1BE7EF4947524554E -EA87550C141BF3EA6A20FF4834D2044AC7733FFCBF34EE678ACA19A3A8FE3D943C2B3505 -242111C2B6307A00989A20E8CB7E4267AECDC4E6F5F9CD70568C5AA8A4E899E404C7CEED -9989C788AFE029340B6A3D6376476181D19844598ED5CCF1AD2CF4A676FBFD17C0EF5BE4 -66CBA814647C2E0B5A2D85F3D3C8C16242848ACC70063D67918F800424305F2140A76BE5 -AC8A5CE0E32E26618F308EA578CDCB1CFED7CD12AFEABC6F6A236BE927BD11AD0A961943 -56C174C7881373770078D3D9BDF23CB838C5D64F923EC5831B791D5604931A8834AA6D95 -A79FC44C7DFC090CBBCB177A42A22E6897CE9376D17FE945E1E813AA473CC1530A7A834D -0EC298E73517624640BB35203A089D9483D047A87CA2646DBD18EB02BB9F0EE711FA83BB -BE07B54F1B7AFF9F36575BA99F81F75326F59D9EE26D4E4F642004285B6BAF192396F4C7 -731C5504593DF687B274EF80F27105F4569AF2EF4C5C5E88D476A73EC4444ABAD8E9AB3F -950C9CF21BD78ACE310C328F988CF22A7EC165E724DDA3F25D403B28A1B61F668C013524 -32458C657E8FA6CBD2E6E91106AF5B9C8EE170FD1FB323404E4101CC134FE8F0887AEEF2 -3013CCFDFFDCFD5FF60897B720A00204E8544F51735C976EC497BDDC085BD209F756C77E -296716650CC169558746490D024BD14FA54EB4E0CB75E8E91FA2E256F3DB4844308C7998 -A0EFE04FC6B14B73A43AE16D586C6683520A82286BA58D24ECEC212CDD93D2810EB4856B -13D432AA6CDF05600A12C7FEAF7B990E9E8CBB8AAE023FCBDF953180AF6913D0DE5B8660 -E23AC2B170320467ADC89CD584E9A366F063ACDFD5FD44E5BAB3B7167254ECFB222AB3FF -2187E43CBA6FB705317EE5DAA8D9F5DB83957CD64508A61EDA6B5D5BDEEFB2C6214DD059 -8AF10A03A486022A8DB111374E8442CA13D467BE84BB1001E7B9DBCAF50F767330FD3F62 -A310CDF232600D7DFAD998A0EA10EFFC49A702347E6C23BE9027C2BDE2E9A14CD55788CB -0C8B4891930AE2BB346CAC0A2CA7C904D2343316A6F4202E22D4E448049B18EBE76FE3D9 -7EC95EC99264B6F938108A36CDC5C4D7DB364F89E9371EABC18B1CE08CE519BB2C4973DC -4C0ECA366D8C6CC07A2DD320B997D5987297B330703D2A2DFE33EFAE86200B750D1A2D2F -762E43A94523A2136492B440F6551374F3591FCE4D37F7C192C592133B3315D3435A9DF0 -F2F3F621ADCDF53F9CEB8E7B332E701AFFF13641C88DF71858352BA45506D267877FDD8E -BEE4E80EBF692631C7C7133012E4CA6082B90533BE3082C34084385CD16C7A4B7123EDFB -66EE5F20C2C66226542B98B437C6925E7CB65C02F4C659DAB78FC4ED155C312DBCD5BC7A -F588D049D52655E57D3964D3BB713C6F7B33296292BB6273D626EFDB0CC6E0D346F8383F -315C275FC9FE745C9CC2416F3E1B896CE9D4621E0B1798959434E380E5672C9301474FE5 -C50B8344DC9BAD4ED7A57F965ECB1F9DBE601D2967701D4C083529B6DE730D9940D03381 -EFCD0F2E5632CD6948F1C7D3B624A248786D69E581B916263DF67B7AD6C34F034B3F48E4 -D26F64BBAD4B57E5E3E4B11BBE3EADF529E0473547DFA0781ABACA0F03AEAE3C14884A2B -47AEFD5174D2A5F45530A8C9A0B7C66DCA9CCB84AD031574B6D3FC3E6F1B0D794D061CC3 -3FBF13B5CFC934C0561396DC77DC2AA6FE3AB54B6215EE21A65582A8A9585AFA2CAF8194 -B3B887EA4C7F71696F93642371258BDD862C0CF23B819B194777DA8503A584CB26B849F9 -5CF461F3321BBCCBCA5DFCB054837FB3C288ACC2F394158F2263A8D4956ED155081F1A93 -B5180BFB3B694BFFD214C63D1CC0AC82521BA89EFE47A573D8FADF7C7B31CC98ACB47E9A -517CD04C18F8A8116592704192274FA9D817D49AFF1BF2EDA8273B04A86E308F51336DA5 -FC70705D6142F000986593A7BBD524A4A03F5A1831E7434B0700B89EC3D45BFC3CBE0841 -06E053FB46BED0AE359A76CFB808CCB22DE78B1A88415AC79249BA9F9BC5BE2C3041DAE1 -9F6B46545F534821E0BF703A6AC49F4DF2D24A4A90AED84C71F87799BCC37ED9FEADEF35 -97ABB6D731757C04C00002C40F34DA0F35E39F6330A1651F89C321627DF1D1289C1C6782 -35D205CDBDE6BE95F64A2510AD7CE06D51BFB98E7AEAAAD4E2AC15E631BF136E4082B01E -409BD78C495C88D3B62E3112B7B72268C4B1BF55E4FF2EB726ACD3A99148B0D0DC516294 -1E9B8C97C861AD1551703D9B1B17D1613F8BA6917B319BC2910728C5B46EF2CF9E1A06E3 -645C52A5D4F72494C1C18F858D211D2EE721FE457969D9A9BAECB4A0058780025142153E -9B94CF1B20B717D5F9AC5BA9271B4CD61628402FC3883ED1D43BB2EE931614D871E7814E -5ECC895E6CD9BB8A27F55004E7BB3E4A09B1D9C5D6B49140BA231B867F68F3A3C9981BF3 -9D9BCDDDB6330C8329FD52B1F1B6A7E392AD3EAA4D8E63BF3A895365FFAF54F297126CA6 -3FC07DB3763E7D2B79D2974BD0A380AAB25DB48F06BED0CD275640E5759C966A22E2437C -11E92131BDDA040BAEDA876D8861FC551F32591621A14BE6EEA790B77752FA636B8A627F -51428CD373F2ECC19DC714100A200E098E262FCDDCA6328A18B060219FF495AD46AB95DB -2E33D5A697E5D25CB5F0FCF988D62C9AC53E415735BF0DFFDEE23ECA22528B3D66DFF37C -77EDA16945BC694775901CFA106809ED3B59312B4A1023AB13738FF47921A0601D0A56A7 -4FB9F6B73F1564EFA5F2A31DB04365A577A1D9DF9FFFE6A4692E2ABF7DA3876BA90B7FB3 -168962EB38E03DC5E06E1633947848968BD649CE9B3064CDD5F88477195EDD4018F60FB3 -D2BA8190C9B2165FB5DB5AD79240CFBA8D4B2DC061F5392759EA162CE0FBDAB3D8EC991D -3238D835F27F6440F50942305538B3EB8B4C9CB46ADC7A0DEF82807C277B9CDAEB65B874 -1E3CCA532A619367426CAAFADE5756F0C22E6FBA7CA826E663ED6716308482C957703BA0 -FD4322B105202352E9091B44793A849E17B9D4931D7E4FFBAAFF32D1705FF5D82A878139 -0B5CBB1E5E00A02E80C299CC3C9612FFC9AE200C4F4B919E958039D4628480A7A0279EAA -DD0D28BD5E1D07BC18D66FA86EC9843665066045DC5DEE15146D9B4CEC6B0CA6EC946967 -3A464C46BCFF5451383B65B62D348907887BDD77931996B56645F118E9392215662998D8 -51AE73BC084FF9931D22E5012F6D18ABF618DFB01CFCBFE1A2C53B61B84D3B85A5D04196 -FC8A0E507A87560ECB8E2DB3CA84A2C97AFEE1005F6A44E00E3924527B1FCB8A3954C746 -D6F0E4266940814355AB8B57D3AB85A89EFFD1E384FD8E832E6A846D6B8DAF0C99C3803C -F9BC1CC4A1B611DB8B3B3F1763F6BB877952ADE48CD9BEDEF049137CC2F0D859CB4EB075 -2A1E581D835921533C868480469430E3AE90B9C965B4130B20E22A060A182827628CFA56 -FBED3BE7A4C078E939BD9F79D1A51017DB08B27472B813B5D94CE9CEDCEF61AD4AC1DFA2 -37261EB3360CAA70EB0AEBB1777928B2199791EB0F4E0DA70F0A59DDB0B7FBD49AEF255C -BF51C0F35AE0A242100AB96E0A2B51F82D5413FA7AA2C603F913066AB8AC55FD474829EE -82E5DBC360130AF5FAE5EE9159B5E09ECE9678DE75A50F49EA5C24FEA536658D48417F7B -5DC4737FAF73D41EA93B3889B9FE272D79788E337120691A76D0820E24F5657DF5CF2BA4 -BCE1799E533A991BC20CC52CEF9142186FBFB77E214A4311A243CFB5AD566995DE9CF7C4 -06D4235FA3ADE98D6C6CF3DAA3AF13106D38C4FBA7DD764FA38225DC7C41BEA8E87F6013 -8D320F004E832F52EE5D716F21C47ED0BE801523BB94D9691B393704380A58722C70E0CB -F70EAAF9B5CABA0D298A0152E246CF19A63DDFCE9D45E691EBD404B4EF6F14B3AB70329C -286C3CF24CED4D7591E4FC548ECB3B7864677028CD1073C949F6E334E528D62EB1EF23CD -E94DBB71E289FD419A9D51579BEE2F1E66C0EDBD29A32859F1E5CAB29264EC3D6AD03E0B -7BCA83FE20945CA48A4BF76C1F89B747DDD06BD000373561D123AB04AF26D1A785AB792A -95ECEA3DC6F5E36A143204A17492A6C3C9F974D73919F4830BC2ADF839B83753C3C58011 -BA6975CEE5655357AA6981C18EAB50DD25E4956D2912BDC0B401BF8E3E719D34D4543E00 -6570D7F59EE1E6E683B53B0DB9A8DD3C188FBF57C719C8E1A35EB957151D5CA1208DC55F -F81AE455B267013FE1515015206F1DA5E7F9F56C1F0A2FE55C1724CDE3E00C9FD055F198 -ED0E75DABCBCA26D558C90BEBAEF6F67D9DBE1758FA9C67FD49528CFA39AA21A4CB6D797 -C5E81AAAEADA6E7EC773F9C5ED0D2B0E722BBC8D449F5692E6FD2E90EB3673648EC34907 -8D99E469FEC7D6F63606E607BF946C78C1347CE1CF45DF42036AF0DEBA6AB19ECF358DD8 -C691742D3A0FB495C0947C3528B0AF579C16598750E475F169C1A36E8DCB33D2151CBE14 -52496F4F9414BC8EFFEB38D22714D2388B56035A4D431EF4D07D126CA898324F2BE44E42 -BDD930AD74363F011B2EA953CA48A7065C5E21B0B0E9C87FEDCFCA17AB6DEE77B167F31F -6E157B289EDC38F47D836250303B7A6662825E184A464B3B6BAF6A31627EEC2E932E617B -16806DAF25E7A6CEB17E89C602FBB0191592BDC0244293F46E0E698281FA9B697EA945FD -9063410A495A75AF971B7F50331D3FE964B3B2E7C6EA890198D4AB7D515F58936D7104AB -67013017B699EB3F3DF5F49744076536B951160156CB7F9D64B035C6BF0C3119ABACE506 -F15605840976E567A1ABA8B94B3B956A2982806AA50413B5F89514E0B065A6710FCF6173 -5C91FA417686324F69A98BD4EF2B0EB1A3CE20DEBAF35E592CFC68CB3F1640B91D20D415 -08DFC28FC3AD0143A8EB9BCDCD2D2BB45844D387845FEC9A6C9E26F495573F7435B6C62E -93DAC158FFDB41A137F5DAF1F8FA134C26A1A40BCB646E26A513C76A6EB07B559522863A -6373062B7C033FB23364CD9540C146CC7D0C1F33A137E5BE097F7FDE6281EB9B9C2F8203 -6DC40494242533C561CF736393C54CA3306FB4974FD76685D26BFA885CAF41AEE3B4230F -DF98BA4EC7646D3F25A8A337C557E4AD260C6246EECDBCF0BED340BFAE2A0BE007640D51 -A583D0747A5F354406DF9D3544CEE1A8E45E0C3ED5B5727171DE29E75ED1E06E4B878C08 -1EA5AF1FBC2CEEF821380656867929E482C13FE6D3FCECA67CC16450E0BDDC5996D7B281 -7E15F29F94780F3E4561A3F0D53DCAD7295D68013E2A12F73E2887F500C5C40497802B5C -69FE8CA2F4EBEC94CEF708EB00D4E44C73741A432687036ADDD9021FC35ED215E742BA4C -D8093F29B90132352A60AA49F1A6351C80D63BFCDD2C4E136F18D605FC406EEBD81FF609 -F396669F082D83B9E1C9573A21C8BFF715FA8401CD7B5DF1BB56C709A32AA27DA08F2BFC -4CC9D74491D7452C51C19D585407E97414FF616B8EB4FDB31672B93EF09B1478907D3B22 -8AFC23A38B48E0B1AEED91089548C135CF3BE546F737BBDAF3A3DB727B8AEED13A2CE344 -56ECCE70D653AEBF7B71EAC15074263FB58C10985830EAEE832E65609A6651374DFFB88A -CFD2FA6BB43ACAE247BBD826E54B6F6AB6DDFF4A51F5DCA90062BD3E033AC713FB95862B -540B9EF93991984FB86936A0841FD6491989B55980D917A53663A63952B9CCB826ADAB9B -DC71EAE0BD3B580E767F7CDAD1E0EE09C9A5F015610FF572B4778D19260E5C5154AEB615 -F494F6905F04B1420E9C4531A7F6A8840E79A83AA20DC7BC86C9F51B0D10F6F0DA001852 -FDFFB7E60D675CEEAD92F73756A91D67A760145DC0EF8565833F84C50D0E17A3A1F33676 -E467012444D09186160B317F0D6063194E46E5A484CEF017C919D3E063AE2E79171D937B -1536CA40EC4E4C71FB24CC038B20CE25504189986C5195E7C89D71DA60F40C8E34BD62EE -44018745746F174D3E30E8F2AC3CB4165474B456A8E4BD62244C4698B6C18630122561F4 -6A5776B7961FE532C7DCCED058CDF95197466C2D6B5ADCC3A2BB6487B5DFFF6E95612798 -18FB8D213AF93B346458431C42C697F3E98EF51A234B8D717718B7EC360F181BCCA72A74 -C99FC0BE536FBC7F71B32AC4F85035EAC720C49C03CAC855FA49D1BEEF2799B86D21F3DE -5F3BA47568811A2909D19CB06A3B62A285744DDAD31745AC58AB7D9BBFDAFF5E86EF4806 -5BA5BA3E78F6B85DED5261177F0B7D20B03ED496B3957A34A4ED1D493FF084653D014BE4 -1DEA598AD3EE6907A53828B49DF06C3BF1CEF5AB6946BF2E56D646077AFA325482FF16F7 -93656A895E24CB4263E382CDE6D67C5506FA7E0BD0B20BDFE0766803BC9DF615E456FCA4 -8BC2E2AD6E4348414F748F031E23854AE6FC92650A55DE479AFAD409836481881C04729F -DC49DF2D9FC46D2BFB3B68DA59CED1280D0A97C7BFFFEBFC72E9BBED16C24B734343C111 -4A999791D052352ED194974774876A84B7B9339B85E6566B1C721A535A378AF89D834374 -78DAA191261D4C83E12F372EB245CBB39AF956E9A28289BDA6399BD2390618BCF9AC4EDD -18CAA6EA6AF116C9560FA860C615467195720014657D4767D70F6817979FEED7A181CCAB -AF11554132B382423713EA8F05092EB14DFF6F06E1A813BBC84091E76038D6E3DA10DCFF -81E750DAAA2BF7BB75C4B1A3347DC8436E47D1B9780DA48842492B86E7D9DD848E1E8F62 -4BA0B054DBBE5328F208952E19707BDC6012F04A475D47D8C7EB6A64C2AFAE3A363CAD97 -936DF3D6347D8CF1862818495A6836AE1343272EB8F34BB4C3F9B0A631E922C920446DA8 -34E9C2F3551BF71677176A1F414188645F43BAD39FBC3453265C05EAF83C3F8B85CB80B4 -B3B5AC99B901E6E2C9A1C065848A814033FA6D5551954D4B36BE89E01C1CD16949005298 -CDA21D4BA36577A9784DAA57DFDFD0621EAEE192200CD5932A18442B6E925280A7B52D2E -8C7116DC0CAE26B92A9A81B5B6B62836E3857CD38F2F5AB075E642760C0B442725756915 -413B2636001AC3D87FBFABC43D6EDD8D111B01942EB7FA47D71AA4520026FB22834DF914 -791FDB207DF0897D89A0057B2BA1DBDDDDE182DD14C85EF10D35F6ED8CD2398171EE25C7 -9C54D90C059A566A0936B8716CA905803FBD950BC4595D9F4CB59C37574AAE4055D5B472 -DE1E6DD3A7C58CED64FFE344AF8B8698F8F1D2FBFEAAEA7F136EA0044472CDE262C7FC8A -0416A868086A5A9A2669B7C6B97482C570FB3192255D5DA008C9E13D1F5A4A3EDB7A5C35 -F71797DAC5B5F32A5C03C429198D56BC5B8BBFBF890C6A29A4DF397B2863B75FFD8DA751 -95F747DFC65379BA575CFE55A02C589CC8E62B8A8623FCC135E90ABD9900782B42378CA2 -C55BFCEED08EBCACB61C53C5678787DC29D2455EC3A379C1ECA2707DD3E8C008E26C42E6 -C48C8E3B9E0F667C541B963313F4FEF02BD67EFEFC63A1A0093A95F15FD139398A4CAC17 -83471AC10E3598688E1A6E261AE763A28C58E8A5B9CE4DD7B8971764340B9862AF36C89D -F6708F535653BA9CE2711624A646B1D1BE8AB250275A1718841830BFABA2A900AD276D4D -592A5D7164C6A7B00A62B08C7F27ACBC78C91E91298AA4B56D090B0A8546549B2BD2E3BB -6FB39B6CDC7EBFB5798FC9589DD707C01842E40FFD597F2BB1B3EE4408F9D38600804C82 -2ABEEDAD6AA6EA75BAEF32E3C33CDA01847303D9C142140FA1B6E71E2BD3C78F5ABEC001 -66B2D689A8C4B0A7A1C32F3AB9DE8CEB7D20B59524656606DB340F4B7727FB35D2176112 -F91C3AABAC27DE231F74AEE1F6CDB49E2844F40F5F01FC9E96465FAD1D10E1A921D81F9B -3F13CF82DC97DEE3462F58797B21E6DE4279A153669FE49D78CFEA9835D5A85ADE360B6B -4EBA9BB8E9FF8AFD2287EE69877FC6C5593A69114EB174AD40F150282B1939D8A3BCFDF9 -74A8864679AFA7619D7EF1F347AD39E2899DDA9EA99E112D15E809E899A2294CC42F4EC1 -251631ED566907E1947F95ED61DD306F67BE79407AF36F34DAECABF7057555BDBE1DF645 -433F5DC42894C3CCF54D21C17B64FBDDB881A2C27765017B51BFA8147BF24157E7CE1314 -79D5C001348767CF1E82A9A43BECDF2F173A42292C8145FDB705CCEFD9ED6CC945A4CB6F -6DAF4DDECB1DEBB0ABD084011D033F0A06F66D9E2C40DACDC790BD663A2436F50B3A91BB -27B40F6B05B4D84169CA16CA7C7E609957A918BD60284C78DA035DC6215AA76115F0FAF5 -4C90315EB8A8F3FF25734F79300F0E676D06836B5FD19BED6CC7DF74548575820A735D25 -89F676D0129D8A44EB47AC1B673657EFDCE874541E2179437B9393978525FBB93A1CDB32 -1D1E47B3B6FDE0924CAD789284CE6F18837E89CD0E1739CEDA90AF44ADA49DB336934144 -D8BED19D5090A3E79B6A96E303A45E0DF44E795A08E1B5612BD05BE52E0508D60E5979ED -B9BB44EB5851737FD5660B71661FC76DB3F9347FD7CFDD2E9C23AC26F805AD8E70A52F73 -B11DE295E3285A08BBEDFBD62C67A540400A01D6FD969896C8D5C46C7093646E530824E2 -C9DFF21E870EEF04CABCB2F62EAC60C1B62CE5403A1B5620DF7A3065B44C7D28366AC821 -86E49974DBA9CAD1249E3EDD876981C595BAC7D05F18D6430F31B96879DFE16021590211 -9F228B03E1378D8E9F7080D517F8C668CC27A9A60F74134827F37CC38C65E577D1DCEEDF -2A207906E90A51A72AC31C4431BBB18242DE354DCAF50978E619E8A06CA801937B522396 -AD588A1FDEB567116CDFF51876FA3640027CE40CBE18D9423F05EDA77E876433F496FF70 -0D89FD7B47B848C5336C80A5EC644FEDB3F4A9EA02AA43A6EEFCDD27762051D2DE2DA02F -A03CD491478948B3039FD532751EA70F56C254893A034971CA7F65BFF5662D4A61AF91BF -752BAB772A556644F711EEF61958DA954494C50941CE83C6B7B6B2859AE7E9754FABA903 -35437EFE4C7B2B36B99251E0C8122A16E4F9C883DC4CD72B5E2A854622B73E6E3C4DA098 -1B208CBCEF104F5777F2BAF65746B7EC51F3C51AD38A12089E4971BAED178A9302F20DC4 -88CEDEB2CD8BF9607912EBF7B0BFC3F226228C96C0C128C498FA351081022E47F62EFB15 -23545AA028A8CE0F56C85BE3186D6811E4B86B31EE3234C595D34164B27D40295D2C2DC8 -1BED866C6A0405C4742CDF5A2563524C93AB0D350CD8B3DF7D219379F302A3A1C12E0954 -09698ACDAC5A2A89B7F54C846A0378E44E923CFFDE69B53F62FC661571E22880B065261C -B0929D4E234503B81FCD8771685310EF5CFCB2210073EE65770F445B93EACC6DE6556C80 -59794A7499C2402066996593653192CE60E4907FED614060F4A9F68F0B949C33A7D5672C -60317CC5AD98FF3301C2176E6CEAB2EF6ACEF60B6FB96F553CD8CCB05C2B1EED6044CB83 -40DF43DB21B567EF0A5657704E4DE711FC3EA7933BAEE7744234A369326D1B0BDE34A8C7 -2E328F30FE150DFD111D75122F29CED31C666793100CC8B69A17CFE330BCA55848B86397 -F9DD4950D6DF2B4486E26AA8FFB58445EBB14BBCCA683F3DCF2AC64025ECA14151D278C2 -977A9E046EAA361E658451DF157386033AD47B48C674EBCCDB79B8032A7D8FC01C8AD15F -E1B9A410C5D4B51E20AC8E8DDAC4BF6020A2751114FB024A96B95E3053F38A3E9444CF7C -C666B514EFDCCC3E167CA0B5F8095EB8D4060937718F6D8705A15B3E515201D9CB804467 -25B98EA469785969D46E24F05EA3AFDB074901774745286056761846B80553F0D3460CF8 -29C7794E4A360D3C731448086638214DC101591F4531543E9DB6BBEB1B91DF1FB3D1C4EF -B13058C4B339935CFB4660CDB385C473BF7ABA5B5BC69083FEA6A17C6D04B23E9437C8ED -14C680DFC74453C4FF2A6BEED2BB7DE8B346EA2DEAE4435DF08305BCE245ED67E41DBBF2 -96E3E10562A55D667D3F9CD286FDC42624B4BAF764E3C3378C8135A99F314C1CAC47B3B2 -E1FB39499594B223CC03EAC5F75BA3D91D892883D2843B29397BE6E06842D48B75DF75E5 -480F6501AF694E0E76D228DF52219C15E7F33267A9D1C3515308EF73D3DB303FCB9497AB -FA1236E8DBE95DE4EC90A9592CE96949D0DC55EF858A18DD37AF76A51EB3B98BDE0ED83E -7F4C6297245315E685559B4AA1D37E47053657E710D0AA3CCD41ECCCECC286BD133B64A2 -E8583148702FA532121E1E7B058BA1D24E7DF660A9E130BB8BE6DD87D005CEBAB1C8E87C -34C3EA39378893ED7752DC543535761B4A237ABD04B53080196D79D692DE2E53B7167B6D -76DA2279335AC5BF986E1AEADD9EE3A100756B15353BECE08FA788CAB5F63BC7AD58C442 -4AB03866AE0E18D4DC71BDF4B58A79C75D616933A31BD5BC14A2743E4A1EB88D90DB1854 -F132A946B090E2A092F71CD84239403C0CAFE30A7900061AF680F855DA5E91B023830B93 -48050178113D7831EFB051CA8534A3FA88222FB85D1A1E9D99936C49DE0A1DD7C8383F29 -B9B2EE1CD7064488D60C7E76F4F2DB018A4B9C95CCBE2F9CD7DEDE9501BEAA9C0D08C590 -1F9211AEF3AAC99DEFBD5F9C431EAA31798BD7D3A3A5604892F44CB3B736E8F8F79202B1 -6E9ED3ED418EF08539CD3DD9E624BADD761A44835AC95D5D07F7D67B93EB70AD8E86E0EB -5AC1D4263F51E84583E424D0444B673747A8B353A780A6F8549F11A4962641A47CB1C3E3 -C4A241D244BA92AB05E6BA17BE0D6DC648C1F9D5F88EC20E103D1589D0E86D2B27CC077D -810BD20514BE94853BCCFEF33D7655EE94DB8559BE3FC78C539E70F84E20534E7A5D6930 -A02889A4A82BA058888AB3EC75769BF961283481CF006D73FFA088EE019BB4AA990FC858 -621437BFB2D79C49157B5757CDC8EEAAD540E02BE1404EEBDC0B7BF094B80789D03B5F7F -5756535B392A64F9617ED0856A7D167A78032855ADF1E672851A439D9DF57967EFC56D44 -FCC6D878C31CE7904C70433721C4E981F2643C08D96E4753850A4F427FA3D984E00832BD -53437FDAB0A491C81CD6CF81D8BF5247E01CAD335A6DC9A69962B5830DEE96B57C9B08A0 -A5F401CC9CE286D3FB2B24F8E77508E4182551B4EE7B8139B80B805B64923ACE685CD576 -BF57A5F538B3F03C38B7DDFDE686B8F79271F8E4E909960D6D36523D4A217E4036AD4C84 -1E228DEC38AD432162211F5BA65FE03E0796A29EB8A8C4DB9BEA37E5C15A4AFF900A3456 -723DD6CB1F8BE7C5372A815691A92B5F1DD97BFC89FA5EBCDCC61AE4EF0245684ED4FC18 -7631D4292A94C9E3BBA81159E3688CAF6FC988236FAD971D774B54626DA436D10BD42A1E -86036DB36914728E66B8EEA3B432126A5C1F0FF3928557A3D7583BE21007D81D40D8359D -83075211A8366B16613E1B40EB840DFCCED4063CF06117963EF200E0FC0A558B1B69DED6 -08A00C25C68AA7EA0D902047A0981330DB2788E994E2196FED97CE2E777C0213532CB19C -A28B07792F57F19433A14D1E6506958E8B6483D3651A1EA10D988C541CDA715DE138B612 -76926F9793C603B1836E4E9A4DE110A69D60E0F9BB0D5DB9F4B67209EFBE8D69D4C20B15 -0640052CD4367DDCE4722A87E9914B7DF541DEFA52278ECEB60572E0CC31AFC6C30ADEF7 -5898DB0B4A5D00F169688EC5212983AD3DCA6604CD2B3FD4A351EB4661F025716B2DCA8A -F52CE6D269979C1F7E7942F583B2CB678F8DC52CB250C603D48B206D5547816C220AF203 -609BFE7B53CE4C88178C95A4E8F2F8B4BACB1CA5EF4CC1E76347AA958F2789D441AA1193 -C56ED7B27A0099B3EEBAC6AA6302891D3F16A913D980522CDDD8E3303437EC9AFBC4858E -D3DD92E3E329B34B344718E4950DE3829812896AA20A9480582570DC88FD7F4AC2F46B24 -CDDD8EC6BE4862DE1412F427B698B83AF5A0EA767778564F3C3CA40EA60281099297E104 -E46E308BBF5EF23CCA84F9D6A6F773157582EE0F1BC477274999637E199E269DAD3D67BF -D3EBBE840CD906E73A31EC7EB044E41F6B72367F6EABF54DA9F1664A1664338E202105FE -E7F071026D12CEDC2D86D581C496B400D58CFCBB7B2A551BDABAFAC1125090DDDEFD4F55 -55B21AC1F6E5DDAE6700935C521AE129F886598539C41D07FE2680F25442BC29BDE2902A -07FEEEB0A14E4F0201483BDD99D4142194BA2FB991F76B35D0DC31526A417212E5151E31 -60F3AD665ED99E0C7E50A43F58B2D6A8A075A96DFAFEA84C12EAD776CC6A3445771DE987 -DD0775A8DA30A1D0B92ED1D1A8B3E0133198B33C58A9E79943083C1EF44C0AE8A12D3BF6 -7CE1EF00C97E220DF31245B47F4720DA1F1B66A11A1AECBC9183C654DCEE7A16D47A3503 -74458A7303ECAC951588D2DEFE51919ACE2093697639CF60467FE9E43DC30B9FD53D4C22 -DB1F7B81EC206548C1E6E6B6CFE038764C4702F62CC23C38AFBC762D24E7625804867B40 -1626B14B8E45C6D9641B591D868FBADB07FCBE00C193F2F13F174648665CDA538E8977FE -E8B54B74CD4F84BDF7A1D2D1E64539F146D3D116BEBBAAEA5FED99C5DE42526EEFBB78CB -F8AAEC9F769B94FEF470C60E0B2F79C7F99D8C9C7C32A68302B352496255FB3785F74B43 -B4A173961F9018930515E6D1A57897420C404F32B3A0E2CDBBF8B53DCCDA0F0954BF6F80 -2638FBACAE414DB6C63F60ABFF719EAC3831C7D5AE46AAA7BECE1B71875D46504E61C29A -3AFA16498509FC57DF4B4BF40CD4D8D59399EEF835D97EEF06B373F6E006EC22FC61BD13 -99EB69F248D991725232C1C5BBFFEBF0477A08BDD42F32FA43C5F5C06C2BF639E1C86F0D -8E49B70E134B038781A1E85AE2A16FD1364479A5A46EEB1191390F469D0C573079523D1E -F2B049171F9345AC5FAD682E4CAE51E1717FB19F8AAED47B7572EFD188806BD9FAE5AB42 -37683C9797DEB62E1FD9DD5CD1D477918D19D004AE0334E7F6A705C4B6D01FEDD05DA5FA -063F81B6C6842D81A774C04531F708045021B8F11243E2C3F3EF7FAF5BA95C117B9DD6E1 -AABBC678F5046CBB55FB58849B6500A1A9593AB0BE9E2CD823FD35F60A485C3DDA2A36E4 -D13984CFFDC0992E39CBE5CD18076A92820D874E2576C83A6B02384D33F07DF51788BBF8 -27DD031A3520EAA36248860261133BAB4441635E255AE14B59B37B35CACB94688809FC1E -DFAD40EB2307B2E0B8303BD47A15F736F58A4B7D8ACC44141E5E7D85D24B6CD12591633B -7A005A49120406ED1CE82835C70426862D94F10BE0A51C894074506444BC899136DCE869 -D20F94E6E1D67F579E94D83DBD0B2230E55B90E01088DDA3748DEB1A7FBEB2D9D5625149 -06F512CAB6655C97060CE906ABD62996B2F1EFB10585C49EB019986CD391C1250C9E290F -435A19B3035A30B415C614D64E396E5AF2970E36BB508E4AA4A030C9A38ED4D04B967E2C -F5BDFC66833DCC48BC43772864DC29337040BC9AFBBA5E6272CEB78222394AF8362D32AF -C1AA0E3359A4DCF2A98F14C1876631E2C98E8E29C41655F970963592C4BA3D028420B197 -559C882A42896CA2FCAE8919352A02C39BF565A6841E3B181234E3750125F983E415A065 -137F3C67B80FBF6390B53BEDBD3ABF8E11C807C89B1420C37C790BAFFDE9EFFDE9092673 -DFC748B14ADE1A7B9883C545C0C145DA0D404571F94F4A161F7A747EFC311D1F52C33CF5 -993D987161F2AF52920FE97AEFC3651767C8750FDB45920C972401A337517BB88B3B65EC -B1E6A67B6B0728E3A1E46B1FDCBBE1D3757D715F91AE74F3740D2329944246FFC50665A3 -87B472AB71CA71539C2D15C56AEE7951666BB869FDDB6D91FB4F90A00163E7F1F4634472 -46DC61B4B08ED312157BA05105B93F0F8DE781CFB59480E1B8596A3354C8783CEF52EFDC -74C9D143C16088448B8A9CBBCEC59900B16961E845CC92AAF400943EEDFE174CB3E465DA -6D92240D8CEED8557EC7631EA9D2B4F0758CDD9847D703A5623FC1C96D321482243A6E9C -853FA07459B8DF72F6D6CADDE4D92A8B110566984A4B8678B8CC8FF4B2F4665030FC2B47 -A0102CBB3D8F4E0C40D761D05BF4B9A684FCE51A5F750093AE65299413225E64BB20D6C3 -E287D934DD3040DEFDA92AFBA6E79483DF64FE3CB9B265F7CDDB2F5DEA767D5967CF0393 -B7405BE70F810DEF309C5D2EE786DBD819EA4A4253125AEA8DDE8F9AC42AB35E11773CC8 -434462261939FE3EE8F30383450E3C6CBB033FC839332F6B6092E724274A89C86BB4ECCE -2FF70EF35268E9EFD66F1A75222BAA8CC9F9F4BB4943CB28207C633004F31E0721FA48B7 -D1E9D10A0694EF6A58A1F01EAA6BE615F2B1BAC49B9CC0A77FE251B7CF5611ACB1A0BD53 -8ABF1BE4F584AABB038F4FE84606BD96CF25FE9146651587023F868B13557E4153F2FAE2 -070BE3D081C4CC5410E803F04FC2284EDEE54DD387DD61F0B3C2A1815B35DBE6FFE337D0 -7C50DFF344C2A4D9921DC7FD0FBA8CA06FB07CED571BE57E89C3E429B40F0D8EDE7B522A -32AF6249D1EB966D27A5424495A82F15DBC8FC90B8619C0363AFA45C26D60FBB408606D9 -A37B385582513B61641595F7328A1EC830E90BB7C8B186552E2F645E2F09553BAA432558 -DEAEDDD0591CA23F19E6B9D2143F0CFC9550A43DE70F69A66A89C4E505E02FDF77C87E3F -A3768B12B7B7137C5DF761978563CC1C81AF9B7721D1E21A7E18CFD583EE4BC928E75AE8 -3F4DEF7A587D0AF30DE0CF4D74872360DB3BCD6529906995C1294DB90C93B44EBFB95527 -3D0B704C529EE441EA8E1EE2E3B03B7BA50CEC0C34AC176EB56AADB692EE9A53C215AB0C -5736A3A4EC7E37F2ED5E4BDC7B82D0E35E06915E068FD974F225E70461D780906A7B7831 -AA07687C177FE71B84A4136C7A6BF2FE6408A9C7049795C49326069BF24244430A960ABC -ACE67533486D6D5C6CA89D71904C5C48D02969628A2184F6B36C5FFB64A671116196BBE7 -4FA57CA9CC66378C0CF086FBDF05DFA609BCED01EF21DB027551B888242BDD941C302340 -0C2622E8557A0E12DDF981313D1F5953B57835592C8828C102C16EC39D06B63F31C373A2 -5077672A1134EFE0D4437E8F38AB373B214EB5F2BE1F6D80A07E1AA296AB7F974EE1DD76 -EED4B86A3CBA0E3C9D9F1A12F5E58913054D4557C2CC1C2C147196C7CB1435CC90C5D7CB -D2379FE287CE562D9B7660E157E175ECCE8AA94B1173665484D19D65A9B191D4C09D43B7 -90D1DA313C09025020B2315B0112B8E059E01525EE0AF0189CE06A307801725A26B2B3D1 -F0A1BFA9056E1D7DF67B1A8E82946D5328AAB07A9D90E21F5163B1E3DD6D789068C8A1DB -553FCEA69C14609A69805B3333EB608E4744C58C454DE66723A7794D09DEF7C6C981DDF8 -1B84B3E498D055ECEB6E8372D331861437AA69AE7D9A0932F4E71B9930D6F2DC38161257 -A32B87A7D37D200A5B9B5B257C0C9833BF04F91496BBAE83E9AE742362D8E74E0A4AE5CA -029B5CA078EA6D8F00B1ABB84A08FF1C03BA539128A42166D06E09FA8AE71B74A216ECCC -82DB316C9589BC68456F8ECD9B4BEF1E12506D537B6BE4CBB15C969B05D2F220B6E2678F -4F2D497DFB72D8F9584FBF0D363547F84E1B28FEA0C869A090FADD5B90E36B88326F6589 -BCFD8FDAB3993532F04949DB9EC2D2F2F1360E2E75AE76A6796A2E7AFED4DAB1B7B10D54 -33AB4C76331AABAE0D3ACAAA62C1BC3F72662EC71B76568BF3450B45C2D09BECB562A49D -3428A9DEED6D956CE1AFD83D90A0FC021957B45B8C03CDE0579EDADAB4BA570B29809545 -3A1D56FB60FCF22C038803ED3908D09A5E4E3EACD180A6D355FD7EB96B05305E841DED98 -07F75F133A6CA5D3415D0376504634B8DC2AC7A5BB53F9A3A032A878DFFA224FAD7A22B6 -9416767480B814D12E7D316D07AE8AA5117C04503B2E194F5CE94EFEE005DA30AD9114C8 -BA99323CF76547C24D607E40B62C51D86B672675E6F0730ABDC9B7B186D7EFDC4BEE86A6 -6456C4074BAF42818B46DB83D70FC8D1CA702CBB672B38BF0E776B52755468462B2EA034 -DA32113FC26E122261018D3A125D174D301FF7B16B57A406CD70110AD35710C2B67B7330 -CEC7B6B33770572AA9227AC52B0D6C6D0E25515C5844FD5D24140E01F3A4099BE114B94F -DB65580BAB585F3561FC997C5DFC1A27A5AB4CC6DAB5DF46F3D575316C81A2049089FCD4 -1E4740F4D16EEB08F117EEED488A6A9DE20B498CB60E48EB5A0839134B9F102BFBBBA982 -74ECB5679EBC7CD178B6F179ED979AE8E9A41763A97B4E14A7AB6A2C1A446615786CA3FA -32BAC716808B486702635502AA9F336C101A6E6A5F3033F5A92E13B9DFEEA4E7E98422E3 -3D051264262DAF41BDE94B43E0A375A42C59702EF2C43445C5EC7B6002BDE7C342F52AC3 -A5844A0EE75F5670C8B80AEBDDB2FE3D28BD6961037C0C54BE5ED708F683D1494DDFBCDC -976AB35442BB049A5ABAD1246996AB4E56CB0DC9596EE6ED06D02BB2DF9A7C9CD5B07BDB -7AD345607291736909E194D93DC68A1C612945A264A81603A9D0DFD5435DDB97F42957BC -AB7D6B400E2943A3F455918135E6EFFB0AA5E9C3509860CB5727363AC596CA1D08979225 -814CBD4A22CB979E1A6F6B9BD0359E782E852F51DAB107EFB2C2F1CE5D69D5471704572B -65A8B8B45305088AF7FA401348962022C952067504E39F3E879025FBE8E5ADD940B6D4D1 -737101C3999B9C6F58B259219AF84F1C146AE2DDF02C492FB5F582E739F1D1A3A0752CBD -5C401C91BFA7BE13F936DDA112AD87ACFAA7DF7CDB341443967E8CE3091F024329934DA6 -AE431187CF6C1955744518EDEFA73ED94EF60764C59EC21CBB08EA73512314A7E0658DCD -B61CDF37259EDE297DDDD7022DF5174DE5FA5216E566D1AF3249DE12E3A4EEF90A125EB0 -5633B85E3A12463693D5E2D6C01F5353761DE77FC8BDEF35FE0432E1CE3254F0F50A1B77 -C2245BB6DAA558E893F89AD98296C328D37C816CA808943AC488BC0090A4DB29DB0EAE82 -C89337A7C3FD1B4000202C42489974411B7B63D69BCB12E7EE7173E51D1DA17D7C82E6D9 -F810E76A97A9F118F1989B9DF448249BA2AD095A9698BB74D744C9ABCADAD6260E069C9C -73B05D41228C475C1207FB4AA8A14562FDC889D6870F5D045073F18D8716944B52A7F9C5 -0005002C0D1032B7F3ED2F60E9B27D056D1BF9AE3B1C9B4AE9A76EFAB3EB926376080C14 -5100DBBA2FAFB47E119443AAC33CD4A49DBB8C0E8629C56B8427AA94A6E076EDD6A16574 -336E6AC1D23E04E9BDA3CD2C926604C4E8170A3B9599FBFA9D3C8BD6192020E0296968C2 -EFA8C621C0FB0AFD399FD8E14CCDD94D5C6406D6B1A2564507BC818467322EDC55C3A3EE -E343DC08142264D205F542C023F8C82CAFAF6DC194E2016202247696F03CAD55224FDBCB -0E8DD2C9DC53F5BA9DAB23C033C788CBA2382EEA7390EE61A9672345EE2749CCA136632B -34AA12A5FC16974E9EB835A5598ADA0898BA5C87757D5EADAB5D0F71E4B75B8B1D711128 -E277A973EC136CAFFEF269A28B00881991B33CC8C5DF618B95C049CD97D746978B6C3AC0 -CB9EF6A51BD9702D0C14AB484DA4AC2400BDC557CD5E57A2421ADEC7F2326370E6F5D5C2 -9DAC782AB9255D0F4D0C98E7F9E0D7D31B114B1BD18AA2510E4F4A97582A15F170C12EFE -80842C1D3FB9C74F40DDCC8517FB123EDCA605305E841DDB1E5AD5448DD4972A20045021 -196CC951B8C99E3F000CF984252686EBBDE5DA0593C8514F131FA94949AAE1AED3E780CB -0504CFAD74171757769C8B2F51D54DBDE3EEB48E75486B4A75E4431F8BCD1A985C4484BB -1B5CA35F1BFE7B3A7C41A42B66756A229A7A5A0DA6B7A5084EEF6B8AC804C17F1E88E5C3 -D0C1D55BD687A9803A1AA74A60C0360873B37C79B09A1B823C3C8AA322BFA2E9B77701D2 -BD815C11DF5C55C393B73F98B73A500EEE6CBDC9E4F5405C73C3B635D6D0CA58BB47D41B -25149C3962190A1CB6FE7A8D6D4E26A205733F42BE8A2B0A8B4573C92CC98FDD07318671 -F3D3D5C7C757DD5AC7350F64E70381D190A05C674AAA796DE36886AA50955B422BF5995B -6F8EAD32715151456AEF2AD3D16FA3120B0E95D817F9CCCF7B2A55D529272B1E1BC060B9 -9F6342A1229DD8EC1DDFE9B59DBDF216006E98EC1AA5A1F55EA3D7EDCE63ADE2D4A3BE57 -E45A1FFFC04D1C9F1466583BB2AD58AF695DB3DC075327144B35BC40EADC993BF3BB97EC -A3F7756324E46DC6F4A13CE5266433C90FDEF6F46D38A9CE9DBD993B941AABE630ACA87B -B14EE46C977EAF512A769611F269A17D6A7889F28F4D38CB9F20580F6F4F5324FBF8F6B4 -F6C101ED306407463004171F3C8EEC70B9A2FBAFE213D1450F9E368E56183F4449780F4C -20171C3354E3AFD7D31B9CD7979F57FE545B06F40AB613B5B91D21D9E50B7B01E057F02D -DE24F4720972007D62736223D8C3C442CA0BBC8F31D29387399CEEC87700982A394A11CC -C73E118113558A4D44BA30924C4310F7C83F2C6D3FF570FCB031C12322CBD38CF98053AF -BEC2E7DA168EAB3B646713AD5C3FB0CAC7BE1D7CC779FDBEDA2FB78CADFB0EDE7BC13C17 -531C20EFA0C63BC58AA447545EB89FE0271198D71AE26924F939A063521C082560D97EE9 -6130A6F6EB7CB75BADBA1A8A00736860986EC623DA35F8210E26B843345B941C0C0B262E -B8EEB95482CB4EB437431E541F1C2820699258B1D17229E1DC8D7B170742CA64773F8062 -330A53950E929080661E588C1E4B85B5235130D50876837EF131D3F01CB0508954F39838 -ED8A7F38E5E7AEC8A74FC71EFE42E03E01B3CE075AC305B223B03944F9C39193A9EB6334 -FE05EFB242FECDEB2CFB62E0852B8AE333A92B8CD54F33318B1B22A8FBE47619A40D2CE1 -226735134BD860754D2804FC482441D48F1239B2D53E0ABD6FA1D556E4551203DDC5C79A -F0169D0306F1BD451D9FAF5A200FAC1C833CD3E72E37AF7D95860D2D04A1FCAE8EDCC522 -255D759C135B7812CBD0A6EA9BDCC084E528A533B79FE9CE5BA00E86448CA798C6CA5B05 -5EF88EEB8EB276D2E84524D64468EA6D25F062CE4D47C1E15CD734BBD04308FF67DA439D -577A00E4824EBFCB2EA5A00B55655157AFA0DA8FBBBC520A39B37D9FAE15A2CC90DE8B11 -9F69965BD22F20B63A3DC8C71A15510F85AC76F3248D2E5593266D9874E3C099649F78A1 -85F07DC3D9C1CA1FB2FCDF2808945571904E3E37A00EAF493BFDF11E9B6D4DD951C76EB9 -9BA671641E4A3FFA7C16F3AF41ECE3EDAEB91B0D8065D2324856C13B02C6666AE0DE50A2 -EB8380E0CF9665C3005EBFBC1AC075D05713A70CDD5590E7B9A54CDAA5F5BD2463AE744A -A12F29C1C2D241712C3A80DC860C4BE572905586FCF974241213D073D3AFE446608B31B9 -E4F368D5627A50E0D55F22899B18E8BBD1DC96EA7EE8411650950B38E5E977E25A210070 -B8BCD0C109AAA5E1D838AFB35A25B0C32267672D34D5E1F139DFC10AE6D23F14B07190A6 -0DA8E6522D3050EACCE19A9D1C762BFF247CADBD1D1F172C006DB745A3F4D05D33957DFB -471AE4ACE69B8AE49D8257B8B88D36865C0301D3DBF8114850A2B05D2A8121B3335DD399 -067962216367A8E8CC834D69BF7E16D06B4C7F602F908DA3903FEAC017228C976741A421 -C49048140D1B8D484153AB948A01CD7113C0AB9BD5466F8A26557E9F984BEA514EBE72E8 -C38FAB5F634EAB033C960539945FFDCF63E1DF47A8C6BF4460F6DB6778BE2D90B90BAEF4 -6AADCACBC8D1DE9BA3E9D4A2A8EB70F5CC3F02ECF6D76BCFDCAB9BBD36DF52DF860D64E1 -F0958B74361BA4298D792AF1D119905FE6D3067BFA8146CE1633D5C4658847F3F9E18143 -F1AB4D35C953AA5105FF94FC0C345E478B5B1D4584CA7BC050A31740EDE0FAC5EFA57126 -2CDAE360AB92ACBFD23807A0394160A8EF0B0F320CE3685040D091289DBCE3454B1ED51C -83D8EDB2C86C71805DDBD584BB61E88A673ECD1535F5891EF7695F182F783B59ECBB0DA0 -B445D7AB5DF5C9BD042929611182301813145BAAC4D54644E93BC8FD2CEDE0207B5D60ED -FF95CE7CC60DA632FEA04F8BC518E4A5197BBE065062556EADE480A86B8A2E0C9F1BF739 -1102D97C4D6A33B05C2EC5F457306266572C06274ABA9EEDB8F3C4E405EB5F132AB3E947 -CFF44017C6D8B79980DDEB698BB03BEB0C864A0766EDE34FED65FA889C5F149736CB7640 -B13BDA9CC6D5BF72FBC3009CB4FF5A877CA3E973A2A08FF25B212B8665DC4D6630B6EB48 -0D6E1E8DCA6F34AC6EAA482A4C6AD1763E17665BDE15BC08806A3FF8BE68584C8EABDFB1 -1E415329EFD07459890671D21872E0B0CB2EE1577B4A9283F224E3D0CA7106ED0C91FFFB -4A3B8CBDB5E528C8D95D19741F16DF780F6D49FF6815351D0F0D92A0CD72FD14A19E1DB9 -97C3CC11BD6FB2AEB5281951D508A3EAAAFBB048B87AFC7CAB9BBE1D1C407D52978B6AC4 -6136E779209453BC2A6A86C198D1DFD8818526715228EBB5F411E1554004F48FDDD2607B -E0D3979B82E35B78985FAC19CC95022D1F0AB9358CFE21C27BAB89AE4B03CD35565BC65B -E6E25BBC43F5298B14000AC0867BAE57BCBC40E938C304F37D9AC390A90BB5ACC906599E -789066315EEC0C15FDEC2F6E637A3082C85B2ED6BCFD621F033396CF1B7330D97265F873 -C92A64271C6CD63635758B05C10F67831EE579EF0B4AEAC245BC87541C1E7561E24B5E01 -B323E220BF1170BE5A4319684883C910556AB899372CF97C572D1AA86A34D826D6D4A048 -AE28B9D3E63A00A6CD36A5C4472E1B7840FD3B09A16190BB63588E98921E17D4180AA540 -56457195934F082F0C0F7D104E9271FB8E7D0CECCD395BCFF6539B76EC3FDBB1363A56ED -366E8F9DD48A9349E4DD8A78C5B683E8365F3D0B4F2F8DE3D70B0B8825667406898EFF52 -A957499AE83E6FD2037CBDBE6B9265B0CB7323F86AD386F7A65CBFA93DD00255BBA82F96 -34A80487F68BC69000869F6CBDD217096BBE6BD9179DEEBE12422C308CE023854FBC077B -BF1B820172633D8F70B26A302EE6B64258FE46DA73AB8C384756200C95A5623D0F2A41E4 -7EE54394A784941A06F082C737B9C6C5855C5F11729D6777E38A6B5F061C8E324CD2469C -37B564AED2568502B980A054BA7007E8D9ED7733D3956BF5A3AD62C262CFA0BA9BFE0772 -7B67909D59A0084BBB85DE630245D514D86A920891417AB9FBC93863498E04E1DB27EC92 -6F5455BF6A5D09BB6C4968E10A177CA4B057E7D360F4646C986BDC5FB0C7ADA94D69F257 -96A37E10F1C62FE65D66790A0599D0A20ACD87AE4ECAD36C45678542E8D8E364DA954F9E -E832D403BAD839441AA6F7118FD8C18B5C36F20EA984755E672FD1C2DECC0F6764711C3E -7F6710BB8C7911BBDDB001B9CCBDD363B8CD618CF15ED57B63E5436047E7FB5BAE45D062 -D2EDEC99D9335118AC31D73AC1770FD0E5618608C7F42507753B5115520D4E220339B3B8 -AC54C83451996E8A489FA86B1E6C990A5000614688D4C29AD6EF8010131BEC1AD2670F9C -DBAC78485175F999CDFFB8572F30648EB8F49548850B6CBED30114EFB970C8A58E814239 -CB0C1A855ECB24E0E38A6F4AC9EA5D255A9EE180F41213F8168F03E4F646411AB5B4AFFB -B17C2533092A51313D3556E734FA0970E0760CE24A573A511EDF00457F348C5E465C1AF1 -198BCBA0CA6DB414B66EBF68E557E2EA72E80D7615B3A3017214BF1525A6CCCD1BBB3925 -C42E13E162797DC077B2674BCA2265F48F72407B24CA2002C2DBD2DAEFE4D0BF1B1D682E -40B74BAD6C4B69328848F208D5ECA1A49B6F59E89B306FC5C47E6C007A5B0E5380538B38 -1DAAB61199AF1857C9D0649570534B486FB5144D9588547716F848A8015C8C2D21995D4C -860802DFB07E4DF45E09C7D7FD5EE824CE4128ADF624250D69ACC87A0A10F647E7575DF1 -E7ADE6B0BCF063411797D563441EBCFB213F200A4CE96623BD6CF127727364E0450EFE99 -288E9A3B1FA4A1E776C9BC581931B72749EF0DF7D786F898CEB10158B705BD15B6A9ADC9 -9C7E2E3624905EC361BEEBA65E43FEDA49EB8F8A85187973C5D19FB54BDDCD79E42E2C08 -130865F10D7D600246548D33303B617CD6F81E0A11F4BC23DA3B167E5B2FBDA8BE051C49 -536C4B0940C61A954418AFAD8B0B19D85DEB12B1219DE27FF75797D0DA16F00F80AC113D -F19AE8BF86FCBB602F3BC696611935FDCB61F05EE17FDC36E0B1087187F80D5C3EAE1B17 -DC1BA5817CBA5C3CBAB6BD6455AA2C3B44B57494B8BD08859C1213B24A62755F7CCA048F -63F3F430CCEB00BBF39343F25AD4B6C62039A3F7B943344F86312E7566620694B77C5B69 -2AB977A7331B5F38D883F9B7C4F89E4A66F725E0EBD8E988AB9AAECF32D31C75A3E6849C -32E4F06196DB937008FFA15DA36CA90BECBE909AEF6CA20E2315C82BA27385D08720E1FC -BD5652AE843BE5F3D457B7F488E7AFDDDCD29BDF7ACEDF1075ED819674E47D0FC92DB7FE -0AFDE6D58685F855FFDF52CE51B9C2720A82712A4B7BD96DE3EA95CD1635ECF7663C1D54 -A885A6AE72D84462639C52F987138050CBF73A5504F66D1430DFACF226FF12069A80ABDD -0141CC2E05524BAC464CA4C59AF2912A2A4EA112F8C8A0BC4C908BD6C0BBA0123110F3E9 -CE3A216081892A19AC53FAD507E34110EFC7D4699A98849C5502F9DCD4418FA81EAC9481 -E4C20B4F46BE4DD134FFB03E47D6547D6540E1EA036167460F2922629E01ED36553AF423 -0050BBA670A4B74790B213D70D7ED543F9787E8920551C4703DB62110EF2E30DF12E91F6 -8AE86C3C6F9EB3043C162C0A0CFF7D4FA90CFDA5278D2B47D265D06CC33FCDDFDF3C68D3 -6BEDCBABB491F89962A46F90923C51EFEACB39FA22A36CDDEA38855682F126AEBEC06558 -94CE26C769392D71F1C4CBC34E3A4565EE74D67AB272327B457D346B756322FCA806938F -BFB118244CE3B164ABB58135A96B7E1211220995376CD058DDBC291AEFEE79A41501AA17 -BE5200BA08E047BF985A97A8DCC1640E279DD35938B57C186918F163012A4C947D665449 -5CAC149C96F6A40502ACF8BE05D671777DCD218EF7FFF41AF93A80418A2AB81FA89120BC -91A462F034E8801E1251BC3327321C7C0652ED3B26CB8B6CADF42AE3D97A8DB1A732E452 -FF187A97A2E03372667F91825FF3CC861B4122A1A0A3F4564323209DCB8FD2A886E95F58 -1539C74E4F5A0EC5B63DFB416F3859B46DCDBE7D724DACA0C5B6483FEABF3F36D6B13D2A -49DACF1EAC4FA6C7B161A22CD876F5D511C2C2FC96C8B3AE53311E2D9468874BBB9E6B4B -D18C5DA32F4E00923F59D2FC2079BD4BEDFA9E960249C650EADF2937CF7E339FD103CF71 -AF2549D4E9763E75A84744E73F70B669B6808258677265A9C2A48D95CF90D1E1585B4B60 -D19CA105909FE1D0EBCF533562ED6953C71C3CBD9CC474B6F6418A87C6B608E9D62CD3B4 -15565A14EAA18B23199A1521B101314B38A6662F5EE6390C9DEB538F5AF1BCC84DC9CA33 -E2D403FB1FB1A2E12D485D534F1A8A27447B5F9F13ECE527F7CD3CD9144AC5F137637659 -8199D0EE633CCD95797F4D55447D3105AA87498F1FC8B8750A440C46ABF820EF499F9D5A -2818FFC414EEABC029AD6F961CA43BF94BFAEEDB8962A6124A192E1343E16A5E20204016 -B5175FF8252310B60F276148849E8556BBBD44CB9E59F5992AC845CDB2BC3B33BD7F0816 -2C36B7D91BD17A37F77A7938A5209FE92DEAD16A595E91917F6E49ECAD8C7B01F1565089 -815BAD961827931E718DF2B1F9743B938ACA21B648916FA76C5C99BFAC1DA9526A8F8793 -733B8CB1123A12E1FAEFE75332D850FB7F296539E76031DDEA6851EA00D97F7B83945C3E -5C29D9B7F31B9A7B541B7640C17347CB2E39C15FDCF8C8B8ECE605239020783F333064E9 -ABBF3236976CC021E852C2D1C1A95D6DFD5746E076D14E75D2D31D0E93260802D9B4B846 -865DDE6FD59150562F6EF062B5DFE7C136978FB4A84ECB6AD463E199CB6ED2A9EDD7CBED -D8BB618DA4E68319C7F194C0DEE2AF19A36943837505AA05FCFA86550C704A7EF74227D6 -58BFB33945D1E1FF102C91F6378D54AF74F1CEB81BEE7A848B8C933E4F9AB1D6914D9010 -9FF6C47194AFE0004A7245ABA2CE53A6C0B8636FB445E1D27E631618DCEE6E1FAFA19B28 -A3FF71FE46241F832D43FA786CAA4B5125821F13BA3023B54DC4E59CBB027C1720432DED -5D53E05E2E830F53F6CEFFA0F17394A13EDC3ED8EE8493523394C5C73CA15C428E481D73 -FD4BAC226F9B923A1BC380535B19161F12034CC22DB93B335E1D603F8FAFF5BAF4410A02 -C8D0391C8B118EFBE289DD957956EF0CAC55D68F2069FF4D24ADE54DC83286E790F7EC12 -2EA9CE466BDD9175E8D50EF54A5219997A440C689634B35CB4C440327CD35CB05AE77E39 -87D742854CEC4E4784D4C1B06340295D19C1944BCF826E96FF84B4C80E173892B6DEAB45 -DFC0BF6CE1142215881A64D73D10AE8BB835CAFEED23A7810FB3FA4E8D811809BECD7062 -2C9C6CE8725C331F42F991BC35674C0E451EB19887FF4792D738D4E22E4BB897C03E79BA -7F79F5CBFC2FB014BB58DEFF61A4AF62F3029F6829CF1DF5BD69FB1C73C68E36F2B3B1B2 -30B1D436D6DCA96563DA655E275ABB2AFD15D313D000D8E3F0D3461421D52B2A22623249 -E155D6276A5E6E0B5746C1BAB10B628092CD035976220A0121A3D16BC6B6F222511DA119 -E245943C5E7D68E32308EFD355CA3438436A5942292295282CB1FCDAE8B7A3AD3CB39CCC -5A6DDC8FC771700383C268F4D676E9DBDC33C14688F23179089396251728AF49BE24D02A -7CA4B1AA3CC148FB87E7C87EE41FE22723009FE89BD2DC689DDC9F034931ED7802B014F1 -C20D8F53EC110CDF35B8360FB1C58C9AA0F366260F36D21232E89FA1314476FFBA7F3AB8 -935147AF814D3BFF97635B11AB9EA47F6EF5952ABE438B536CF0FF25848F7480DFF36F43 -7CE6BD8701F4394A80E4D62731086ADAEEC41E6017A8AB72F890E9ED036C13BE24A7F2D0 -ABF1999B865B61349C501A9024FD08A319FB8E5DBA6E7283E8FC0BE48B9672CECD1F1091 -23A155914F163FD67AA466048A46DE447257D86C493B90178F37A23D66D192E552E46CB8 -E3C6D39B4CF574DF2C38CA6C74D0881E6E5C068766AC2898185BB326890F530984F3F31F -57F80C0220E2CDC14CE937420869C037B4C197C44B59FF91FAD5DAA875A7802A293679A8 -2AF31176B3DBDCA9FB5BF5C40038E7F119C61B7554F35DA79D942B9BE756497B3C9B7A19 -E5BCFFFD7BDD046EED61780D4CC5A7F8E3A78B7B2414212870BA0D27FF3C01B2AB030EEB -8F036B48673D6AB3460BB45939214BAB345B8D1FD6D2CDD3CAB37376244A7AC0FA3DF861 -60A193EE77CCCA93B2D984FA9CF07A54E9207EE127EF5B877A561216609567F9BD907BB2 -11A7383579FAB14FFACCFCC0E260DDCE27377C32FC039FF52A5D8059E7D4CFC880B0D634 -51482FC24A8E711B3D962A0926F4A0FBDF29036E0499FE6F5D115B7A95A059D6FCC36C87 -03DB34BB67B65F511637D91C428EED31371E9E9A00FA82BAC36AE2FDD0ADAD995E0E96FB -C909C5AC04BB213EBB5865A2CCE6942DD92EC73AF8C7D554A4B32910C7CE57EE79D11ACB -26D7CADECC469CF16953A50DDB0FF9A909F0382FC342CB38E2F3D8EDD0DC5919433386D1 -14B708E1AE5F01C2F08B8C8741D67BD1F02B4934A76D79B095AF43B68958BDE13D0F570B -71128A40A050BFF9C5D944C09A4B5D8AD0758B497771699B4E577436B15E31EF7D804663 -F768B9F5C9829EFFD5B479E1A0813E49D48705EFCCBCB2B23A7F0C39DAC69E7E35D7F4BA -770945D9F36A39D251B6CB76C88AD374E177B0F9D703865A69CEB6C0157419E781888F73 -47D0D641C43FF3521C3F380E26ADA5237ADE8C5FEEC8AF046C1B46903941181D958F16D1 -908D95A62869DE2DFD0AAC4D7441238B2ED50CDF729B10961883EC733F806C587C2D8F7D -B205AA3E7F6E34D5A2A2003E8CFDD22A63DAC1B04A11D77A6830CED7D9DA87BBD9E8D278 -275D1626D31054A23E9283FEC3D634BA1544AC5AD0E28DBD03C5CABF697DEAAE65D6167D -0E2EC4BC6C3B91581AC32B45F7ABA1B825848552D1413D1B5111168959A23F54C5B8E5E1 -B49C4096D5F546388E1279891E01D1FFDF63940F7AA520570B408C9C2CDA7F5A4B058919 -53B35D7523EA69927469DC90F6D8E15782204AE32885DC6BE6107D5EEFB29F69FBFECE44 -70CEFB37D0093844BE3ED424EFF064CF724A54B6B720ED020E70ADAC6716787FEEA1F22C -84A5E59BC6A643A29F50E3B76E6658D5BD8CA3554EA68CBFACD0CA0882B8E3389EE7945B -AC71B219233EE299C4C8FFB3BEB77BD483DE2A89DE4E697FA3A057EC47448CB99A7F1696 -00BBE4735D36408548405A8D4CE4209445DD0C4FFAA271ADCD14DDAA1598D44247156649 -1009AFC9B40874D4499857EF50BA7038F25A2159AAF9AC535EE1BC83E515D1439057F042 -C62DCB063AF8F014090AC771CC83DDFFFE0336CD4F14E3B6397E7AA442FF3C385A5A4B59 -2080801CC0BD5EA5F608A7936BD16248E3CAA7B49A475BEC9720EE44A06921A93375F344 -013752C467DB023F3F01FA7F427121DE5C4AFF495A06932C52FAA62C043B22ADA265BC90 -61B7702F9E44E326B54A423A472D23817F6135E05C1DDE477A9E27F42F5555E8FC22060B -D53ECBCA45C31C09BACC68EEA5126EE5E73502F2CF42BC5916B95590B778D556C4DB817B -2780787590B62405840D01F6B5301260E1EF0856219246C2CA7FBFB307FA728241E9A08F -F8FE0F6E708228172358EB98895B3C3C7FBAB501BEA9911A6C6769456E491C89B2FBD751 -C9339E174850B679B47118416AF8E849438FA52C4E2A0D1D8AB94385FED3747F9A8E78E5 -47FA728DA9C44F5D2296072A8ED789FAFFD237802988A20A8C16F78A50D2AB87A2BF8EC2 -8503F757AC6E9E556686A37D84D7B9DD81345E70D212D3D83E7D074A2BD9191D05205B27 -56E74664E1C3169AA601EE6276EB238E3EB9586C37ED4089E5C7AF97021FDADB6AAAF8ED -54CF169A574A7A6066EA74B3A255CFE9B6FDC2EABF4915325BEC03173370C41B71A65C08 -C4C809A78F52E89A27514E2771572235B8CE4E21229953786A90542924444BF56C163D41 -BCBDA2BD5981499D1BBFC7F7FDCD4EBAE43341EE9EBC04A5B3E86ABAACEE27AAAAEEA722 -63298EF83E19321B7CF9B1FAE2520159C2731E6023FBDDC81296BD2303788705D7A6FF72 -5ACD9365879F3742C0A375E23B124F85E2E533F958EDD9CEF05698E4F7E2C035EE665851 -E1B9B324D381BECE9AE126892F2B51826E44B80DF026FED2832BE1414CDC410B142E9248 -380FB3EF59A1CB8944C21E3B8F0450293E6FCE004AC4B002989C877AC2648964D137D881 -7C37A778E0EB56D243F6606A883875808323739C0B55B5F82C5BBC389566B7C24604D9E1 -9070CD37A2199B77BD81C6C0E4317AA361CD7F3D4CB2EEACF59D09FCB317C2E5656DD9EE -54D8D9C2FE364E21FDCC38F9FBE33457A70B75A4F9BE1DF8B6577B9E103F2276B77BDCA6 -0AB499915F331113F04C81F9572AFD95245AD3573A195D9CD1AF7D26FAB028F7A821DE62 -8132A99E8B39D4597457CBA2281394CF68069397BFB22BCF992989D8AFAFF25129A9F9CE -040FCB4752291D822EBD224DAC909194EAA4A07FC65F1EDC6C2D376190875FB8D2D19820 -7F71663705D83FE18CCAB848C11C5E112193D753B6A2BD9183054AE6021629E7927E4064 -9CEB4114C9B59F9827B98A70052FB67B5C45360C9C272DCD0C7DAC2A515707F6B63B2718 -B53B84441A28F777122D848B490C796185AD91E8474267D48B36DA7E3A7F70FC0F9319D3 -F937FD90AB3859794AC608FB96E283ED974159234761B8A114C8856FA00353C44D5C3976 -54488B0CFDBBC5A243595E2950E2ADFF06568551EC636B7D18FC1E68130F6623EB109415 -5F58F46A636EB98B30DE84A313ED1ED0EC0C8032B21ECFD11F2292A31E24E702D4723F50 -632F9D91DFF52142CFE2749A16B5B81F0ECEF869A7486191A3A910AE94C24471231B733D -FD6645C3856F341C0E1ECC17432635133CF66336D3C2C4F103C3EFE59FC7E45545A0A5A0 -CA19C0DBBF2B8CD3CBB482CD5BA7EBCA2CD5AC9E0C201FA4ACE28F00EB491ECEC3871AA9 -C0A303D585F94FCE1365117A59BD2644CE990F0A04239ED4B52CB5A0639BE554A2FFB03A -B9BC1E6C7989680B41BE26D2B01EFFE47819E737BBDB28868E0CEA2FFE4C7300B82E3016 -3BEEAA5EC834B2A2509BE99FCA5B087861C63EE1F84AACFA6FD77543D91C9C2E525BE531 -C02FF04A1F50C50B1F9CA7157F8A7787DD417868E48A035904BDA647EACC821F0ABB4053 -F19B502075211F1E1BD2714EE43D1AE7E19F8D13354D331E1935BB1246544EFA1DE7390F -7A561A6CC3F48C222A9C6C0B3A89714A16B3F61B6E26E3238FD641D431C7F6EC8005ECB3 -113C00A96AD8842746CF3D457F0F951D90C797716C3E8A08059207DBBB40D9095D8074E1 -069E36841ECC7EBF2081F293C194A044F5FD536D0F3B6551AD3CEA2FB84A5A32E20E34E2 -CDC9AF5E6839C3521EBECE2F4B39788F313FAB6D0F089BE45A7F4FB021D15C2661BA55F8 -691E8A9E5AE18FA617E5AC262F24962132E051BA7DDBBD3C5E7B3256ED5BBF7A670E0091 -B3AA0F6860559521C858CE6FC640029FD9D5FE03D1CC485A27080DE3BA08A36DDF87C81E -CE731AF1CE3F87FB19F91E324FF044110AE7C39110F9787C7F69E9C09FFBE37BA8B3DD17 -9B1EA5E176D6562DAC43992B8B5AED68898B6D56189426727100A36D92E2CB96672F58EE -EF30E90EC2569CEE9DA1B590F16B88E5E55FAEE2477E36E9CECA4D4DD9E969FC0D27CB94 -B5C3E738635D3C9AB4A0191CB553399EBB25D1D43DDA545A732B66DCF18A913EB214AAE9 -A408BC1E04449C07E114142FC22AC8639359B2413F3ADF5303088B00DBCD6AAF1ED46964 -F749F420207CE7CB3A27A4C260E174E17C6892695B3167B65271C232F1C67BCAD83B0216 -278FAD19834B58E7E1A2813EAB45DAC586EDEF11FF9CFC828811CC290C4EA40017A4BBD8 -889D5373B0002C0DCE55B2EABAB80E58B4341F386781264AD72C9B251255C0983AEB350B -03410B4C7E7E2ABE655E3A7AAB548D49C1EC489006EF4167BE2EA41CAD999E4CD6328ED0 -726C61B51EDF0952909C38480A6E801ADC241B50A972D31C7AC63BEB3746172F1CAFFA20 -D6E1009B9B1E79308ED3CD70D3F2975B0D241D8CDFD191A934E83E0BF3A938E19B3C461F -566B19516C068AD6BA4DF7CB37EA8343DB1ECD5CAEE329432E15147CE61AC4EEC2866463 -557C05CD59FCE1659245B7D8AB628F2ED8B24F6AD0B1AD37797FC20C098445EA1F43E3B3 -388550D0AFD24C74AAB269C1FE7596CF8F010D665111305ECFDEF52E89C240510D5D83F8 -FFC38DD47A537F55F7F79CB460F36812A1E3C26E8A7DD6131DA076BFA93D6C03E6E4C279 -D720B41A9CCD6A58EE1BD43A3035CDCE464BDC7CEBD79B867F30B0D15400B897A5ED7324 -A4A75568BD1211D036A5710F23C7A2E1D3F7E45C929FDA7ED13EFBEC7604427BCF853F92 -D954E627D0ED842663CFB64A2A6358C86F80FFB6A955C17B04B096D76B03DA9660D93004 -C44AAB74C40F99C702BBF33C4FE471ED4E6A0ABF3B15B340708D5D16FAB80D1E51F7D1A3 -8C7AC19A871C5D47963CE3CB961AF75A47C09B7AE97A3EB1C16D64D12A0798D5CAB48F68 -0E6B2DD1F7BCF7FD97719CBD7FCA4BC1CF31640675AB798F7A7CCD4E4A109E0E00A806F5 -8888F7A7091A9B7CFD350599C9AA0E7F679AB200035F48A57172C499737631A4F442F3A1 -BF5A3E5A2B77E02B66768DB9E76AE46E403E0E4BFBC1F14256ECD89BDF623F266389DF28 -AAC38991DDD4743F4A3B8EAEA45BF38EEFD1B7D3998B9B8542E78EB9FEFCB9D256EA8EA7 -6B56BA2A4849598F03483C59ED550D3508D12B35E4B82C2703883BBAFC0885BAE8B1440C -D2E368939FFE45BFEB172FCC597F19B089FC567332C97C3567C9DA05A3B99DADAB2BA61E -B9CFC9C1407322118C7B7BE2686FB5DBF0D31C5116F2F232AC8C3B6B1ED3E36AE2E9A638 -1E714212A76D2733DCF8F2BA8C1BB345A8B3D98162EE87C308539AEC3EC8EDA6CFDC423F -BDF208A89A906314950C1877A12E14C1DCBE5033474850128DFECB859E33F6EE578BB384 -DDC252AF788BD61E95E5375D134D6457B0A4690D7239440FF37E9F67CF10D1EE312653A0 -22702614C537EE7FFC677F630A079A98139EAA23FA2764B1D37CF5360002711890C12374 -CE980C83FF11E102C7AC31E4D96862CD3B8A77FB59FB8F3932750F21929B00912332196F -D9AABC0E4703C7BBB695FB1EC820CB6F69B9869FB819DD43AB4000BF70FA0320B5D3D2DF -8801021F0B0A45EEBCA8BFE6B616DCA4641358A4A18CFC749B17058929CAEFE146183C73 -BFD0BC668BE2EB8CC7003FBFC5F79373DAA86E4D9B65953031DCED7595D7779FA985FB1F -176161B955D22591CD434DA21E63FD9DF743B49B16A5ABE84E74293B1CE2BB4E2481770C -9B90A6641984001AF9E6DFB280D37922ED6A77D3C92F9E0F82B4CEC5FE92CFDCDF708EA3 -47EE98261C07F434E88A2042877D47C813992A1DBED99A6898288156CA26C7E473988BE2 -F5EC8DDD0FEE7D552832B69523330C12C6F0A307CDA286454EEBEB0B236AF69390B6FD9D -3546DE7015FBA1D36B08769D5DF07FFCC8AAAC31825F0F515813221E1D467F126CB9BDCD -E95DF5C7D64FF789BDB3A3339130A974D96606CBB812C8AEE855F29C5BDD9BA49FBDD481 -14DB68A228B685F35B5C33A9CE2CA9E0C30690831780284D6A75C9F9D86CC5A492EA5264 -09E1A2736EABD5FEF257F027B7363F8BF39519DB2940A1DFF0B3DCEC5CFBEE09633B4DF2 -6C29184ABEC66BB894F685BCF2AAF1301B1AB15398050C86A84E87491489F15FD2907D7D -ADD73C36FD0F7A40E021077CDD8AAA237DC9CB5E13C00EB7E91353BC58E0B8870BB319F5 -074B651F0D5179AABF87D023AFE75B3AA68D62FB959A5B6EFEA8D204C09F72B038A8C5D0 -9977F1457ED158E3BB57CE63EC2EE4577DE42F9D91AA5ADF0460374A36C972C33616D040 -2D8C1257C018B736CAD8BC182ECF63CEA524C8B3835E9CBF7618D930717C9DF018778787 -B5BD608E6DDE644B3CEC092A232B66420872C1412751FE7A72D604B7C01CB200506DD521 -F45DAE82F0C7CD4AB3B8E2E1B5A9B3D13546DA5A45A3195DC9A550D428882299614F9E8D -47E1674C7A95FE4B8E5EDA9D9499614A78DC322870B32E916C14088CFA3A76BA4F7CE4B6 -5C979130800F2F2D998F48DC5A2EC1CD18496402265677FD28F48CB38145EBDB30D2BBFF -15CA9FAEC6802D7BDC7F1A281DB9A6553B7D3F757A1FAA6AB91C0D31757FBE705EFE4C71 -AB0749AEFFE6768B35A0AC03636F4757B38C2F4C0A78EAA3557473913AC1AD37B72E79FB -75E2DA3A4A7AA867032A952D519BC5FC9BB684D0F21A661DEBE79B1C1513A16D8E32EB13 -E8DBB3F132C87ECE0972BF63001E8B9DC6C3F445191D536F8983B142BD94DD8F41C8756E -EFDB106BDEE3224FA448DAC03ACA80AE79B7DA40347D3C3A643B915C51BFCB861438C546 -1A59FB26B538BDFBB8D7DE77955A8FE6016F770BAB928D277CD4C2B3FD3839FE75308F21 -826B36084E485927C5DB75AA7B6133F468C71D218307B40CFE1BB6AD24E3C2240EE17084 -AF6C1E0D83CCE1699FDDB4763BC15F722D0383F5F4638785268FC439EB0A8C6B5AF7B938 -957DD111A83BA935CCF13A9DCBCAC9188CA67EDF1A6D18A34C956DE87418EA5E4796E59B -D981015C8D276CF4D8884AE423314AD62781108BA767131E08302A926C44B858B792DC52 -FBD6D15B5E9C4CABAA159FB5BCA5CAD068A5A718613598B518D015D3B6C43A01A5540849 -EC15F399A1DDEA9BDC47B409B10067FCCDA5932FD02BEF518433D8E7C83BA8567A2248DC -2271BB39F07414DF7655BCA33FA7811592168ABD559F49EC0F7968E87130093E607C2F1F -087154DA681D1C92C1B5EB87BFFF15C7DB4F8E319E42BDEC5B95A2F816BFC0A0CE997CB8 -BCCEA3DF23280D4C922482CA09EDA8C31F9C5FD9C22480DE591A3649A29F0293F976F366 -7A66D3923D6BEBD0C1A1F06C11C2C4207B2981E91DF0C0ABC84CE8B7B23B4837C51E2A94 -A7E3AB209AB5B99D40F39B1DE342502818A23235455B56BDCED3ACD910CD92E9E71DEF41 -0E3A01D9B7156F9DE0FC8916AB29D79F5B093C1CDD19CC1FDD6FFBD050ED563CA3C60022 -404A2E53E9EA3186A3177A57FB4B726DAFA37A4FD45D2C191E3E771C0CDA22EFAD7915B2 -15CCBD2A35E04CDF4779FE80B980ADE2D2E71B8F936D905AD7382B08C43A3ED6BBC5578C -80417621C7A3A87079ADF2B635671C36A1F57B971FF2918E14E80549150AB492D9709508 -ED98B983A9D40188F93847967A10FD16DFFE2C1276EACD959435C36899210DBEA62023A7 -ED706126E4E5E005B7608F078E3F0A42E87C84B37215F883E0F078127D47C4B362CEE951 -69F92B2887F67A3F1D02BEBF0277BA479264E7AD5E1087F613330246606F4907D3BA39C4 -644B7F9BC608BAC3107D9C66FF7CD9E9D624703055DFE0262E96B17BF017579001A7EE29 -4F4217B697CD9A397D35D8CB781D9FE282D9082D273AB082CCD017D7843E1AE3A41613F1 -F69AE113E8A993C83FFDBEDEFA92A9101B54D1AFB5BC7B41F3AB3C610E60AC17861E45B7 -34D7706BF6971921CF0E5344DC613EB31AB4E31775D990CEC15AF459BE474959EB24CABD -ED3B7D6A6540AA81B806D326D7614808FA2039A6675AC11F4E90EED294E867A84116FB5D -89BEB45F738B1275BBB4106108FB19D6EA4CA71E3B0C2BEA1EAC19D27EB928EBACA9DD62 -75865C4B86025B626202116190ECF58F149257C62C70EEEC110B540C636BBF747801A21F -B32A82CCF24062325AEB3B5DFEDD49AE625635C34CC330A93F1029F3A3A731537A0BF076 -C938773406C1670F4976AD1AAA5D3629EFE797A1133A683FBEC7DB8C480B32CA888ABB6F -049CDD5D65EAB1E23EABAEF26756618BF3CBA5D62286C938D3F6F20C731DB6044B89AF92 -F58FE18DC156E0F0D7A548C6D838F57899D7A693A6D158E5B9A19D4CCE4CE574FA1F9570 -7092879FA2C3F4AC5F223E3E0A174B97BB2CBC7815A20FF509B43D6EA17D515BDD9B3CF9 -4827C88EB2AC1FD13192752DB92070FBF319E4DD93EC6C9287108E248BC3F814CF3F85A4 -F6EEDCF1B78BBEE9987BB0767968894F13E299C79F50E052B7627584F1C78BC8EA588B4C -FB6C1204AAD2D47B42955EEE8563913BDC8167B5E82B48F3243F218E8832BCEED22BEEB6 -1B434A2AA2E93CB5654868F0A7E049852EE328F6A555AE92CB23702AE1B71B5E6EDF1BDE -ED68CA1E96EDD0A9B214C02A429479FE612C312D8B8BBE3DFD711D25D816709B78125476 -4AC1676AEB53B4CE261AD842C485829A8DBB25956041C5BBACB27B75F0659622F2791718 -110991560C261EC4834C976182843A56DC1918191840DFE95A5FA00624A6C24228805545 -4E7EDDCC9CA865B10991C4B73BBC16BBF6F0F4D4058FE9163BAC69EFB2A3269FE9F2A092 -BE8F9D59D9AD9F434998B44AB3892EA4360C38BFB150DA95EEEBA94B419D9D126410188B -475E794541F41D5C9D12D96BEDA86DF04640E6D766F0276BA1D0EE6E3B47A758D8D2D6DA -90B97B6ACFFA7D7BFEDF0BF7101F32248C7C72560F770D52AFCDC8F285846E00F5B0A83F -346B85D71DD49927304D228E2BE7980904A813AD23D5EE752D210FA2EBF72200914C8AA8 -ACD6B586437EAC4287C0D3C569E1969E71797949592DD7E1A65096819C7F3ED6218F1D0E -6FAFF3597787C9AF1C875E66878D55C64B2140B873C14F9D344E80F6E1434D0814B3C55C -7FF47038B2DD9104B7E836E0804B3E4042F5E1627E4C871AF0C42B498BD34475CDFD89CE -72E8D6DEAE27C84CBC4270348B684D5DB84C025A0CDD01F010F345ED7C75251990AC320B -AFF49806BAC46C8E87895DAD7D223A89AACBC9745439B6FB5B8603010AB29F2F9D3EB3D8 -24E2471720BC1ED2EE9BB61682AD6328D642B131780AB02A598BA9806C8327C43E1880D8 -37C5CDEB36BFD7812569F2FCBDF7B68934689238D59AB7D111FBF5BAD7DB4E85148373C9 -6016A50269968F2DB4824C1BA985C6FF1AC4BBB99F57232795F390BEA26222E79BB218A2 -23E68505A11925BCB27A403E5D27C9FB0EAFB29B7B6396CC58431D267FDB5DA11A64662A -EF150E3C268732F5EAC6C2FDF28FA507531ECAEBD55F4B0AB89D8F4C4CD41EAA211EDFD6 -65091948FF530681FBE7919E476C4DBE1397C51E4AA2C4BA1F0BBA3ED714E766E2638ECE -21B08E93C2EE29FB886C75B9436D2ADEB232736CFB5BAEED34EB47FF78CE41C6444377DE -8B7970BB19E9B52F5422305F14BB7AF0BF98F46D1D1E17B13E679C99112388F39827338E -E36498823D40CAB56D7C2749AAFF144D3F89A703F2F416C34592AAA4C6C30A96F3287868 -CE6F6EAA22A55E06F5D353F441E62A851A138B6E26631EF586EFA6952D428AF7D71901A9 -7E5BA59D462E10388C233E191AEEA380D9E2E23579C4345DB63F7691D0378F950B9CD2C2 -C0C17A8CF6144A7E81CDB3A5DAF7F2AE6A5F92E6910CA0D7A50569EA890FF71DD49D5012 -BD3FA623A1331BDE94EA4D2CD2C538AF787632B6339925FD6CBFD8ECBA7CC464B31DFFCA -F79AB027945A2C1E9C058ED8F0F3221A0353961BB2B2EA75876B74EDDDAFB7ABFEA39F38 -36A8E19C9372D3CD704A19B301BAD2801B16BEFF75BCADC90D2EEA514A199105FDAB37EC -8A75B14E67B638CAF1ADFBAF70D38355A66B513BFEDBBA2CC6981C25E364297C873C908E -A288D930A8A18AF24C38B92F520DB5A41D708A438BC39356730D028198A08AD3430237FB -8EC675CE19EAF97C06CDF706B138EAD722EAD2C7C6108A4C474210CE38A7A4EB0FF573DA -59B024BED3579A7C870AFF17EB284527030EAD8F515D18EE490FD5D32545527F38BE7B7D -CE9C1D1283B1771AAD8953E6D89EBC068E1C42C8431D6EC365F736652C4D74C627BC0689 -A3F273D9D9D94FF32CC504AADE91D4E17105EBA804952F566F0849A34B4E150223E5ED27 -786FD43209CC4F4EE8F4DB98D2C1DB336AE17E745DD8EB3D95A9984A632475430B0E80AE -49A5118C73F0E060C7AC98A8F03E9E7BCA9492AE7D5CED0AA5F177E5EA1F6FFB5AA43A13 -76C8FAD9344ECD8E6B64EDA15AA52B37DDE5AEF3242C236D2C5B401000EE78D62A889665 -2553636E765463181099C47679428ED39AD2F77F8F35DC07A726666751D8DF804635DB17 -C4A81D61036E8CE9CE5E441226584EC469082C6C765909DCE05DD9C9D932F295EB587B37 -C7C32818BA4126B809ED89CEC7F14494720018DC93BC5F2635B5F1ADECFC9B4D2B028FFE -AC248B2663FCD7A43E5468B43FA11E3BC439A5B519DFCDDE7403AB81F0771A7D85BCDF08 -B2C1DF316723EBCB4FBCEAA61454F48D6A354FCAA92E58757D9CE79F92166468522C00BC -FFD765E0F3BCCE1C41E1717BDAD21746C86310CB9490510FCE6DB36CAD377215650FD82B -9E3FD5E1188EB4D87A216B9B475DF5B634C39C87DD4B89EBF8DD52E7850E680F9CC7E610 -774D1F96C682B067FDC4456954D74B9D1FF2C18CCB9FB0C059517D174974D58D3376C32A -53A2F6C1E6844152C3EB1E954A095D9EFCF72158B0C58A1B55EB29741FFD07F55030A9EC -945C351CEE57273FBD4ECFDA6EB2A4FC374E1763B50648C68678B5FB5CDA2DA8D87EC85F -738F2C2F2DFD4F93E44CD2BC2BB5B8103073EC603487DB06311F97BBFBACF934E3524EC4 -3006CC8A613AD9DDADE1023D0044F0C27F577900A62888C75FCA2B1F7DC59683028FE95F -78039BACCF4E9710D3594B1205B5B08AAB01B04827A82516467C561E80484C2AF83781E0 -F947645951BC5CA167AADE20C8AE192CF9F800C409971D09BD173FE2FB130D8C543F4B57 -D7170BF0146B6138A12D9B04B717CB244E68A023E96E30918A1CBBC4A17EB994398BD47D -CE04656333D38F705EE4ED3A75E569A68409CBD18DF1FD537ABAE8E5D4E67D45FE12CD4B -5ADE49AA221D208F8C0C93FA8D659A01F2B9AC7869AAB3A69C1DC5B48FB8A91039BBA6E8 -3FE9985115B0B304F0E5293FFE5BC54CC84840EF951EAE7E4A1F0D4D1231E0A2F505F54B -9CC2E373991495EED14DCF911DB949E4FA0016D5DD8D1126BE6A149AACD3B51F26347320 -A064FA81697B41AA19D5EBB8500022559BBCFFEA94E6F6F5C8755D9B669418107341FB18 -6855A75AAB2D1FBCCD70DE7120277E9B9D8C9BAE1CED962255F61D28EE29C001D0758578 -0B24E2F7B0CD7EBE33EE42A55A217C5832730B414D5109844A5E9934CA865AD2AE9127C7 -CAC28FE451C17A44C8C79395762EB7747B2DD7780DA0B2145CD2732B2D62724271FE4B5D -96B882BF2C73F1E2BB9D700B83CE16AE2D6AB9726E12B09872EA940C1FADFEF125F89D09 -1FE5580E48ABF5493F9D8CC50CCCE629D6F8ACAF3998943225C5D2D795A1A10E2C1AC6D8 -B057F4A8225F0B24E4D6410F4A38D75D14601250E427EBFDD43AAF5E5C1EE0CCDB6D4504 -E3F854ED2EF4E8BDFA1F7422AB86B17896E6D3D0B14B81C515B489C3BE5B471461D6901D -B39949A0B137BF9AF0C3A8124BB3FB4C1DC43A9ECCC48DB999E5FEB94B60DF942AE440AA -4E69A70EEE8860EE2CE8570ABFA7519AC16AA1991540596881033B01CDB54E4DB401430B -20696CD808C73AEBB6E61A5C41C96D7FC338E6E92A112ABF427C6E0EB23E278B3E5967BE -13998C6786382093F74E2B067D428E9877F44DF94F6FEC76109987F3D7F13CE7C4C24648 -61128BB2C51BC858F4B87C3B3938698B4CE4CEAC0A73D872D5A43269B11B95D85FDB1F49 -545527BB2AA699944776B9A623DF59DB1B3035A6177A713667D78F7457C950D2664BA6DB -1076009612A6806B24AB931A8466BE6EED4BC7776F1AB926213490BDA0F8E65E84B960D2 -625E6FC88744371574FC22DE9CAC8E37D0F0BEDACE16C034A588888EBA681CB89FB9D2E5 -3F04BAE4629739F91C372321D3F2653E4D24439E6B8AAFD71184436B86AA3D9C0B170A54 -728385BF8B6ECCDB25ED1D3363837400E80789F16FC73CD235568FE7F51385693E41555A -F53AB56069EBF4F2B5D0C7859E988DCCAA37F0AD98EB34169D3E9BF7C664BE123640569D -89F1C34BACC3B967853750B3627FD055A2AE8B2BBD6DDC2F6AC54BC7FF5122A540D0D200 -FF8FCF17DFD821E8034BFFEC18E1CD7DF35D4E1D80614347D92743B7CBE2910AD330A5B1 -C1D5DC95379F601A289069159AC6183E283257AB2C97C8BB3D6500B012BC6A9F47B0A57F -2639AAD56552486847B304AD088CB8AEB07D032C4C275029A69563E350F3D64A67A7B88D -561AB9C9DE1FC593DFC448FAD9E42063AF99A70DC8EFDB928FEFF2225FA1DE159DE073E6 -3A55D312B9B1810B375E116D79617D0F348EB2184E8A150E94223C792193E1A096646EE2 -A0D82C33EBB19E422988824963C50BAAA8598B9D51DB4149A366F621852EF0B17B4A41A2 -3436A438D8E65735F6B4D1E2EF89A12E4002AC8E585BC407EE6F34CD2D7046E042C463EE -EBC4971A00B9A5F29102455E787BC66620D627385BAA3812F6B0BCF03AF1728064E1A8B7 -D7F5574C5DC22F5C0472CBD0E351F430823302827B31BF2338D85F80DDCCD3EA5E49B9A8 -8B8BBE6B0132C8198DA4436F609C27D13E7E561F05E783F04630B3EC03272F33E3F08419 -D5B4C16B386DCA42D17E89D7ACF46F6F4A79BBA082700F7F98327F2C7E62D8B1E6BFAF8C -212819FB632C3DCB4AC92A8A0F94F350FB0BE0C89503CD0A52B3AE4817C2CA7193563FE9 -20CC6F4E24C116AB47AF0E3313702E1E96BD9817C1297C30FC7178314E401E4CB3847ACB -1CBB1A672D928C1945E6629F626F66A679E9E39263C3A6804BA6A7D18F0CD0F1E01FEAFA -7786ECD7026C94DD0310F20E8BF525CF5EB072E1EE59E66FDBF54880401F7F66A4C5D019 -297B0EF4C6D3478BFE76B93FACE72F5CDEFFABEBD78DD06E377787E873CB76C7F5130748 -E42599B216AF2254DDFC5AA8146EA01E76FFA094DD65EBF264C301F1311A53E86082E20A -9B5E98CADFA0A10BE2A96CA3D0A33104911C1EF4CAE7E4E7CE3F6A765952D3E72E914DEB -FC50474634A05EC92FA59914A798E42044484FB6F7E3E5D1AF45828422B971D5E7B91601 -848A2624DC276C47F14441338E47FF6F1741A38939A8B75ADC8702F0553ACD787BD49F4C -D4D2CA40759C000A619BE27C2923D72438EB49D684DBBE48DBC67AF1935C9833B9E25252 -1E2869C7E808FC1ACD822659AC94F94FF2E11174FB7A7D199EDE962C61672D9F5D2C93F1 -BC99052FB782D94B08617E3C7BF232D9EDD6FD466A2ED7E55318F6E789E4A09F636B91E9 -6EE41F556224A8108BE1CFB2A83A57BA6C8995B6F7A5BE1D454A18CBF2E71FFC4D23A3B4 -9A202FEFF154CCE053BFABCC83CE4FE091E31B4759761F3D535348EF85AE276108592DCA -9A84E1EA28786F871636712C1B85B412DFE705AC768AC8F5B65BD49CE921CDDB5C4D41DF -BB2A7F14263AD2295F25ACFBF3F621D19437F0DDCB174280EA65836E9DCE638364E04085 -29F239946EB500E4455E7B79A412EB03C72D7D18A1EFC6A5C86AA2987C43E3987A5EF3F4 -F35712C790EB5137ABC92B2DAE1CD4E06E21B0DC03E2503687BA0DB73A4DDDEFB41C3BF5 -199ED14731480556C59F1127993C587517CC2406EFA6529122D90D9A9E4C1400B97B5DA0 -3A17AC4C5E238267969046365CA9ADE8D7C76746091704DF72709098602891ED11EE7AF8 -FD7B26DDE5E9CBD0BAB0E2E8C2B6BD49F2FF4CD016EE88B55F087152E7B2E4F67D081FAB -847050548D26D0FE5365833D2A4791018284552C1F40D9ECE2605A3BE0EE2ED5DECE4D4D -A8D5D81ED6101786D8AF3E5EBEB78FBECD7D3B471FF8C6900E12D0F45671D44DA582421F -9BBD5759CDCC9FEE1991520E8F84BB8ACA4A370237E4C4FF92BE8EE6C307DFC47078E167 -DA4C7B2740B9A429012F4BB8519507F2A18F51BDD82168B9576E29531A5B26CD7B0FD7DB -6E346CAB301B33CEBEE1F3D61D73B7D6145F89985653445FA519F91597A0F984DADE3094 -7109124D39A2A7E6D1CFDAF96A73FA0849075111F1ABC010A6871CC05709441C20CEF9B9 -A9AD1A8B1C207D0FE1E7D9D238D0A65EDAFE0BB3802D68CBF0B4CC151A8B330DD04E07DE -C3329735761D7FDE1ACC1B0E86566891E6AE571EB4936A3BC13A3684A52CAF7B7BD84C73 -C68F436156F5A1F05A1898FEAD0F35CF7778CC824139B47484C71C4EE3625F86D1B12317 -7620B46984D92F7C1D38D392F8981CA76FD1678CFDD43FA5F2A5B5F92FEDFF593F699866 -F063DA7E0AD329FF3C45A2236A3F7A6D420E3A66B2BE1BFBF1CC584BE3B68BA2714DB085 -1B803EB1A075C6B1495099C0A5CC7C51369BE2A79E23D793BCD72A8BD7DEC3E180ABF90D -D5D4137A796716083BBDD2C75EAEE01531EABFBD93F8D442525DD798E799D7EA30AB15BD -9A20FE527E524FD7D6BD01884C12044BD7E81DE8293F50F63201D31838FDC0C7B20EEB93 -2372EA2F80F325EBE41BFC037B9FFB5150E421E2E785B5DDB910C3569DCE72A9441AA858 -D0325B3BF2FB3FE83A3D558A63AED58F48C5ACD609D5E1B048A6B519E061E601F4387F03 -7049B8CD97F402EED07DF88A9FB133E9DE42A205727495050C9C6B9D346E0B159C704A3B -99F4F4A11A7B530F48BA5EFE0C6141F6F973C844BD43119D3AF52E22D2C6B615E53FB90B -E1683719BC94124D51559326EDCFE600F75B0427CCE88D215A5B57F6DC59F504F2A7AC5B -2B90F94AD673C8872A03DCDEB8712634E1BA3CB2E227ED6535160B62FABBC22B7FBA8174 -70E62F61792B40AAA5454010B2B008FB1DB7C11038CB98C8CD5401C95DB173A4AFD3CC0F -7E5F19B6DFDC8BDF118786ECE351307B0E4C30233C0177781085FA1B2C5D1EF51BF9490B -B6D1CD1C18F0782098F9E484F9420D635C79D6AC0740B7AE70BBBFEAF8B8958BD921D2A9 -798546BDD7858F810FEB5D84CF411AA3827A50420FE741BC3812CDE1865F4A2EF6A25A4C -ED7EB24CCD38095AFE425D3B0A90539A1CD93DE3F35B020D047EFCE7E1C5C18633B419A2 -1167ACFD3CC3EE0629C0717AE994F151BEFF9EF0AF6E0F14358FBFBA8B61D669ADA8C47C -AA03859AD7E8C07FC39514A8A85E5C5D02B5DDB48725BC15B70AB80FF7F563D481106810 -D8DF1EE07EAF9DB56374124F654CCB454E3C7B0BB490E0D9CB50460E1857C32C95021954 -35C010736A65A00FC28A348ECD4B494F5FEF4D236FBCB951535C546F248F0BAA11F372DD -67F838667C2657A7ABC4631530F275D7A5ED73DEC263A1749630C251ED3F5B9708876730 -0ED8DBD0F588D874267EE87E8486B700B58DE87DA46980B752B5EAA853699AE65D50A6D5 -1A41D217244B8BC5C39D98272731E8D605EEABE0E6E487BC89F5962D2423DAF0C580D424 -719EBA7E9FC3C8C49AA2ED9BF1B679C51EC07D7C4F4401DA63B66AF7061BAE89C443718E -EEA6FBD03E21DDAD5A1B2C251FF101AADE3FF3243F71CA14F19F71E3CB8689BE24E506C3 -C2E9BF2ADC82BFDBAD0C07082B75EAE1ECD31A8B90B9A582FEC64B65A8DF81E54B867EEB -E71C191443897E25FAC6EDE419F11912D284F8819AF00617BB03330055E5C49023BD472E -B32FE903E2C3A3BD9452389DA13CB1E4662ABFE88ABCA6DF0E55878CADFE425B8BF42313 -9107696719E947249B70C02251E24CBB3F3E027245651181113F3C2DDA0FF61B1243B6C4 -CDB870D3E05B7DA867C1853A6F8E53CDDD654831048A6F58EEDE299A70E0C18C02600DA3 -7D1507535286BD1C167BF37F925C8468967709EDBF94DFE0BFCFF11F0B715C77BF1FF7D7 -0BD8258DBDEE61ED4785F85DF2C52157FEC3C01282226FCC96E0ED8CDC8874A209E54A9C -0E8EDA0887E0561CE0B3ECBAB1019F39132E6DA0FE6761379C4424EFC66C36EB4AD7D125 -B88A0A7C19ABABD4A60FBDF0CC1414A77837EB57609D6E4C5DA8A37D18B05B4F755776FC -1930C15DFA2B545D8DCC65B7C8C4A3B9A8DBFC8C64CF90C1047828084070516FF3897E5C -CD223CA4E5DE09834C960D0483F48156CB48B73EB3387A01208AC9991949027675AB9AAF -B3D1AE8791DDA72EEA9053C50218F89B65935D6E40979F583456658C00C593034A067B3F -5B9F7177E6032F1F6BC96AD544F8B98472724D7F48C91D08B4CE91B5EE736A22996CD971 -34E2D4221E0891CA4C8708A6059DB1C48350106A304F7000A1D165D44CCD6F6EE7EA5434 -4F5506C13BA5D12A04548D75D266E0A027DE905EB4DF15ECA1CDFA1D4EE0B9D650AFF4A6 -3ED6A0AD78D63938669B505CD5B799DDB4A3BAD89CAB921F18D26DC9B581B0E28EA395A2 -349B5909107EE11E9CC364961A335C913A34094E63C9163E45A5FF43D3B58E5101E8E2F0 -AFCE604BC96F676F942301846A6F3C54AF5A4D60F37B7A4C3BE982FDEE76F0B8 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -{restore}if diff --git a/locale/ppdc.pot b/locale/ppdc.pot deleted file mode 100644 index e69de29bb..000000000 diff --git a/packaging/cups.list.in b/packaging/cups.list.in index 3bd9b1c25..c901371db 100644 --- a/packaging/cups.list.in +++ b/packaging/cups.list.in @@ -280,10 +280,6 @@ f 0500 root sys $SERVERBIN/backend/lpd backend/lpd f 0500 root sys $SERVERBIN/backend/dnssd backend/dnssd l 0700 root sys $SERVERBIN/backend/mdns dnssd %endif -%system !darwin -f 0555 root sys $SERVERBIN/backend/parallel backend/parallel -%system all -f 0555 root sys $SERVERBIN/backend/serial backend/serial f 0555 root sys $SERVERBIN/backend/snmp backend/snmp f 0555 root sys $SERVERBIN/backend/socket backend/socket f 0555 root sys $SERVERBIN/backend/usb backend/usb @@ -299,27 +295,14 @@ f 0555 root sys $SERVERBIN/daemon/cups-driverd scheduler/cups-driverd f 0555 root sys $SERVERBIN/daemon/cups-polld scheduler/cups-polld d 0755 root sys $SERVERBIN/driver - d 0755 root sys $SERVERBIN/filter - -f 0555 root sys $SERVERBIN/filter/bannertops filter/bannertops -f 0555 root sys $SERVERBIN/filter/commandtoespcx driver/commandtoescpx -f 0555 root sys $SERVERBIN/filter/commandtopclx driver/commandtopclx f 0555 root sys $SERVERBIN/filter/commandtops filter/commandtops f 0555 root sys $SERVERBIN/filter/gziptoany filter/gziptoany -%if IMGFILTERS -f 0555 root sys $SERVERBIN/filter/imagetops filter/imagetops -f 0555 root sys $SERVERBIN/filter/imagetoraster filter/imagetoraster -%endif -%if PDFTOPS -f 0555 root sys $SERVERBIN/filter/pdftops filter/pdftops -%endif f 0555 root sys $SERVERBIN/filter/pstops filter/pstops -f 0555 root sys $SERVERBIN/filter/rastertoespcx driver/rastertoescpx f 0555 root sys $SERVERBIN/filter/rastertolabel filter/rastertolabel l 0755 root sys $SERVERBIN/filter/rastertodymo rastertolabel f 0555 root sys $SERVERBIN/filter/rastertoepson filter/rastertoepson f 0555 root sys $SERVERBIN/filter/rastertohp filter/rastertohp -f 0555 root sys $SERVERBIN/filter/rastertopclx driver/rastertopclx f 0555 root sys $SERVERBIN/filter/rastertopwg filter/rastertopwg -f 0555 root sys $SERVERBIN/filter/texttops filter/texttops d 0755 root sys $SERVERBIN/notifier - f 0555 root sys $SERVERBIN/notifier/mailto notifier/mailto diff --git a/packaging/cups.spec.in b/packaging/cups.spec.in index 5a0230540..6eb682395 100644 --- a/packaging/cups.spec.in +++ b/packaging/cups.spec.in @@ -18,16 +18,11 @@ # Conditional build options (--with name/--without name): # # dbus - Enable/disable DBUS support (default = enable) -# php - Enable/disable PHP support (default = enable) %{!?_with_dbus: %{!?_without_dbus: %define _with_dbus --with-dbus}} %{?_with_dbus: %define _dbus --enable-dbus} %{!?_with_dbus: %define _dbus --disable-dbus} -%{!?_with_php: %{!?_without_php: %define _with_php --with-php}} -%{?_with_php: %define _php --with-php} -%{!?_with_php: %define _php --without-php} - %{!?_with_static: %{!?_without_static: %define _without_static --without-static}} %{?_with_static: %define _static --enable-static} %{!?_with_static: %define _static --disable-static} @@ -70,13 +65,6 @@ Summary: CUPS - LPD support Group: System Environment/Daemons Requires: %{name} = %{epoch}:%{version} xinetd -%if %{?_with_php:1}%{!?_with_php:0} -%package php -Summary: CUPS - PHP support -Group: Development/Languages -Requires: %{name}-libs = %{epoch}:%{version} -%endif - %description CUPS is the standards-based, open source printing system developed by Apple Inc. for Mac OS® X and other UNIX®-like operating systems. @@ -90,17 +78,12 @@ This package provides the CUPS shared libraries. %description lpd This package provides LPD client support. -%if %{?_with_php:1}%{!?_with_php:0} -%description php -This package provides PHP support for CUPS. -%endif - %prep %setup %build CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_OPT_FLAGS" \ - ./configure %{_dbus} %{_php} %{_static} + ./configure %{_dbus} %{_static} # If we got this far, all prerequisite libraries must be here. make @@ -194,8 +177,6 @@ rm -rf $RPM_BUILD_ROOT %attr(0700,root,root) /usr/lib/cups/backend/ipp /usr/lib/cups/backend/ipps %attr(0700,root,root) /usr/lib/cups/backend/lpd -/usr/lib/cups/backend/parallel -/usr/lib/cups/backend/serial /usr/lib/cups/backend/snmp /usr/lib/cups/backend/socket /usr/lib/cups/backend/usb @@ -364,12 +345,6 @@ rm -rf $RPM_BUILD_ROOT %dir /usr/share/man/man8 /usr/share/man/man8/cups-lpd.8.gz -%if %{?_with_php:1}%{!?_with_php:0} -%files php -# PHP -/usr/lib*/php* -%endif - # # End of "$Id: cups.spec.in 7718 2008-07-10 23:04:22Z mike $". diff --git a/ppdc/Dependencies b/ppdc/Dependencies index 8d49d5843..ef9bd5a8e 100644 --- a/ppdc/Dependencies +++ b/ppdc/Dependencies @@ -154,8 +154,7 @@ ppdc-source.o: ../cups/cups.h ../cups/pwg-private.h ../cups/http-private.h ppdc-source.o: ../cups/http.h ../cups/md5-private.h ../cups/ipp-private.h ppdc-source.o: ../cups/ipp.h ../cups/language-private.h ../cups/transcode.h ppdc-source.o: ../cups/thread-private.h ../cups/raster.h ../cups/ppd.h -ppdc-source.o: ../data/epson.h ../data/escp.h ../data/hp.h ../data/label.h -ppdc-source.o: ../data/pcl.h +ppdc-source.o: ../data/epson.h ../data/hp.h ../data/label.h ppdc-string.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h ppdc-string.o: ../cups/cups-private.h ../cups/cups.h ../cups/file.h ppdc-string.o: ../cups/ipp.h ../cups/http.h ../cups/array.h diff --git a/ppdc/libcupsppdc.exp b/ppdc/libcupsppdc.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/ppdc/ppdc-source.cxx b/ppdc/ppdc-source.cxx index 43084498b..2e4934a63 100644 --- a/ppdc/ppdc-source.cxx +++ b/ppdc/ppdc-source.cxx @@ -66,10 +66,8 @@ #include #include #include "data/epson.h" -#include "data/escp.h" #include "data/hp.h" #include "data/label.h" -#include "data/pcl.h" #ifndef WIN32 # include #endif // !WIN32 @@ -3541,64 +3539,6 @@ ppdcSource::write_file(const char *f) // I - File to write { switch (d->type) { - case PPDC_DRIVER_ESCP : - cupsFilePuts(fp, " ModelNumber ("); - - if (d->model_number & ESCP_DOTMATRIX) - cupsFilePuts(fp, " $ESCP_DOTMATRIX"); - if (d->model_number & ESCP_MICROWEAVE) - cupsFilePuts(fp, " $ESCP_MICROWEAVE"); - if (d->model_number & ESCP_STAGGER) - cupsFilePuts(fp, " $ESCP_STAGGER"); - if (d->model_number & ESCP_ESCK) - cupsFilePuts(fp, " $ESCP_ESCK"); - if (d->model_number & ESCP_EXT_UNITS) - cupsFilePuts(fp, " $ESCP_EXT_UNITS"); - if (d->model_number & ESCP_EXT_MARGINS) - cupsFilePuts(fp, " $ESCP_EXT_MARGINS"); - if (d->model_number & ESCP_USB) - cupsFilePuts(fp, " $ESCP_USB"); - if (d->model_number & ESCP_PAGE_SIZE) - cupsFilePuts(fp, " $ESCP_PAGE_SIZE"); - if (d->model_number & ESCP_RASTER_ESCI) - cupsFilePuts(fp, " $ESCP_RASTER_ESCI"); - if (d->model_number & ESCP_REMOTE) - cupsFilePuts(fp, " $ESCP_REMOTE"); - - cupsFilePuts(fp, ")\n"); - break; - - case PPDC_DRIVER_PCL : - cupsFilePuts(fp, " ModelNumber ("); - - if (d->model_number & PCL_PAPER_SIZE) - cupsFilePuts(fp, " $PCL_PAPER_SIZE"); - if (d->model_number & PCL_INKJET) - cupsFilePuts(fp, " $PCL_INKJET"); - if (d->model_number & PCL_RASTER_END_COLOR) - cupsFilePuts(fp, " $PCL_RASTER_END_COLOR"); - if (d->model_number & PCL_RASTER_CID) - cupsFilePuts(fp, " $PCL_RASTER_CID"); - if (d->model_number & PCL_RASTER_CRD) - cupsFilePuts(fp, " $PCL_RASTER_CRD"); - if (d->model_number & PCL_RASTER_SIMPLE) - cupsFilePuts(fp, " $PCL_RASTER_SIMPLE"); - if (d->model_number & PCL_RASTER_RGB24) - cupsFilePuts(fp, " $PCL_RASTER_RGB24"); - if (d->model_number & PCL_PJL) - cupsFilePuts(fp, " $PCL_PJL"); - if (d->model_number & PCL_PJL_PAPERWIDTH) - cupsFilePuts(fp, " $PCL_PJL_PAPERWIDTH"); - if (d->model_number & PCL_PJL_HPGL2) - cupsFilePuts(fp, " $PCL_PJL_HPGL2"); - if (d->model_number & PCL_PJL_PCL3GUI) - cupsFilePuts(fp, " $PCL_PJL_PCL3GUI"); - if (d->model_number & PCL_PJL_RESOLUTION) - cupsFilePuts(fp, " $PCL_PJL_RESOLUTION"); - - cupsFilePuts(fp, ")\n"); - break; - case PPDC_DRIVER_LABEL : cupsFilePuts(fp, " ModelNumber "); diff --git a/ppdc/sample.drv b/ppdc/sample.drv index 9410cd787..1af2a6847 100644 --- a/ppdc/sample.drv +++ b/ppdc/sample.drv @@ -112,7 +112,7 @@ #media "w576h468/8.00x6.50\"" 576 468 // Common stuff for all drivers... -Attribute "cupsVersion" "" "1.5" +Attribute "cupsVersion" "" "1.6" Attribute "FileSystem" "" "False" Attribute "LandscapeOrientation" "" "Plus90" Attribute "TTRasterizer" "" "Type42" diff --git a/scheduler/client.c b/scheduler/client.c index 162822b00..9ee65ab74 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -3179,9 +3179,10 @@ encrypt_client(cupsd_client_t *con) /* I - Client to encrypt */ return (1); # elif defined(HAVE_GNUTLS) - int error; /* Error code */ + int status; /* Error code */ gnutls_certificate_server_credentials *credentials; /* TLS credentials */ + const char *priority; /* Priority string */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "encrypt_client(con=%p(%d))", con, @@ -3222,18 +3223,14 @@ encrypt_client(cupsd_client_t *con) /* I - Client to encrypt */ gnutls_init(&con->http.tls, GNUTLS_SERVER); gnutls_set_default_priority(con->http.tls); - gnutls_credentials_set(con->http.tls, GNUTLS_CRD_CERTIFICATE, *credentials); - gnutls_transport_set_ptr(con->http.tls, (gnutls_transport_ptr)HTTP(con)); - gnutls_transport_set_pull_function(con->http.tls, _httpReadGNUTLS); - gnutls_transport_set_push_function(con->http.tls, _httpWriteGNUTLS); - - error = gnutls_handshake(con->http.tls); - - if (error != GNUTLS_E_SUCCESS) + status = gnutls_priority_set_direct(con->http.tls, + "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:" + "+VERS-SSL3.0:%COMPAT", &priority); + if (status != GNUTLS_E_SUCCESS) { cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to encrypt connection from %s - %s", - con->http.hostname, gnutls_strerror(error)); + "Unable to encrypt connection from %s - %s (%s)", + con->http.hostname, gnutls_strerror(status), priority); gnutls_deinit(con->http.tls); gnutls_certificate_free_credentials(*credentials); @@ -3242,6 +3239,27 @@ encrypt_client(cupsd_client_t *con) /* I - Client to encrypt */ return (0); } + gnutls_credentials_set(con->http.tls, GNUTLS_CRD_CERTIFICATE, *credentials); + gnutls_transport_set_ptr(con->http.tls, (gnutls_transport_ptr)HTTP(con)); + gnutls_transport_set_pull_function(con->http.tls, _httpReadGNUTLS); + gnutls_transport_set_push_function(con->http.tls, _httpWriteGNUTLS); + + while ((status = gnutls_handshake(con->http.tls)) != GNUTLS_E_SUCCESS) + { + if (gnutls_error_is_fatal(status)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to encrypt connection from %s - %s", + con->http.hostname, gnutls_strerror(status)); + + gnutls_deinit(con->http.tls); + gnutls_certificate_free_credentials(*credentials); + con->http.tls = NULL; + free(credentials); + return (0); + } + } + cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.", con->http.hostname); @@ -3282,9 +3300,6 @@ encrypt_client(cupsd_client_t *con) /* I - Client to encrypt */ if (!error) error = SSLSetIOFuncs(con->http.tls, _httpReadCDSA, _httpWriteCDSA); - if (!error) - error = SSLSetProtocolVersionEnabled(con->http.tls, kSSLProtocol2, false); - if (!error) error = SSLSetConnection(con->http.tls, HTTP(con)); diff --git a/scheduler/conf.c b/scheduler/conf.c index f83d3de26..2d30822b9 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -496,7 +496,7 @@ cupsdReadConfiguration(void) cupsdSetString(&DataDir, CUPS_DATADIR); cupsdSetString(&DocumentRoot, CUPS_DOCROOT); cupsdSetString(&AccessLog, CUPS_LOGDIR "/access_log"); - cupsdSetString(&ErrorLog, CUPS_LOGDIR "/error_log"); + cupsdClearString(&ErrorLog); cupsdSetString(&PageLog, CUPS_LOGDIR "/page_log"); cupsdSetString(&PageLogFormat, "%p %u %j %T %P %C %{job-billing} " @@ -718,6 +718,9 @@ cupsdReadConfiguration(void) if (!status) return (0); + if (!ErrorLog) + cupsdSetString(&ErrorLog, CUPS_LOGDIR "/error_log"); + RunUser = getuid(); cupsdLogMessage(CUPSD_LOG_INFO, "Remote access is %s.", diff --git a/scheduler/cups-driverd.cxx b/scheduler/cups-driverd.cxx index b4a3035a8..c8865dbde 100644 --- a/scheduler/cups-driverd.cxx +++ b/scheduler/cups-driverd.cxx @@ -1411,9 +1411,7 @@ load_drv(const char *filename, /* I - Actual filename */ * Add a dummy entry for the file... */ - httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "drv", "", "", 0, - "/%s", name); - add_ppd(name, uri, "", "", "", "", "", "", mtime, size, 0, + add_ppd(name, name, "", "", "", "", "", "", mtime, size, 0, PPD_TYPE_DRV, "drv"); ChangedPPD = 1; diff --git a/scheduler/cups-exec.c b/scheduler/cups-exec.c index 0081fb4c2..f6c5d66b3 100644 --- a/scheduler/cups-exec.c +++ b/scheduler/cups-exec.c @@ -27,8 +27,10 @@ #include #include #ifdef HAVE_SANDBOX_H -# define __APPLE_API_PRIVATE # include +# ifndef SANDBOX_NAMED_EXTERNAL +# define SANDBOX_NAMED_EXTERNAL 0x0003 +# endif /* !SANDBOX_NAMED_EXTERNAL */ #endif /* HAVE_SANDBOX_H */ diff --git a/scheduler/cupsd.order b/scheduler/cupsd.order deleted file mode 100644 index e69de29bb..000000000 diff --git a/scheduler/job.c b/scheduler/job.c index 08e2f0200..fdd09f0a0 100644 --- a/scheduler/job.c +++ b/scheduler/job.c @@ -2910,7 +2910,6 @@ finalize_job(cupsd_job_t *job, /* I - Job */ int exit_code; /* Exit code from backend */ - /* * Convert the status to an exit code. Due to the way the W* macros are * implemented on MacOS X (bug?), we have to store the exit status in a @@ -3163,7 +3162,9 @@ finalize_job(cupsd_job_t *job, /* I - Job */ if (job->history) { - if (job->status) + if (job->status && + (job->state_value == IPP_JOB_ABORTED || + job->state_value == IPP_JOB_STOPPED)) dump_job_history(job); else free_job_history(job); diff --git a/scheduler/log.c b/scheduler/log.c index de7b5458f..c5dff9754 100644 --- a/scheduler/log.c +++ b/scheduler/log.c @@ -516,15 +516,12 @@ cupsdLogMessage(int level, /* I - Log level */ * See if we want to log this message... */ - if (TestConfigFile) + if (TestConfigFile || (level <= LogLevel && !ErrorLog)) { - if (level <= CUPSD_LOG_WARN) - { - va_start(ap, message); - vfprintf(stderr, message, ap); - putc('\n', stderr); - va_end(ap); - } + va_start(ap, message); + vfprintf(stderr, message, ap); + putc('\n', stderr); + va_end(ap); return (1); } diff --git a/scripting/perl/CUPS.pm b/scripting/perl/CUPS.pm deleted file mode 100644 index 5f2ed5f14..000000000 --- a/scripting/perl/CUPS.pm +++ /dev/null @@ -1,144 +0,0 @@ -package CUPS; - -use 5.006; -use strict; -use warnings; -use Carp; - -require Exporter; -require DynaLoader; -use AutoLoader; - -our @ISA = qw(Exporter DynaLoader); - -# Items to export into callers namespace by default. Note: do not export -# names by default without a very good reason. Use EXPORT_OK instead. -# Do not simply export all your public functions/methods/constants. - -# This allows declaration use CUPS ':all'; -# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK -# will save memory. -our %EXPORT_TAGS = ( 'all' => [ qw( - CUPS_DATE_ANY - CUPS_VERSION - HTTP_MAX_BUFFER - HTTP_MAX_HOST - HTTP_MAX_URI - HTTP_MAX_VALUE - IPP_MAX_NAME - IPP_MAX_VALUES - IPP_PORT - PPD_MAX_LINE - PPD_MAX_NAME - PPD_MAX_TEXT - PPD_VERSION -) ] ); - -our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); - -our @EXPORT = qw( - CUPS_DATE_ANY - CUPS_VERSION - HTTP_MAX_BUFFER - HTTP_MAX_HOST - HTTP_MAX_URI - HTTP_MAX_VALUE - IPP_MAX_NAME - IPP_MAX_VALUES - IPP_PORT - PPD_MAX_LINE - PPD_MAX_NAME - PPD_MAX_TEXT - PPD_VERSION -); -our $VERSION = '1.2'; - -sub AUTOLOAD { - # This AUTOLOAD is used to 'autoload' constants from the constant() - # XS function. If a constant is not found then control is passed - # to the AUTOLOAD in AutoLoader. - - my $constname; - our $AUTOLOAD; - ($constname = $AUTOLOAD) =~ s/.*:://; - croak "& not defined" if $constname eq 'constant'; - my $val = constant($constname, @_ ? $_[0] : 0); - if ($! != 0) { - if ($! =~ /Invalid/ || $!{EINVAL}) { - $AutoLoader::AUTOLOAD = $AUTOLOAD; - goto &AutoLoader::AUTOLOAD; - } - else { - croak "Your vendor has not defined CUPS macro $constname"; - } - } - { - no strict 'refs'; - # Fixed between 5.005_53 and 5.005_61 - if ($] >= 5.00561) { - *$AUTOLOAD = sub () { $val }; - } - else { - *$AUTOLOAD = sub { $val }; - } - } - goto &$AUTOLOAD; -} - -bootstrap CUPS $VERSION; - -# Preloaded methods go here. - -# Autoload methods go after =cut, and are processed by the autosplit program. - -1; -__END__ -# Below is stub documentation for your module. You better edit it! - -=head1 NAME - -CUPS - Perl extension for blah blah blah - -=head1 SYNOPSIS - - use CUPS; - blah blah blah - -=head1 DESCRIPTION - -Stub documentation for CUPS, created by h2xs. It looks like the -author of the extension was negligent enough to leave the stub -unedited. - -Blah blah blah. - -=head2 EXPORT - -None by default. - -=head2 Exportable constants - - CUPS_DATE_ANY - CUPS_VERSION - HTTP_MAX_BUFFER - HTTP_MAX_HOST - HTTP_MAX_URI - HTTP_MAX_VALUE - IPP_MAX_NAME - IPP_MAX_VALUES - IPP_PORT - PPD_MAX_LINE - PPD_MAX_NAME - PPD_MAX_TEXT - PPD_VERSION - - -=head1 AUTHOR - -A. U. Thor, Ea.u.thor@a.galaxy.far.far.awayE - -=head1 SEE ALSO - -L. - -=cut diff --git a/scripting/perl/CUPS.xs b/scripting/perl/CUPS.xs deleted file mode 100644 index efaf6dc7a..000000000 --- a/scripting/perl/CUPS.xs +++ /dev/null @@ -1,270 +0,0 @@ -#include "EXTERN.h" -#include "perl.h" -#include "XSUB.h" - -#include -#include -#include -#include -#include - -static int -not_here(char *s) -{ - croak("%s not implemented on this architecture", s); - return -1; -} - -static double -constant_PPD_M(char *name, int len, int arg) -{ - if (5 + 3 >= len ) { - errno = EINVAL; - return 0; - } - switch (name[5 + 3]) { - case 'L': - if (strEQ(name + 5, "AX_LINE")) { /* PPD_M removed */ -#ifdef PPD_MAX_LINE - return PPD_MAX_LINE; -#else - goto not_there; -#endif - } - case 'N': - if (strEQ(name + 5, "AX_NAME")) { /* PPD_M removed */ -#ifdef PPD_MAX_NAME - return PPD_MAX_NAME; -#else - goto not_there; -#endif - } - case 'T': - if (strEQ(name + 5, "AX_TEXT")) { /* PPD_M removed */ -#ifdef PPD_MAX_TEXT - return PPD_MAX_TEXT; -#else - goto not_there; -#endif - } - } - errno = EINVAL; - return 0; - -not_there: - errno = ENOENT; - return 0; -} - -static double -constant_P(char *name, int len, int arg) -{ - if (1 + 3 >= len ) { - errno = EINVAL; - return 0; - } - switch (name[1 + 3]) { - case 'M': - if (!strnEQ(name + 1,"PD_", 3)) - break; - return constant_PPD_M(name, len, arg); - case 'V': - if (strEQ(name + 1, "PD_VERSION")) { /* P removed */ -#ifdef PPD_VERSION - return PPD_VERSION; -#else - goto not_there; -#endif - } - } - errno = EINVAL; - return 0; - -not_there: - errno = ENOENT; - return 0; -} - -static double -constant_H(char *name, int len, int arg) -{ - if (1 + 8 >= len ) { - errno = EINVAL; - return 0; - } - switch (name[1 + 8]) { - case 'B': - if (strEQ(name + 1, "TTP_MAX_BUFFER")) { /* H removed */ -#ifdef HTTP_MAX_BUFFER - return HTTP_MAX_BUFFER; -#else - goto not_there; -#endif - } - case 'H': - if (strEQ(name + 1, "TTP_MAX_HOST")) { /* H removed */ -#ifdef HTTP_MAX_HOST - return HTTP_MAX_HOST; -#else - goto not_there; -#endif - } - case 'U': - if (strEQ(name + 1, "TTP_MAX_URI")) { /* H removed */ -#ifdef HTTP_MAX_URI - return HTTP_MAX_URI; -#else - goto not_there; -#endif - } - case 'V': - if (strEQ(name + 1, "TTP_MAX_VALUE")) { /* H removed */ -#ifdef HTTP_MAX_VALUE - return HTTP_MAX_VALUE; -#else - goto not_there; -#endif - } - } - errno = EINVAL; - return 0; - -not_there: - errno = ENOENT; - return 0; -} - -static double -constant_IPP_M(char *name, int len, int arg) -{ - if (5 + 3 >= len ) { - errno = EINVAL; - return 0; - } - switch (name[5 + 3]) { - case 'N': - if (strEQ(name + 5, "AX_NAME")) { /* IPP_M removed */ -#ifdef IPP_MAX_NAME - return IPP_MAX_NAME; -#else - goto not_there; -#endif - } - case 'V': - if (strEQ(name + 5, "AX_VALUES")) { /* IPP_M removed */ -#ifdef IPP_MAX_VALUES - return IPP_MAX_VALUES; -#else - goto not_there; -#endif - } - } - errno = EINVAL; - return 0; - -not_there: - errno = ENOENT; - return 0; -} - -static double -constant_I(char *name, int len, int arg) -{ - if (1 + 3 >= len ) { - errno = EINVAL; - return 0; - } - switch (name[1 + 3]) { - case 'M': - if (!strnEQ(name + 1,"PP_", 3)) - break; - return constant_IPP_M(name, len, arg); - case 'P': - if (strEQ(name + 1, "PP_PORT")) { /* I removed */ -#ifdef IPP_PORT - return IPP_PORT; -#else - goto not_there; -#endif - } - } - errno = EINVAL; - return 0; - -not_there: - errno = ENOENT; - return 0; -} - -static double -constant_C(char *name, int len, int arg) -{ - if (1 + 4 >= len ) { - errno = EINVAL; - return 0; - } - switch (name[1 + 4]) { - case 'D': - if (strEQ(name + 1, "UPS_DATE_ANY")) { /* C removed */ -#ifdef CUPS_DATE_ANY - return CUPS_DATE_ANY; -#else - goto not_there; -#endif - } - case 'V': - if (strEQ(name + 1, "UPS_VERSION")) { /* C removed */ -#ifdef CUPS_VERSION - return CUPS_VERSION; -#else - goto not_there; -#endif - } - } - errno = EINVAL; - return 0; - -not_there: - errno = ENOENT; - return 0; -} - -static double -constant(char *name, int len, int arg) -{ - errno = 0; - switch (name[0 + 0]) { - case 'C': - return constant_C(name, len, arg); - case 'H': - return constant_H(name, len, arg); - case 'I': - return constant_I(name, len, arg); - case 'P': - return constant_P(name, len, arg); - } - errno = EINVAL; - return 0; - -not_there: - errno = ENOENT; - return 0; -} - - -MODULE = CUPS PACKAGE = CUPS - - -double -constant(sv,arg) - PREINIT: - STRLEN len; - INPUT: - SV * sv - char * s = SvPV(sv, len); - int arg - CODE: - RETVAL = constant(s,len,arg); - OUTPUT: - RETVAL - diff --git a/scripting/perl/Makefile.PL b/scripting/perl/Makefile.PL deleted file mode 100644 index f5e4bdd27..000000000 --- a/scripting/perl/Makefile.PL +++ /dev/null @@ -1,17 +0,0 @@ -use ExtUtils::MakeMaker; -# See lib/ExtUtils/MakeMaker.pm for details of how to influence -# the contents of the Makefile that is written. -WriteMakefile( - 'NAME' => 'CUPS', - 'VERSION_FROM' => 'CUPS.pm', # finds $VERSION - 'PREREQ_PM' => {}, # e.g., Module::Name => 1.1 - ($] >= 5.005 ? ## Add these new keywords supported since 5.005 - (ABSTRACT_FROM => 'CUPS.pm', # retrieve abstract from module - AUTHOR => 'A. U. Thor ') : ()), - 'LIBS' => ['-lcups '], # e.g., '-lm' - 'DEFINE' => '', # e.g., '-DHAVE_SOMETHING' - # Insert -I. if you add *.h files later: - 'INC' => '', # e.g., '-I/usr/include/other' - # Un-comment this if you add C files to link with later: - # 'OBJECT' => '$(O_FILES)', # link all the C files too -); diff --git a/scripting/perl/README b/scripting/perl/README deleted file mode 100644 index 1605c7798..000000000 --- a/scripting/perl/README +++ /dev/null @@ -1,35 +0,0 @@ -CUPS version 1.2 -================ - -The README is used to introduce the module and provide instructions on -how to install the module, any machine dependencies it may have (for -example C compilers and installed libraries) and any other information -that should be provided before the module is installed. - -A README file is required for CPAN modules since CPAN extracts the -README file from a module distribution so that people browsing the -archive can use it get an idea of the modules uses. It is usually a -good idea to provide version information here so that people can -decide whether fixes for the module are worth downloading. - -INSTALLATION - -To install this module type the following: - - perl Makefile.PL - make - make test - make install - -DEPENDENCIES - -This module requires these other modules and libraries: - - blah blah blah - -COPYRIGHT AND LICENCE - -Put the correct copyright and licence information here. - -Copyright (C) 2002 A. U. Thor blah blah blah - diff --git a/scripting/perl/test.pl b/scripting/perl/test.pl deleted file mode 100644 index acf31916b..000000000 --- a/scripting/perl/test.pl +++ /dev/null @@ -1,17 +0,0 @@ -# Before `make install' is performed this script should be runnable with -# `make test'. After `make install' it should work as `perl test.pl' - -######################### - -# change 'tests => 1' to 'tests => last_test_to_print'; - -use Test; -BEGIN { plan tests => 1 }; -use CUPS; -ok(1); # If we made it this far, we're ok. - -######################### - -# Insert your test code below, the Test module is use()ed here so read -# its man page ( perldoc Test ) for help writing this test script. - diff --git a/scripting/php/Dependencies b/scripting/php/Dependencies deleted file mode 100644 index d3c60c70f..000000000 --- a/scripting/php/Dependencies +++ /dev/null @@ -1,7 +0,0 @@ -# DO NOT DELETE THIS LINE -- make depend depends on it. - -phpcups.o: ../../cups/string-private.h ../../config.h phpcups.h -phpcups.o: ../../cups/cups.h ../../cups/file.h ../../cups/versioning.h -phpcups.o: ../../cups/ipp.h ../../cups/http.h ../../cups/array.h -phpcups.o: ../../cups/language.h ../../cups/language.h -phpcups.o: ../../cups/debug-private.h diff --git a/scripting/php/Makefile b/scripting/php/Makefile deleted file mode 100644 index a10f4f49c..000000000 --- a/scripting/php/Makefile +++ /dev/null @@ -1,153 +0,0 @@ -# -# "$Id: Makefile 3572 2003-04-08 19:56:25Z mike $" -# -# PHP Makefile for CUPS. -# -# Copyright 2007-2011 by Apple Inc. -# Copyright 1997-2007 by Easy Software Products, all rights reserved. -# -# These coded instructions, statements, and computer programs are the -# property of Apple Inc. and are protected by Federal copyright -# law. Distribution and use rights are outlined in the file "LICENSE.txt" -# which should have been included with this file. If this file is -# file is missing or damaged, see the license at "http://www.cups.org/". -# - -include ../../Makedefs - - -# -# Where to install and how to compile the PHP module... -# - -PHPDIR = $(BUILDROOT)`$(PHPCONFIG) --extension-dir` -OPTIONS = $(PHPOPTIONS) - - -# -# Object files... -# - -OBJS = phpcups.o - - -# -# Targets in this directory... -# - -PHPCUPS = phpcups.so - - -# -# Make all targets... -# - -all: $(PHPCUPS) - - -# -# Make library targets... -# - -libs: - - -# -# Make unit tests... -# - -unittests: - - -# -# Remove object and target files... -# - -clean: - $(RM) $(OBJS) $(PHPCUPS) - - -# -# Update dependencies (without system header dependencies...) -# - -depend: - makedepend -Y -I../.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1 - - -# -# Install all targets... -# - -install: all install-data install-headers install-libs install-exec - - -# -# Install data files... -# - -install-data: - - -# -# Install programs... -# - -install-exec: - echo Installing $(PHPCUPS) in $(PHPDIR) - $(INSTALL_DIR) $(PHPDIR) - $(INSTALL_LIB) $(PHPCUPS) $(PHPDIR) - if test "x$(SYMROOT)" != x; then \ - $(INSTALL_DIR) $(SYMROOT); \ - cp $(PHPCUPS) $(SYMROOT); \ - fi - - -# -# Install headers... -# - -install-headers: - - -# -# Install libraries... -# - -install-libs: - - -# -# Uninstall object and target files... -# - -uninstall: - $(RM) $(PHPDIR)/$(PHPCUPS) - -$(RMDIR) $(PHPDIR) - - -# -# phpcups.so -# - -phpcups.so: $(OBJS) ../../Makedefs - echo Linking $@... - if test `uname` = Darwin; then \ - DSOFLAGS="-bundle -flat_namespace -undefined suppress $(RC_CFLAGS)"; \ - else \ - DSOFLAGS="$(DSOFLAGS)"; \ - fi; \ - echo $(DSO) $$DSOFLAGS $(ARCHFLAGS) -o $@ $(OBJS) -L../../cups $(LIBS); \ - $(DSO) $$DSOFLAGS $(ARCHFLAGS) -o $@ $(OBJS) -L../../cups $(LIBS) - - -# -# Dependencies... -# - -include Dependencies - - -# -# End of "$Id: Makefile 3572 2003-04-08 19:56:25Z mike $". -# diff --git a/scripting/php/README b/scripting/php/README deleted file mode 100644 index e4ab27d84..000000000 --- a/scripting/php/README +++ /dev/null @@ -1,157 +0,0 @@ -README - 02/25/2006 -------------------- - -INTRODUCTION - - This directory contains a dynamically loadable CUPS extension - module for PHP 4 and 5. The CUPS 1.2 module has been - substantially updated to provide an API more consistent with - the C API and is NOT compatible with the CUPS 1.1 module. - - -COMPILING AND INSTALLING - - Run "make" to compile the PHP CUPS extension: - - make - - To install it, type: - - make install - - -RESOURCES AND SUPPORT - - Questions should be reported to the CUPS newsgroups/mailing - lists at: - - http://www.cups.org/newsgroups.php - - Bug reports and enhancement requests can be submitted via the - form at: - - http://www.cups.org/str.php - - -QUICK REFERENCE DOCUMENTATION - - In lieu of actual documentation, the following definitions - can be used as a quick reference to the supported functions: - - - CUPS_CANCEL_JOB - - Cancels a job on the named destination: - - bool cups_cancel_job(string dest, int id) - - The return value is TRUE on success and FALSE on failure. - - Example: - - if (!cups_cancel_job("myprinter", 123)) - print("Unable to cancel job: " . cups_last_error_string() . "\n"); - - - CUPS_GET_DESTS - - Gets a list of available destinations: - - array cups_get_dests() - - The return value is an array of objects with the following - properties: - - name The name of the printer or class - instance The instance of the printer or class - is_default TRUE if the printer or class is the default destination - options Associative array of options and their values - - Example: - - $dest = cups_get_dests(); - - - CUPS_GET_JOBS - - Gets a list of jobs: - - array cups_get_jobs(string dest, bool myjobs, int completed) - - The "dest" string can be blank for jobs on all destinations. - Pass TRUE for "myjobs" to only get jobs for the current user. - The "completed" argument can be 0 for pending jobs, 1 for - completed jobs, and -1 for all jobs. - - The return value is an array of objects with the following - properties: - - id The job ID - dest Printer or class name - title Title/job name - user User the submitted the job - format Document format - state Job state - size Size in kilobytes - priority Priority (1-100) - completed_time Time the job was completed - creation_time Time the job was created - processing_time Time the job was processed - - Example: - - $jobs = cups_get_jobs("", FALSE, -1); - - - CUPS_LAST_ERROR - - Returns the IPP status code for the most recent request: - - int cups_last_error() - - Example: - - $error = cups_last_error(); - - - CUPS_LAST_ERROR_STRING - - Returns the IPP status-message string for the most recent request: - - string cups_last_error_string() - - Example: - - $message = cups_last_error_string(); - - - CUPS_PRINT_FILE - - Prints a single file to a printer or class: - - int cups_print_file(string dest, string filename, string title, - array options) - - The return value is the job ID or 0 if there was an error. - - Example: - - $options = array("name" => "value", "name2" => "value2"); - $id = cups_print_file("dest", "filename", "title", $options); - - - CUPS_PRINT_FILES - - Prints one or more files to a printer or class: - - int cups_print_files(string dest, array files, string title, - array options); - - The return value is the job ID or 0 if there was an error. - - Example: - - $files = array("file1", "file2", "file3"); - $options = array("name" => "value", "name2" => "value2"); - $id = cups_print_file("dest", $files, "title", $options); - diff --git a/scripting/php/phpcups.c b/scripting/php/phpcups.c deleted file mode 100644 index e1fb4d4c9..000000000 --- a/scripting/php/phpcups.c +++ /dev/null @@ -1,487 +0,0 @@ -/* - * "$Id: phpcups.c 7624 2008-06-09 15:55:04Z mike $" - * - * Printing utilities for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * cups_convert_options() - Convert a PHP options array to a CUPS options array. - * zm_startup_phpcups() - Initialize the CUPS module. - * zif_cups_cancel_job() - Cancel a job. - * zif_cups_get_dests() - Get a list of printers and classes. - * zif_cups_get_jobs() - Get a list of jobs. - * zif_cups_last_error() - Return the last IPP status code. - * zif_cups_last_error_string() - Return the last IPP status - * zif_cups_print_file() - Print a single file. - * zif_cups_print_files() - Print multiple files. - */ - -/* - * Include necessary headers... - */ - -#include -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "phpcups.h" - - -/* - * PHP function list... - */ - -function_entry phpcups_functions[] = -{ - PHP_FE(cups_cancel_job, NULL) - PHP_FE(cups_get_dests, NULL) - PHP_FE(cups_get_jobs, NULL) - PHP_FE(cups_last_error, NULL) - PHP_FE(cups_last_error_string, NULL) - PHP_FE(cups_print_file, NULL) - PHP_FE(cups_print_files, NULL) - {NULL, NULL, NULL} -}; - - -/* - * PHP module info... - */ - -zend_module_entry phpcups_module_entry = -{ - STANDARD_MODULE_HEADER, - "phpcups", - phpcups_functions, - PHP_MINIT(phpcups), - NULL, - NULL, - NULL, - NULL, - CUPS_SVERSION, - STANDARD_MODULE_PROPERTIES -}; - - -ZEND_GET_MODULE(phpcups) - - -/* - * 'cups_convert_options()' - Convert a PHP options array to a CUPS options array. - */ - -static int /* O - Number of options */ -cups_convert_options( - zval *optionsobj, /* I - Options array object */ - cups_option_t **options) /* O - Options */ -{ - int num_options; /* Number of options */ - HashTable *ht; /* Option array hash table */ - Bucket *current; /* Current element in array */ - zval *value; /* Current value in array */ - char temp[255]; /* String value for numbers */ - - - ht = Z_ARRVAL_P(optionsobj); - num_options = 0; - - for (current = ht->pListHead; current; current = current->pListNext) - { - value = (zval *)current->pDataPtr; - - switch (Z_TYPE_P(value)) - { - case IS_LONG : - sprintf(temp, "%ld", Z_LVAL_P(value)); - num_options = cupsAddOption(current->arKey, temp, num_options, - options); - break; - - case IS_DOUBLE : - sprintf(temp, "%g", Z_DVAL_P(value)); - num_options = cupsAddOption(current->arKey, temp, num_options, - options); - break; - - case IS_BOOL : - num_options = cupsAddOption(current->arKey, - Z_BVAL_P(value) ? "true" : "false", - num_options, options); - break; - - case IS_STRING : - num_options = cupsAddOption(current->arKey, Z_STRVAL_P(value), - num_options, options); - break; - } - } - - return (num_options); -} - - -/* - * 'zm_startup_phpcups()' - Initialize the CUPS module. - */ - -PHP_MINIT_FUNCTION(phpcups) -{ - REGISTER_LONG_CONSTANT("CUPS_PRINTER_LOCAL", CUPS_PRINTER_LOCAL, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_CLASS", CUPS_PRINTER_CLASS, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_REMOTE", CUPS_PRINTER_REMOTE, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_BW", CUPS_PRINTER_BW, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_COLOR", CUPS_PRINTER_COLOR, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_DUPLEX", CUPS_PRINTER_DUPLEX, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_STAPLE", CUPS_PRINTER_STAPLE, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_COPIES", CUPS_PRINTER_COPIES, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_COLLATE", CUPS_PRINTER_COLLATE, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_PUNCH", CUPS_PRINTER_PUNCH, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_COVER", CUPS_PRINTER_COVER, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_BIND", CUPS_PRINTER_BIND, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_SORT", CUPS_PRINTER_SORT, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_SMALL", CUPS_PRINTER_SMALL, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_MEDIUM", CUPS_PRINTER_MEDIUM, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_LARGE", CUPS_PRINTER_LARGE, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_VARIABLE", CUPS_PRINTER_VARIABLE, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_IMPLICIT", CUPS_PRINTER_IMPLICIT, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_DEFAULT", CUPS_PRINTER_DEFAULT, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_FAX", CUPS_PRINTER_FAX, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_REJECTING", CUPS_PRINTER_REJECTING, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_DELETE", CUPS_PRINTER_DELETE, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_NOT_SHARED", CUPS_PRINTER_NOT_SHARED, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_AUTHENTICATED", CUPS_PRINTER_AUTHENTICATED, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_COMMANDS", CUPS_PRINTER_COMMANDS, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_DISCOVERED", CUPS_PRINTER_DISCOVERED, CONST_CS); - REGISTER_LONG_CONSTANT("CUPS_PRINTER_OPTIONS", CUPS_PRINTER_OPTIONS, CONST_CS); - - REGISTER_LONG_CONSTANT("IPP_OK", IPP_OK, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_OK_SUBST", IPP_OK_SUBST, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_OK_CONFLICT", IPP_OK_CONFLICT, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_OK_IGNORED_SUBSCRIPTIONS", IPP_OK_IGNORED_SUBSCRIPTIONS, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_OK_IGNORED_NOTIFICATIONS", IPP_OK_IGNORED_NOTIFICATIONS, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_OK_TOO_MANY_EVENTS", IPP_OK_TOO_MANY_EVENTS, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_OK_BUT_CANCEL_SUBSCRIPTION", IPP_OK_BUT_CANCEL_SUBSCRIPTION, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_OK_EVENTS_COMPLETE", IPP_OK_EVENTS_COMPLETE, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_REDIRECTION_OTHER_SITE", IPP_REDIRECTION_OTHER_SITE, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_BAD_REQUEST", IPP_BAD_REQUEST, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_FORBIDDEN", IPP_FORBIDDEN, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_NOT_AUTHENTICATED", IPP_NOT_AUTHENTICATED, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_NOT_AUTHORIZED", IPP_NOT_AUTHORIZED, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_NOT_POSSIBLE", IPP_NOT_POSSIBLE, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_TIMEOUT", IPP_TIMEOUT, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_NOT_FOUND", IPP_NOT_FOUND, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_GONE", IPP_GONE, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_REQUEST_ENTITY", IPP_REQUEST_ENTITY, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_REQUEST_VALUE", IPP_REQUEST_VALUE, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_DOCUMENT_FORMAT", IPP_DOCUMENT_FORMAT, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_ATTRIBUTES", IPP_ATTRIBUTES, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_URI_SCHEME", IPP_URI_SCHEME, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_CHARSET", IPP_CHARSET, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_CONFLICT", IPP_CONFLICT, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_COMPRESSION_NOT_SUPPORTED", IPP_COMPRESSION_NOT_SUPPORTED, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_COMPRESSION_ERROR", IPP_COMPRESSION_ERROR, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_DOCUMENT_FORMAT_ERROR", IPP_DOCUMENT_FORMAT_ERROR, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_DOCUMENT_ACCESS_ERROR", IPP_DOCUMENT_ACCESS_ERROR, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_ATTRIBUTES_NOT_SETTABLE", IPP_ATTRIBUTES_NOT_SETTABLE, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_IGNORED_ALL_SUBSCRIPTIONS", IPP_IGNORED_ALL_SUBSCRIPTIONS, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_TOO_MANY_SUBSCRIPTIONS", IPP_TOO_MANY_SUBSCRIPTIONS, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_IGNORED_ALL_NOTIFICATIONS", IPP_IGNORED_ALL_NOTIFICATIONS, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_PRINT_SUPPORT_FILE_NOT_FOUND", IPP_PRINT_SUPPORT_FILE_NOT_FOUND, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_INTERNAL_ERROR", IPP_INTERNAL_ERROR, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_OPERATION_NOT_SUPPORTED", IPP_OPERATION_NOT_SUPPORTED, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_SERVICE_UNAVAILABLE", IPP_SERVICE_UNAVAILABLE, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_VERSION_NOT_SUPPORTED", IPP_VERSION_NOT_SUPPORTED, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_DEVICE_ERROR", IPP_DEVICE_ERROR, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_TEMPORARY_ERROR", IPP_TEMPORARY_ERROR, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_NOT_ACCEPTING", IPP_NOT_ACCEPTING, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_PRINTER_BUSY", IPP_PRINTER_BUSY, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_ERROR_JOB_CANCELLED", IPP_ERROR_JOB_CANCELLED, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_MULTIPLE_JOBS_NOT_SUPPORTED", IPP_MULTIPLE_JOBS_NOT_SUPPORTED, CONST_CS); - REGISTER_LONG_CONSTANT("IPP_PRINTER_IS_DEACTIVATED", IPP_PRINTER_IS_DEACTIVATED, CONST_CS); - - return (SUCCESS); -} - -/* - * 'zif_cups_cancel_job()' - Cancel a job. - */ - -PHP_FUNCTION(cups_cancel_job) -{ - char *dest; /* Destination */ - int dest_len, /* Length of destination */ - id; /* Job ID */ - - - if (ZEND_NUM_ARGS() != 2 || - zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &dest, &dest_len, &id)) - { - WRONG_PARAM_COUNT; - } - - RETURN_LONG(cupsCancelJob(dest, id)); -} - - -/* - * 'zif_cups_get_dests()' - Get a list of printers and classes. - */ - -PHP_FUNCTION(cups_get_dests) -{ - int i, j, /* Looping vars */ - num_dests; /* Number of destinations */ - cups_dest_t *dests, /* Destinations */ - *dest; /* Current destination */ - cups_option_t *option; /* Current option */ - zval *destobj, /* Destination object */ - *optionsobj; /* Options object */ - - - if (ZEND_NUM_ARGS() != 0) - { - WRONG_PARAM_COUNT; - } - - if ((num_dests = cupsGetDests(&dests)) <= 0) - { - RETURN_NULL(); - } - - if (array_init(return_value) == SUCCESS) - { - for (i = 0, dest = dests; i < num_dests; i ++, dest ++) - { - MAKE_STD_ZVAL(destobj); - - if (object_init(destobj) == SUCCESS) - { - /* - * Add properties to the destination for each of the cups_dest_t - * members... - */ - - add_property_string(destobj, "name", dest->name, 1); - add_property_string(destobj, "instance", - dest->instance ? dest->instance : "", 1); - add_property_long(destobj, "is_default", dest->is_default); - - /* - * Create an associative array for the options... - */ - - MAKE_STD_ZVAL(optionsobj); - - if (array_init(optionsobj) == SUCCESS) - { - for (j = 0, option = dest->options; - j < dest->num_options; - j ++, option ++) - add_assoc_string(optionsobj, option->name, option->value, 1); - - add_property_zval(destobj, "options", optionsobj); - } - - add_index_zval(return_value, i, destobj); - } - } - } - - cupsFreeDests(num_dests, dests); -} - - -/* - * 'zif_cups_get_jobs()' - Get a list of jobs. - */ - -PHP_FUNCTION(cups_get_jobs) -{ - char *dest; /* Destination */ - int dest_len, /* Length of destination */ - myjobs, /* Only show my jobs? */ - completed; /* Show completed jobs? */ - int i, /* Looping var */ - num_jobs; /* Number of jobs */ - cups_job_t *jobs, /* Jobs */ - *job; /* Current job */ - zval *jobobj; /* Job object */ - - - - - if (ZEND_NUM_ARGS() != 3 || - zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll", &dest, &dest_len, &myjobs, &completed)) - { - WRONG_PARAM_COUNT; - } - - if (!*dest) - dest = NULL; - - if ((num_jobs = cupsGetJobs(&jobs, dest, myjobs, completed)) <= 0) - { - RETURN_NULL(); - } - - if (array_init(return_value) == SUCCESS) - { - for (i = 0, job = jobs; i < num_jobs; i ++, job ++) - { - MAKE_STD_ZVAL(jobobj); - - if (object_init(jobobj) == SUCCESS) - { - /* - * Add properties to the job for each of the cups_job_t - * members... - */ - - add_property_long(jobobj, "id", job->id); - add_property_string(jobobj, "dest", job->dest, 1); - add_property_string(jobobj, "title", job->title, 1); - add_property_string(jobobj, "user", job->user, 1); - add_property_string(jobobj, "format", job->format, 1); - add_property_long(jobobj, "state", job->state); - add_property_long(jobobj, "size", job->size); - add_property_long(jobobj, "priority", job->priority); - add_property_long(jobobj, "completed_time", job->completed_time); - add_property_long(jobobj, "creation_time", job->creation_time); - add_property_long(jobobj, "processing_time", job->processing_time); - - add_index_zval(return_value, i, jobobj); - } - } - } - - cupsFreeJobs(num_jobs, jobs); -} - - -/* - * 'zif_cups_last_error()' - Return the last IPP status code. - */ - -PHP_FUNCTION(cups_last_error) -{ - if (ZEND_NUM_ARGS() != 0) - { - WRONG_PARAM_COUNT; - } - - RETURN_LONG(cupsLastError()); -} - - -/* - * 'zif_cups_last_error_string()' - Return the last IPP status-message. - */ - -PHP_FUNCTION(cups_last_error_string) -{ - if (ZEND_NUM_ARGS() != 0) - { - WRONG_PARAM_COUNT; - } - - RETURN_STRING((char *)cupsLastErrorString(), 1); -} - - -/* - * 'zif_cups_print_file()' - Print a single file. - */ - -PHP_FUNCTION(cups_print_file) -{ - char *dest; /* Destination */ - int dest_len; /* Length of destination */ - char *filename; /* Filename */ - int filename_len; /* Length of filename */ - char *title; /* Title */ - int title_len; /* Length of title */ - zval *optionsobj; /* Array of options */ - int num_options; /* Number of options */ - cups_option_t *options; /* Options */ - int id; /* Job ID */ - - - if (ZEND_NUM_ARGS() != 4 || - zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssa", &dest, &dest_len, - &filename, &filename_len, - &title, &title_len, &optionsobj)) - { - WRONG_PARAM_COUNT; - } - - num_options = cups_convert_options(optionsobj, &options); - - id = cupsPrintFile(dest, filename, title, num_options, options); - - cupsFreeOptions(num_options, options); - - RETURN_LONG(id); -} - - -/* - * 'zif_cups_print_files()' - Print multiple files. - */ - -PHP_FUNCTION(cups_print_files) -{ - char *dest; /* Destination */ - int dest_len; /* Length of destination */ - zval *filesobj; /* Files array */ - int num_files; /* Number of files */ - const char *files[1000]; /* Files */ - char *title; /* Title */ - int title_len; /* Length of title */ - zval *optionsobj; /* Array of options */ - int num_options; /* Number of options */ - cups_option_t *options; /* Options */ - HashTable *ht2; /* Option array hash table */ - Bucket *current; /* Current element in array */ - int id; /* Job ID */ - - - if (ZEND_NUM_ARGS() != 4 || - zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sasa", &dest, &dest_len, &filesobj, - &title, &title_len, &optionsobj)) - { - WRONG_PARAM_COUNT; - } - - ht2 = Z_ARRVAL_P(filesobj); - num_files = 0; - - for (current = ht2->pListHead; current; current = current->pListNext) - { - files[num_files ++] = Z_STRVAL_P(((zval *)current->pDataPtr)); - - if (num_files >= (int)(sizeof(files) / sizeof(files[0]))) - break; - } - - num_options = cups_convert_options(optionsobj, &options); - - id = cupsPrintFiles(dest, num_files, files, title, num_options, options); - - cupsFreeOptions(num_options, options); - - RETURN_LONG(id); -} - - -/* - * End of "$Id: phpcups.c 7624 2008-06-09 15:55:04Z mike $". - */ diff --git a/scripting/php/phpcups.h b/scripting/php/phpcups.h deleted file mode 100644 index e46012dbc..000000000 --- a/scripting/php/phpcups.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * "$Id: phpcups.h 6649 2007-07-11 21:46:42Z mike $" - * - * PHP module include file for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - */ - -#ifndef PHPCUPS_H -# define PHPCUPS_H - -/* - * Include necessary headers... - */ - -# include -# include -# include -# include -# include -# if defined(WIN32) || defined(__EMX__) -# include -# else -# include -# endif /* WIN32 || __EMX__ */ - - -/* - * Zend definitions... - */ - -extern zend_module_entry phpcups_module_entry; -# define phpext_phpcups_ptr &phpcups_module_entry - -# ifdef PHP_WIN32 -# define PHP_PHPCUPS_API __declspec(dllexport) -# else -# define PHP_PHPCUPS_API -# endif - -# ifdef ZTS -# include "TSRM.h" -# endif - -PHP_MINIT_FUNCTION(phpcups); - -PHP_FUNCTION(cups_cancel_job); -PHP_FUNCTION(cups_get_dests); -PHP_FUNCTION(cups_get_jobs); -PHP_FUNCTION(cups_last_error); -PHP_FUNCTION(cups_last_error_string); -PHP_FUNCTION(cups_print_file); -PHP_FUNCTION(cups_print_files); - -#endif /* !PHPCUPS_H */ - - -/* - * End of "$Id: phpcups.h 6649 2007-07-11 21:46:42Z mike $". - */ diff --git a/scripting/php/phpcups.php b/scripting/php/phpcups.php deleted file mode 100755 index 0fe57190e..000000000 --- a/scripting/php/phpcups.php +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/php -f - "100", - "page-label" => "testfile.jpg"))); - -print("cups_print_files(\"test\", array(\"../../test/testfile.jpg\", " - ."\"../../test/testfile.ps\"), \"testfiles\", ...):\n"); -print_r(cups_print_files("test", array("../../test/testfile.jpg", - "../../test/testfile.ps"), - "testfiles", - array("scaling" => "100", - "page-label" => "testfile.jpg"))); - -// -// End of "$Id: phpcups.php 3603 2003-04-11 18:42:52Z mike $". -// -?> diff --git a/systemv/cupstestppd.c b/systemv/cupstestppd.c index 2acc0f25f..3dfa7bf5f 100644 --- a/systemv/cupstestppd.c +++ b/systemv/cupstestppd.c @@ -439,13 +439,29 @@ main(int argc, /* I - Number of command-line args */ attr->value) ppdversion = (int)(10 * _cupsStrScand(attr->value, NULL, loc) + 0.5); - for (j = 0; j < ppd->num_filters; j ++) - if (strstr(ppd->filters[j], "application/vnd.cups-raster")) - { - if (!test_raster(ppd, verbose)) - errors ++; - break; + if ((attr = ppdFindAttr(ppd, "cupsFilter2", NULL)) != NULL) + { + do + { + if (strstr(attr->value, "application/vnd.cups-raster")) + { + if (!test_raster(ppd, verbose)) + errors ++; + break; + } } + while ((attr = ppdFindNextAttr(ppd, "cupsFilter2", NULL)) != NULL); + } + else + { + for (j = 0; j < ppd->num_filters; j ++) + if (strstr(ppd->filters[j], "application/vnd.cups-raster")) + { + if (!test_raster(ppd, verbose)) + errors ++; + break; + } + } /* * Look for default keywords with no matching option... @@ -2309,6 +2325,8 @@ check_filters(ppd_file_t *ppd, /* I - PPD file */ const char *ptr; /* Pointer into string */ char super[16], /* Super-type for filter */ type[256], /* Type for filter */ + dstsuper[16], /* Destination super-type for filter */ + dsttype[256], /* Destination type for filter */ program[1024], /* Program/filter name */ pathprog[1024]; /* Complete path to program/filter */ int cost; /* Cost of filter */ @@ -2322,9 +2340,26 @@ check_filters(ppd_file_t *ppd, /* I - PPD file */ * cupsFilter */ - for (i = 0; i < ppd->num_filters; i ++) + for (attr = ppdFindAttr(ppd, "cupsFilter", NULL); + attr; + attr = ppdFindNextAttr(ppd, "cupsFilter", NULL)) { - if (sscanf(ppd->filters[i], "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type, + if (strcmp(attr->name, "cupsFilter")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s."), + prefix, attr->name, "cupsFilter"); + + if (!warn) + errors ++; + } + + if (!attr->value || + sscanf(attr->value, "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type, &cost, program) != 4) { if (!warn && !errors && !verbose) @@ -2387,6 +2422,102 @@ check_filters(ppd_file_t *ppd, /* I - PPD file */ } } + /* + * cupsFilter2 + */ + + for (attr = ppdFindAttr(ppd, "cupsFilter2", NULL); + attr; + attr = ppdFindNextAttr(ppd, "cupsFilter2", NULL)) + { + if (strcmp(attr->name, "cupsFilter2")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s."), + prefix, attr->name, "cupsFilter2"); + + if (!warn) + errors ++; + } + + if (!attr->value || + sscanf(attr->value, "%15[^/]/%255s%*[ \t]%15[^/]/%255s%d%*[ \t]%1023[^\n]", + super, type, dstsuper, dsttype, &cost, program) != 6) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad cupsFilter2 value \"%s\"."), + prefix, ppd->filters[i]); + + if (!warn) + errors ++; + } + else if (strcmp(program, "-")) + { + if (strncmp(program, "maxsize(", 8) && + (ptr = strchr(program + 8, ')')) != NULL) + { + ptr ++; + while (_cups_isspace(*ptr)) + ptr ++; + + _cups_strcpy(program, ptr); + } + + if (program[0] == '/') + snprintf(pathprog, sizeof(pathprog), "%s%s", root, program); + else + { + if ((ptr = getenv("CUPS_SERVERBIN")) == NULL) + ptr = CUPS_SERVERBIN; + + if (*ptr == '/' || !*root) + snprintf(pathprog, sizeof(pathprog), "%s%s/filter/%s", root, ptr, + program); + else + snprintf(pathprog, sizeof(pathprog), "%s/%s/filter/%s", root, ptr, + program); + } + + if (stat(pathprog, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing %s file \"%s\"."), + prefix, "cupsFilter2", pathprog); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_PROGRAM) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad permissions on %s file \"%s\"."), + prefix, "cupsFilter2", pathprog); + + if (!warn) + errors ++; + } + else + errors = valid_path("cupsFilter2", pathprog, errors, verbose, warn); + } + } + /* * cupsPreFilter */ diff --git a/templates/maintenance.tmpl b/templates/maintenance.tmpl deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/ipptool.c b/test/ipptool.c index 81c663d5a..5fdcd09a7 100644 --- a/test/ipptool.c +++ b/test/ipptool.c @@ -660,7 +660,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ vars->family)) == NULL) { print_fatal_error("Unable to connect to %s on port %d - %s", vars->hostname, - vars->port, strerror(errno)); + vars->port, cupsLastErrorString()); pass = 0; goto test_exit; } @@ -668,7 +668,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ if (httpReconnect(http)) { print_fatal_error("Unable to connect to %s on port %d - %s", vars->hostname, - vars->port, strerror(errno)); + vars->port, cupsLastErrorString()); pass = 0; goto test_exit; } @@ -3251,18 +3251,17 @@ get_variable(_cups_vars_t *vars, /* I - Variables */ static char * /* O - ISO 8601 date/time string */ iso_date(ipp_uchar_t *date) /* I - IPP (RFC 1903) date/time value */ { - unsigned year = (date[0] << 8) + date[1]; - /* Year */ + time_t utctime; /* UTC time since 1970 */ + struct tm *utcdate; /* UTC date/time */ static char buffer[255]; /* String buffer */ - if (date[9] == 0 && date[10] == 0) - snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02uZ", - year, date[2], date[3], date[4], date[5], date[6]); - else - snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u%c%02u%02u", - year, date[2], date[3], date[4], date[5], date[6], - date[8], date[9], date[10]); + utctime = ippDateToTime(date); + utcdate = gmtime(&utctime); + + snprintf(buffer, sizeof(buffer), "%04d-%02d-%02dT%02d:%02d:%02dZ", + utcdate->tm_year + 1900, utcdate->tm_mon + 1, utcdate->tm_mday, + utcdate->tm_hour, utcdate->tm_min, utcdate->tm_sec); return (buffer); } @@ -3823,6 +3822,69 @@ print_xml_string(const char *element, /* I - Element name or NULL */ fputs("<", stdout); else if (*s == '>') fputs(">", stdout); + else if ((*s & 0xe0) == 0xc0) + { + /* + * Validate UTF-8 two-byte sequence... + */ + + if ((s[1] & 0xc0) != 0x80) + { + putchar('?'); + s ++; + } + else + { + putchar(*s++); + putchar(*s); + } + } + else if ((*s & 0xf0) == 0xe0) + { + /* + * Validate UTF-8 three-byte sequence... + */ + + if ((s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80) + { + putchar('?'); + s += 2; + } + else + { + putchar(*s++); + putchar(*s++); + putchar(*s); + } + } + else if ((*s & 0xf8) == 0xf0) + { + /* + * Validate UTF-8 four-byte sequence... + */ + + if ((s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 || + (s[3] & 0xc0) != 0x80) + { + putchar('?'); + s += 3; + } + else + { + putchar(*s++); + putchar(*s++); + putchar(*s++); + putchar(*s); + } + } + else if ((*s & 0x80) || (*s < ' ' && !isspace(*s & 255))) + { + /* + * Invalid control character... + */ + + putchar('?'); + } else putchar(*s); diff --git a/test/run-stp-tests.sh b/test/run-stp-tests.sh index 62ca08a1c..fa943fc95 100755 --- a/test/run-stp-tests.sh +++ b/test/run-stp-tests.sh @@ -250,9 +250,7 @@ ln -s $root/backend/http /tmp/cups-$user/bin/backend ln -s $root/backend/ipp /tmp/cups-$user/bin/backend ln -s $root/backend/lpd /tmp/cups-$user/bin/backend ln -s $root/backend/mdns /tmp/cups-$user/bin/backend -ln -s $root/backend/parallel /tmp/cups-$user/bin/backend ln -s $root/backend/pseudo /tmp/cups-$user/bin/backend -ln -s $root/backend/serial /tmp/cups-$user/bin/backend ln -s $root/backend/snmp /tmp/cups-$user/bin/backend ln -s $root/backend/socket /tmp/cups-$user/bin/backend ln -s $root/backend/usb /tmp/cups-$user/bin/backend @@ -260,16 +258,13 @@ ln -s $root/cgi-bin /tmp/cups-$user/bin ln -s $root/monitor /tmp/cups-$user/bin ln -s $root/notifier /tmp/cups-$user/bin ln -s $root/scheduler /tmp/cups-$user/bin/daemon -ln -s $root/filter/bannertops /tmp/cups-$user/bin/filter ln -s $root/filter/commandtops /tmp/cups-$user/bin/filter ln -s $root/filter/gziptoany /tmp/cups-$user/bin/filter -ln -s $root/filter/hpgltops /tmp/cups-$user/bin/filter ln -s $root/filter/pstops /tmp/cups-$user/bin/filter ln -s $root/filter/rastertoepson /tmp/cups-$user/bin/filter ln -s $root/filter/rastertohp /tmp/cups-$user/bin/filter ln -s $root/filter/rastertolabel /tmp/cups-$user/bin/filter ln -s $root/filter/rastertopwg /tmp/cups-$user/bin/filter -ln -s $root/filter/texttops /tmp/cups-$user/bin/filter ln -s $root/data/classified /tmp/cups-$user/share/banners ln -s $root/data/confidential /tmp/cups-$user/share/banners @@ -277,10 +272,7 @@ ln -s $root/data/secret /tmp/cups-$user/share/banners ln -s $root/data/standard /tmp/cups-$user/share/banners ln -s $root/data/topsecret /tmp/cups-$user/share/banners ln -s $root/data/unclassified /tmp/cups-$user/share/banners -ln -s $root/data /tmp/cups-$user/share/charmaps -ln -s $root/data /tmp/cups-$user/share/charsets ln -s $root/data /tmp/cups-$user/share -ln -s $root/fonts /tmp/cups-$user/share ln -s $root/ppdc/sample.drv /tmp/cups-$user/share/drv ln -s $root/conf/mime.types /tmp/cups-$user/share/mime ln -s $root/conf/mime.convs /tmp/cups-$user/share/mime @@ -288,14 +280,6 @@ ln -s $root/data/*.h /tmp/cups-$user/share/ppdc ln -s $root/data/*.defs /tmp/cups-$user/share/ppdc ln -s $root/templates /tmp/cups-$user/share -if test -f $root/filter/imagetops; then - ln -s $root/filter/imagetops /tmp/cups-$user/bin/filter -fi - -if test -f $root/filter/imagetoraster; then - ln -s $root/filter/imagetoraster /tmp/cups-$user/bin/filter -fi - # # Mac OS X filters and configuration files... # @@ -320,7 +304,13 @@ if test `uname` = Darwin; then ln -s /usr/share/cups/mime/apple.* /tmp/cups-$user/share/mime fi else - ln -s $root/filter/pdftops /tmp/cups-$user/bin/filter + ln -s /usr/lib/cups/filter/bannertops /tmp/cups-$user/bin/filter + ln -s /usr/lib/cups/filter/imagetops /tmp/cups-$user/bin/filter + ln -s /usr/lib/cups/filter/imagetoraster /tmp/cups-$user/bin/filter + ln -s /usr/lib/cups/filter/pdftops /tmp/cups-$user/bin/filter + ln -s /usr/lib/cups/filter/texttops /tmp/cups-$user/bin/filter + + ln -s /usr/share/cups/mime/legacy.convs /tmp/cups-$user/share/mime fi # @@ -553,7 +543,7 @@ done # date=`date "+%Y-%m-%d"` -strfile=/tmp/cups-$user/cups-str-1.5-$date-$user.html +strfile=/tmp/cups-$user/cups-str-1.6-$date-$user.html rm -f $strfile cat str-header.html >$strfile diff --git a/test/str-header.html b/test/str-header.html index 84f0d9b73..f9204bbe9 100644 --- a/test/str-header.html +++ b/test/str-header.html @@ -1,8 +1,8 @@ - - + + CUPS 1.5 Software Test Report