diff -Naur wfdb-10.2.5/INSTALL wfdb-10.2.6/INSTALL --- wfdb-10.2.5/INSTALL Thu Sep 6 15:14:25 2001 +++ wfdb-10.2.6/INSTALL Wed Jun 19 22:07:30 2002 @@ -1,5 +1,5 @@ file: INSTALL G. Moody 30 January 2000 - Last revised: 6 September 2001 + Last revised: 19 June 2002 WFDB Software Package installation notes These notes are included here for those who may not have ready access to the @@ -18,15 +18,19 @@ support for reading input files from remote web and FTP servers. See README.NETFILES for further information about this option. -2. Install the XView library (see http://www.physionet.org/physiotools/xview/) +2. WAVE is an optional part of the WFDB Software Package. If the XView + toolkit is available for your system, installing WAVE is highly recommended. + Otherwise, go on to step 3; after completing the WFDB software package + installation, you may wish to try GTKWave (an experimental version of WAVE + that uses the GTK+ GUI, which is available for many other versions of Unix). + + Install the XView library (see http://www.physionet.org/physiotools/xview/) if you want to use WAVE, and be sure that the directory that contains the XView application 'textedit' (usually /usr/openwin/bin) is in your PATH. For information about WAVE, see the WAVE User's Guide, http://www.physionet.org/physiotools/wug/. - WAVE uses Netscape (or another web browser, if you've made the appropriate - changes in waverc/Makefile) for some of its on-line help. Copy the - contents of http://www.physionet.org/physiotools/wug/ into + Copy the contents of http://www.physionet.org/physiotools/wug/ into /usr/local/help/html/wug if you wish to read the help from local files; otherwise, edit wave/wave.info and change all occurrences of '/usr/local/help/html/' into 'http://www.physionet.org/physiotools/wug/'. @@ -56,11 +60,8 @@ Unix utilities ported to MS-Windows. Accept the defaults suggested by the installer. - IMPORTANT: Although you may be able to compile the WFDB software package - using a proprietary compiler, this is NOT SUPPORTED. The 'Makefile.dos' - files in several of the subdirectories of this one can be used with the - 'make' utilities provided with most commercial C compilers, although you - will need to customize them for your compiler. Your feedback is appreciated. + See the notes near the end of this section for information contributed by + users about using proprietary compilers. 2. Download http://www.physionet.org/physiotools/binaries/windows/bin/which.exe and put it into a directory in your PATH. (This utility is needed by @@ -91,6 +92,42 @@ 6. If for any reason you wish to uninstall the WFDB Software Package, type: make uninstall from this directory. + +............................................................................... + +Using proprietary compilers + + IMPORTANT: Although you may be able to compile the WFDB software package + using a proprietary compiler, this is NOT SUPPORTED. Cygwin 'gcc' is free, + robust, and supported -- please give it a try! + + If, despite the above, you feel that you must use a proprietary compiler, + this section contains notes contributed by other users who have done so. + The developers of the WFDB software package do not use any of these + compilers, so you are on your own if you choose to use one of them. + + Between 1985 and 1995, previous versions of this software were compiled + using Borland C/C++, Microsoft C/C++, and Turbo C/C++. These compilers + came bundled with 'make'-like utilties (Microsoft's was called 'nmake'). + If you are using one of these compilers, you may be able to use the + 'Makefile.dos' files in several of the subdirectories of this one to + perform an automated compilation of the WFDB software package, although you + will need to customize these 'Makefile.dos' files for your compiler. Your + feedback is appreciated. + +Borland C++ Builder + + Thanks to Ion Gaztaņaga for these notes. + +1. Edit lib/wfdb.h to define WFDB_NETFILES as 0 (do not compile with libwww + support). It's possible that libwww support will work, but this has not + been tested. + +2. Build a static library (wfdb.lib) from the sources in the 'lib' directory, + selecting: + C calling convention + Borland Language compliance + Others: Borland C++ Builder default settings _______________________________________________________________________________ diff -Naur wfdb-10.2.5/MANIFEST wfdb-10.2.6/MANIFEST --- wfdb-10.2.5/MANIFEST Sun Mar 10 08:59:44 2002 +++ wfdb-10.2.6/MANIFEST Mon Jun 24 22:45:44 2002 @@ -46,6 +46,7 @@ app/vsetup.c app/wfdbcat.c app/wfdbcollate.c +app/wfdb-config.c app/wfdbdesc.c app/wfdbwhich.c app/wrann.c @@ -73,6 +74,7 @@ checkpkg/expected/fir.dat checkpkg/expected/fir.hea checkpkg/expected/ihr.out +checkpkg/expected/lcheck_cal checkpkg/expected/lcheck.log-NETFILES checkpkg/expected/lcheck.log-no-NETFILES checkpkg/expected/mfilt.dat @@ -239,6 +241,7 @@ doc/wag-src/ann2rr.1 doc/wag-src/annot.5 doc/wag-src/appguide.int +doc/wag-src/blankpage.tex doc/wag-src/bxb.1 doc/wag-src/calsig.1 doc/wag-src/coherence.1 @@ -299,7 +302,9 @@ doc/wag-src/wfdbcal.5 doc/wag-src/wfdbcat.1 doc/wag-src/wfdbcollate.1 +doc/wag-src/wfdb-config.1 doc/wag-src/wfdbdesc.1 +doc/wag-src/wfdbf.3 doc/wag-src/wfdbwhich.1 doc/wag-src/wrann.1 doc/wag-src/wrsamp.1 @@ -347,6 +352,7 @@ doc/wug-src/wave/misc/ doc/wug-src/wave/misc/example.xws doc/wug-src/wave/misc/html.sty +doc/wug-src/wave/misc/pstoimg doc/wug-src/wave/misc/wave.inf doc/wug-src/wave/png/ doc/wug-src/wave/png/chart2.png @@ -364,6 +370,8 @@ doc/wug-src/wave/ppm/file-print.ppm.gz doc/wug-src/wave/ppm/file-save.ppm.gz doc/wug-src/wave/ppm/find-window.ppm.gz +doc/wug-src/wave/ppm/galeon-new-helper.ppm.gz +doc/wug-src/wave/ppm/GTKWave.ppm.gz doc/wug-src/wave/ppm/help-intro.ppm.gz doc/wug-src/wave/ppm/help-topics.ppm.gz doc/wug-src/wave/ppm/level-window.ppm.gz @@ -373,6 +381,7 @@ doc/wug-src/wave/ppm/main-window.ppm.gz doc/wug-src/wave/ppm/main-with-hr.ppm.gz doc/wug-src/wave/ppm/main-with-markers.ppm.gz +doc/wug-src/wave/ppm/mozilla-new-helper.ppm.gz doc/wug-src/wave/ppm/netscape-new-helper.ppm.gz doc/wug-src/wave/ppm/noedit.ppm.gz doc/wug-src/wave/ppm/nomatch.ppm.gz @@ -397,6 +406,7 @@ doc/wug-src/wave/scripts/dossify-html doc/wug-src/wave/scripts/fixinfo doc/wug-src/wave/scripts/fixlinks +doc/wug-src/wave/scripts/fixwug.sh doc/wug-src/wave/scripts/savewin doc/wug-src/wave/scripts/wave2d doc/wug-src/wave/scripts/wugfigures @@ -423,6 +433,7 @@ examples/Makefile.top examples/Makefile.tpl examples/psamples.c +examples/psamplex.c examples/README examples/refhr.c examples/stdev.c @@ -491,7 +502,6 @@ wave/demo.txt wave/edit.c wave/editing.hlp -wave/faq.hlp wave/grid.c wave/help.c wave/helppan.c @@ -512,7 +522,7 @@ waverc/Makefile waverc/Makefile.top waverc/Makefile.tpl -waverc/urlvhead +waverc/url_view waverc/wave-remote.c waverc/wave-remote-test.c waverc/wavescript.c diff -Naur wfdb-10.2.5/Makefile wfdb-10.2.6/Makefile --- wfdb-10.2.5/Makefile Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/Makefile Mon Jun 24 22:43:07 2002 @@ -39,12 +39,12 @@ # create source archives, type `make tarballs'; or to make a binary archive, # type `make bin-tarball'. Making archives requires PGP, gzip, and GNU tar). # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables @@ -52,7 +52,7 @@ VDEFS = -DWFDB_MAJOR=$(MAJOR) -DWFDB_MINOR=$(MINOR) -DWFDB_RELEASE=$(RELEASE) # _____________________________________________________________________________ -PACKAGE=wfdb-10.2.5 +PACKAGE=wfdb-10.2.6 # file: linux.def G. Moody 31 May 2000 # Last revised: 17 December 2001 # 'make' definitions for compiling the WFDB Software Package under Linux @@ -174,8 +174,8 @@ lib-post-uninstall: echo "Nothing to be done for lib-post-uninstall" # _____________________________________________________________________________ -# file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# file: Makefile.tpl G. Moody 24 May 2000 +# Last revised: 11 March 2002 # This section of the Makefile should not need to be changed. # ARCH specifies the type of CPU and the operating system (e.g., 'i686-Linux'). @@ -230,7 +230,7 @@ cd waverc; $(MAKE) clean cd wview; $(MAKE) -f clean test -d doc && ( cd doc; $(MAKE) clean ) - rm -f *~ conf/*~ conf/prompt config.cache */*.exe + rm -f *~ conf/*~ conf/prompt config.cache */*.exe $(PACKAGE)-*.spec # 'make config.cache': check configuration config.cache: @@ -299,6 +299,12 @@ # binaries and other installed files bin-tarball: test-install cd $(HOME)/wfdb-test; tar cfvz ../$(PACKAGE)-$(ARCH).tar.gz . + +# 'make doc-tarball': make a gzipped tar archive of formatted documents +# (requires many freely-available utilities that are not part of this +# package; see doc/Makefile.top for details) +doc-tarball: + cd doc; $(MAKE) tarball # 'make rpms': make source and binary RPMs RPMROOT=/usr/src/redhat diff -Naur wfdb-10.2.5/Makefile.tpl wfdb-10.2.6/Makefile.tpl --- wfdb-10.2.5/Makefile.tpl Tue Jan 15 16:07:45 2002 +++ wfdb-10.2.6/Makefile.tpl Mon Mar 11 12:10:54 2002 @@ -1,5 +1,5 @@ -# file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# file: Makefile.tpl G. Moody 24 May 2000 +# Last revised: 11 March 2002 # This section of the Makefile should not need to be changed. # ARCH specifies the type of CPU and the operating system (e.g., 'i686-Linux'). @@ -54,7 +54,7 @@ cd waverc; $(MAKE) clean cd wview; $(MAKE) -f clean test -d doc && ( cd doc; $(MAKE) clean ) - rm -f *~ conf/*~ conf/prompt config.cache */*.exe + rm -f *~ conf/*~ conf/prompt config.cache */*.exe $(PACKAGE)-*.spec # 'make config.cache': check configuration config.cache: @@ -123,6 +123,12 @@ # binaries and other installed files bin-tarball: test-install cd $(HOME)/wfdb-test; tar cfvz ../$(PACKAGE)-$(ARCH).tar.gz . + +# 'make doc-tarball': make a gzipped tar archive of formatted documents +# (requires many freely-available utilities that are not part of this +# package; see doc/Makefile.top for details) +doc-tarball: + cd doc; $(MAKE) tarball # 'make rpms': make source and binary RPMs RPMROOT=/usr/src/redhat diff -Naur wfdb-10.2.5/NEWS wfdb-10.2.6/NEWS --- wfdb-10.2.5/NEWS Sun Mar 10 11:04:38 2002 +++ wfdb-10.2.6/NEWS Mon Jun 17 18:53:58 2002 @@ -1,3 +1,51 @@ +10.2.6: + Added setifreq() and getifreq() to the WFDB library. setifreq + allows the caller to resample an input record at any convenient + sampling frequency, using getvec() to perform xform's resampling + algorithm transparently. Thanks to Pat Hamilton for the inspiration! + The complementary getifreq returns the current getvec frequency + (either the native sampling frequency of the current record, or + the frequency previously set using setifreq()). Times expressed + in sample intervals passed to or from other WFDB functions (getann, + putann, timstr, mstimstr, strtim) are rescaled to match the intervals + corresponding to the chosen frequency. + + 'sqrs' and 'sqrs125' now use setifreq() to resample their inputs. + + Added 'wfdb-config', a tiny program (in app) that reports the WFDB + library version and linking information (similar to libwww-config, + gtk-config, etc.). + + The WFDB library now records the base time with millisecond precision + (previous versions did so with one-second precision), and 'xform' + provides starting times to the library function 'setbasetime' with + millisecond precision. Thanks to Allavatam Venugopal for providing + examples that illustrated the need for these features. + + Fixed handling of absolute time strings in 'ann2rr', 'bxb', 'epic', + 'fir', 'ihr', 'mxm', 'pscgen', 'rdann', and 'rxr' (all in app). + + Fixed deskewing buffer initialization in getframe() (in lib/signal.c). + broken by the 10.2.0 update, which introduced an infinite loop when + reading a record that requires skew correction starting at sample 0. + Thanks to Andrew Walsh for finding an example that triggered this bug. + + Fixed rounding errors in adumuv(), muvadu(), and physadu() (all in + lib/signal.c). Previous versions rounded negative values toward zero; + to obtain consistent conversions, however, it is necessary to round + all values down (e.g., from -1.5 to -2 rather than up to -1). + + Fixed a memory leak in wfdb_fclose() (in lib/wfdbio.h), and made + additional minor changes for portability (in lib/calib.c, lib/signal.c, + and lib/wfdblib.h). Thanks to Ion Gaztaņaga for bug reports, for his + careful notes on compiling the WFDB library using Borland C++ Builder + (see INSTALL for a summary), and for testing intermediate versions + of the library. + + Fixed a bug in checkpkg/appcheck, which was correctly testing xform + with NETFILES and reporting any errors, but was not counting errors + in this test. + 10.2.5: New output format options in 'ann2rr' and 'ihr'. diff -Naur wfdb-10.2.5/README.NETFILES wfdb-10.2.6/README.NETFILES --- wfdb-10.2.5/README.NETFILES Thu Sep 6 13:33:25 2001 +++ wfdb-10.2.6/README.NETFILES Fri Jun 21 22:54:12 2002 @@ -1,9 +1,9 @@ file: README.NETFILES G. Moody 14 September 1999 - Last revised: 6 September 2001 + Last revised: 21 June 2002 -This version of the WFDB software package contains experimental NETFILES -support in the WFDB library, which is compiled if you have previously -installed libwww (see http://www.w3.org/Library/). +This version of the WFDB software package contains NETFILES support in the +WFDB library, which is compiled if you have previously installed libwww +(see http://www.w3.org/Library/). NETFILES support is known to work well under Linux, Solaris, and MS-Windows. When compiling the WFDB library as a static library with NETFILES support, it @@ -15,13 +15,13 @@ path should contain one or more components that refer to remote files available via http or ftp. If NETFILES support is included, the default WFDB path (defined in lib/wfdblib.h) is - . http://www.physionet.org/physiobank/database -(i.e., the first component is the current (local) directory, and the second -component is the top-level PhysioBank database directory). If you use a -local PhysioBank mirror, you may wish to change www.physionet.org to the -hostname of your local mirror in lib/wfdblib.h before compiling the WFDB -library. You may always override this path by setting the WFDB environment -variable. + . /usr/database http://www.physionet.org/physiobank/database +(i.e., the first component is the current (local) directory, the second is +/usr/database in the local file system, and the third component is the +top-level PhysioBank database directory). If you use a local PhysioBank +mirror, you may wish to change www.physionet.org to the hostname of your local +mirror in lib/wfdblib.h before compiling the WFDB library. You may always +override this path by setting the WFDB environment variable. Provided that a remote path component (one beginning with http:// or ftp://) is included in the WFDB path, all WFDB applications that read local files will @@ -58,4 +58,4 @@ information it receives from your browser.) NETFILES support was originally implemented by Michael Dakin as part of his -summer UROP project at MIT. Thanks, Mike! +summer 1999 UROP project at MIT. Thanks, Mike! diff -Naur wfdb-10.2.5/app/Makefile wfdb-10.2.6/app/Makefile --- wfdb-10.2.5/app/Makefile Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/app/Makefile Mon Jun 24 22:43:07 2002 @@ -33,12 +33,12 @@ # type `make listing'. # _____________________________________________________________________________ # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables @@ -46,7 +46,7 @@ VDEFS = -DWFDB_MAJOR=$(MAJOR) -DWFDB_MINOR=$(MINOR) -DWFDB_RELEASE=$(RELEASE) # _____________________________________________________________________________ -PACKAGE=wfdb-10.2.5 +PACKAGE=wfdb-10.2.6 # file: linux.def G. Moody 31 May 2000 # Last revised: 17 December 2001 # 'make' definitions for compiling the WFDB Software Package under Linux @@ -169,19 +169,20 @@ echo "Nothing to be done for lib-post-uninstall" # _____________________________________________________________________________ # file: Makefile.tpl G. Moody 23 May 2000 -# Last revised: 6 December 2000 +# Last revised: 27 April 2002 # This section of the Makefile should not need to be changed. CFILES = ann2rr.c bxb.c calsig.c ecgeval.c epic.c fir.c ihr.c mfilt.c \ mrgann.c mxm.c nst.c plotstm.c pscgen.c pschart.c psfd.c rdann.c rdsamp.c \ rr2ann.c rxr.c sampfreq.c sample.c sigamp.c skewedit.c snip.c sortann.c \ sqrs.c sqrs125.c sumann.c sumstats.c tach.c view.c vsetup.c wfdbcat.c \ - wfdbcollate.c wfdbdesc.c wfdbwhich.c wrann.c wrsamp.c wvscript.c xform.c + wfdbcollate.c wfdb-config.c wfdbdesc.c wfdbwhich.c wrann.c wrsamp.c \ + wvscript.c xform.c XFILES = ann2rr bxb calsig ecgeval epic fir ihr mfilt \ mrgann mxm nst plotstm pscgen pschart psfd rdann rdsamp \ rr2ann rxr sampfreq sigamp skewedit snip sortann \ sqrs sqrs125 sumann sumstats tach wfdbcat \ - wfdbcollate wfdbdesc wfdbwhich wrann wrsamp xform + wfdbcollate wfdb-config wfdbdesc wfdbwhich wrann wrsamp xform SCRIPTS = cshsetwfdb setwfdb PSFILES = pschart.pro psfd.pro 12lead.pro OTHERFILES = cshsetwfdb setwfdb setwfdb.bat sample8.hea @@ -247,3 +248,6 @@ $(CC) $(CFLAGS) -DPROLOG=\"$(PSPDIR)/psfd.pro\" psfd.c -o $@ $(LDFLAGS) sigamp: sigamp.c $(CC) $(CFLAGS) sigamp.c -o $@ $(LDFLAGS) -lm +wfdb-config: wfdb-config.c Makefile + $(CC) -DVERSION='"$(VERSION)"' -DCFLAGS='"-I$(INCDIR)"' \ + -DLDFLAGS='"$(LDFLAGS)"' -o $@ wfdb-config.c diff -Naur wfdb-10.2.5/app/Makefile.tpl wfdb-10.2.6/app/Makefile.tpl --- wfdb-10.2.5/app/Makefile.tpl Wed Dec 6 16:32:12 2000 +++ wfdb-10.2.6/app/Makefile.tpl Sat Apr 27 16:40:07 2002 @@ -1,17 +1,18 @@ # file: Makefile.tpl G. Moody 23 May 2000 -# Last revised: 6 December 2000 +# Last revised: 27 April 2002 # This section of the Makefile should not need to be changed. CFILES = ann2rr.c bxb.c calsig.c ecgeval.c epic.c fir.c ihr.c mfilt.c \ mrgann.c mxm.c nst.c plotstm.c pscgen.c pschart.c psfd.c rdann.c rdsamp.c \ rr2ann.c rxr.c sampfreq.c sample.c sigamp.c skewedit.c snip.c sortann.c \ sqrs.c sqrs125.c sumann.c sumstats.c tach.c view.c vsetup.c wfdbcat.c \ - wfdbcollate.c wfdbdesc.c wfdbwhich.c wrann.c wrsamp.c wvscript.c xform.c + wfdbcollate.c wfdb-config.c wfdbdesc.c wfdbwhich.c wrann.c wrsamp.c \ + wvscript.c xform.c XFILES = ann2rr bxb calsig ecgeval epic fir ihr mfilt \ mrgann mxm nst plotstm pscgen pschart psfd rdann rdsamp \ rr2ann rxr sampfreq sigamp skewedit snip sortann \ sqrs sqrs125 sumann sumstats tach wfdbcat \ - wfdbcollate wfdbdesc wfdbwhich wrann wrsamp xform + wfdbcollate wfdb-config wfdbdesc wfdbwhich wrann wrsamp xform SCRIPTS = cshsetwfdb setwfdb PSFILES = pschart.pro psfd.pro 12lead.pro OTHERFILES = cshsetwfdb setwfdb setwfdb.bat sample8.hea @@ -77,3 +78,6 @@ $(CC) $(CFLAGS) -DPROLOG=\"$(PSPDIR)/psfd.pro\" psfd.c -o $@ $(LDFLAGS) sigamp: sigamp.c $(CC) $(CFLAGS) sigamp.c -o $@ $(LDFLAGS) -lm +wfdb-config: wfdb-config.c Makefile + $(CC) -DVERSION='"$(VERSION)"' -DCFLAGS='"-I$(INCDIR)"' \ + -DLDFLAGS='"$(LDFLAGS)"' -o $@ wfdb-config.c diff -Naur wfdb-10.2.5/app/ann2rr.c wfdb-10.2.6/app/ann2rr.c --- wfdb-10.2.5/app/ann2rr.c Tue Jan 15 12:46:19 2002 +++ wfdb-10.2.6/app/ann2rr.c Mon May 20 17:40:17 2002 @@ -1,5 +1,5 @@ -/* file: ann2rr.c G. Moody 16 May 1995 - Last revised: 15 January 2002 +/* file: ann2rr.c G. Moody 16 May 1995 + Last revised: 20 May 2002 ------------------------------------------------------------------------------- ann2rr: Calculate RR intervals from an annotation file Copyright (C) 2002 George B. Moody @@ -161,16 +161,17 @@ if (to) { if (*argv[(int)to] == '#') { if ((beat_number = atol(argv[(int)to]+1)) < 1L) beat_number = 1L; - to = 0L; + to = (WFDB_Time)0; } else { beat_number = -1L; to = strtim(argv[(int)to]); + if (to < (WFDB_Time)0) to = -to; } } tp = from; - while (getann(0, &annot) == 0 && (to == 0L || annot.time <= to)) { + while (getann(0, &annot) == 0 && (to == (WFDB_Time)0 || annot.time <= to)){ if (!isann(annot.anntyp)) continue; if ((flag[0] && isqrs(annot.anntyp)) || flag[annot.anntyp]) { if (cflag == 0 || previous_annot_valid == 1) { diff -Naur wfdb-10.2.5/app/bxb.c wfdb-10.2.6/app/bxb.c --- wfdb-10.2.5/app/bxb.c Wed Nov 7 10:58:28 2001 +++ wfdb-10.2.6/app/bxb.c Mon May 20 17:52:34 2002 @@ -1,9 +1,9 @@ /* file: bxb.c G. Moody 14 December 1987 - Last revised: 7 November 2001 + Last revised: 20 May 2002 ------------------------------------------------------------------------------- bxb: ANSI/AAMI-standard beat-by-beat annotation file comparator -Copyright (C) 2001 George B. Moody +Copyright (C) 2002 George B. Moody This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -778,12 +778,25 @@ match_dt = (int)strtim(argv[match_dt]); else match_dt = (int)strtim(".15"); /* 150 milliseconds */ - if (start) + if (start) { start = strtim(argv[(int)start]); + /* If the header file defines a base time (absolute time of day), + the start and end times can be supplied in the form '[hh:mm:ss]', + and strtim returns a negative value (to signal that the user + specified the time in this way). In this case, the magnitude of + the returned value is the elapsed time in sample intervals. We + don't care how the user entered the time here, so we throw away + the sign information and keep the elapsed time. */ + if (start < (WFDB_Time)0) + start = -start; + } else start = strtim("5:0"); /* 5 minutes */ - if (end_time) + if (end_time) { end_time = strtim(argv[(int)end_time]); + /* See the comments about strtim in the previous block (above). */ + if (end_time < (WFDB_Time)0) end_time = -end_time; + } else if ((end_time = strtim("e")) == 0L) end_time = -1L; /* record length unavailable -- go to end of reference annotation file */ diff -Naur wfdb-10.2.5/app/epic.c wfdb-10.2.6/app/epic.c --- wfdb-10.2.5/app/epic.c Wed Nov 7 10:58:58 2001 +++ wfdb-10.2.6/app/epic.c Mon May 20 17:54:33 2002 @@ -947,12 +947,16 @@ the test period. */ if (min_length) min_length = strtim(argv[min_length]); - if (start_time) + if (start_time) { start_time = strtim(argv[(int)start_time]); + if (start_time < (WFDB_Time)0) start_time = -start_time; + } else start_time = strtim("5:0"); /* 5 minutes */ - if (end_time) + if (end_time) { end_time = strtim(argv[(int)end_time]); + if (end_time < (WFDB_Time)0) end_time = -end_time; + } else if ((end_time = strtim("e")) == 0L) end_time = -1L; /* record length unavailable -- go to end of reference annotation file */ diff -Naur wfdb-10.2.5/app/fir.c wfdb-10.2.6/app/fir.c --- wfdb-10.2.5/app/fir.c Tue Oct 9 10:35:00 2001 +++ wfdb-10.2.6/app/fir.c Mon May 20 17:57:17 2002 @@ -1,9 +1,9 @@ /* file: fir.c G. Moody 5 January 1987 - Last revised: 9 October 2001 + Last revised: 20 May 2002 ------------------------------------------------------------------------------- fir: General-purpose FIR filter for database records -Copyright (C) 2001 George B. Moody +Copyright (C) 2002 George B. Moody This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -227,10 +227,13 @@ } if (from > 0L) { from = strtim(argv[from]); + if (from < (WFDB_Time)0) from = -from; (void)isigsettime(from); } - if (to > 0L) + if (to > 0L) { to = strtim(argv[to]); + if (to < (WFDB_Time)0) to = -to; + } nsamp = (to > 0L) ? to - from : -1L; if ((vout = (int *)calloc((unsigned)nsig, sizeof(int))) == NULL || (vin = (int **)calloc((unsigned)flen, sizeof(int *))) == NULL) diff -Naur wfdb-10.2.5/app/ihr.c wfdb-10.2.6/app/ihr.c --- wfdb-10.2.5/app/ihr.c Tue Jan 15 15:12:24 2002 +++ wfdb-10.2.6/app/ihr.c Mon May 20 17:58:39 2002 @@ -1,5 +1,5 @@ /* file ihr.c G. Moody 12 November 1992 - Last revised: 15 January 2002 + Last revised: 20 May 2002 ------------------------------------------------------------------------------- ihr: Generate instantaneous heart rate data from annotation file @@ -167,7 +167,10 @@ exit(2); if (from && iannsettime(strtim(argv[(int)from])) < 0) exit(2); - if (to) to = strtim(argv[(int)to]); + if (to) { + to = strtim(argv[(int)to]); + if (to < (WFDB_Time)0) to = -to; + } if (flag[0]) /* neither -i nor -p used -- include only normal beats */ for (j = 0; j <= ACMAX; j++) diff -Naur wfdb-10.2.5/app/mxm.c wfdb-10.2.6/app/mxm.c --- wfdb-10.2.5/app/mxm.c Sun Jan 30 04:13:16 2000 +++ wfdb-10.2.6/app/mxm.c Mon May 20 18:00:44 2002 @@ -1,9 +1,9 @@ /* file: mxm.c G. Moody 20 March 1992 - Last revised: 4 May 1999 + Last revised: 20 May 2002 ------------------------------------------------------------------------------- mxm: ANSI/AAMI-standard measurement-by-measurement annotation file comparator -Copyright (C) 1999 George B. Moody +Copyright (C) 2002 George B. Moody This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -306,12 +306,16 @@ } /* Set the times of the start and end of the test period. */ - if (start) + if (start) { start = strtim(argv[(int)start]); + if (start < (WFDB_Time)0) start = -start; + } else start = strtim("5:0"); /* 5 minutes */ - if (end_time) + if (end_time) { end_time = strtim(argv[(int)end_time]); + if (end_time < (WFDB_Time)0) end_time = -end_time; + } else if ((end_time = strtim("e")) == 0L) end_time = -1L; /* record length unavailable -- go to end of reference annotation file */ diff -Naur wfdb-10.2.5/app/pscgen.c wfdb-10.2.6/app/pscgen.c --- wfdb-10.2.5/app/pscgen.c Sun Jan 30 04:13:16 2000 +++ wfdb-10.2.6/app/pscgen.c Mon May 20 18:20:34 2002 @@ -1,9 +1,9 @@ /* file: pscgen.c G. Moody 26 November 1990 - Last revised: 4 May 1999 + Last revised: 20 May 2002 ------------------------------------------------------------------------------- pscgen: Generate a script for pschart -Copyright (C) 1999 George B. Moody +Copyright (C) 2002 George B. Moody This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -80,6 +80,7 @@ exit(1); } from = strtim(argv[i]); + if (from < (WFDB_Time)0) from = -from; break; case 'l': /* specify strip length */ if (++i >= argc) { @@ -94,6 +95,7 @@ exit(1); } to = strtim(argv[i]); + if (to < (WFDB_Time)0) to = -to; break; } else { diff -Naur wfdb-10.2.5/app/rdann.c wfdb-10.2.6/app/rdann.c --- wfdb-10.2.5/app/rdann.c Mon Feb 26 12:31:54 2001 +++ wfdb-10.2.6/app/rdann.c Mon May 20 17:35:41 2002 @@ -1,9 +1,9 @@ /* file rdann.c T. Baker and G. Moody 27 July 1981 - Last revised: 26 February 2001 + Last revised: 20 May 2002 ------------------------------------------------------------------------------- rdann: Print an annotation file in ASCII form -Copyright (C) 1999 George B. Moody +Copyright (C) 2002 George B. Moody This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -232,11 +232,12 @@ if (to) { if (*argv[(int)to] == '#') { if ((beat_number = atol(argv[(int)to]+1)) < 1L) beat_number = 1L; - to = 0L; + to = (WFDB_Time)0; } else { beat_number = -1L; to = strtim(argv[(int)to]); + if (to < (WFDB_Time)0) to = -to; } } diff -Naur wfdb-10.2.5/app/rxr.c wfdb-10.2.6/app/rxr.c --- wfdb-10.2.5/app/rxr.c Wed Nov 7 10:59:15 2001 +++ wfdb-10.2.6/app/rxr.c Mon May 20 19:17:35 2002 @@ -1,9 +1,9 @@ /* file: rxr.c G. Moody 16 August 1989 - Last revised: 7 November 2001 + Last revised: 20 May 2002 ------------------------------------------------------------------------------- rxr: ANSI/AAMI-standard run-by-run annotation file comparator -Copyright (C) 2001 George B. Moody +Copyright (C) 2002 George B. Moody This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -701,12 +701,16 @@ match_dt = (int)strtim(argv[match_dt]); else match_dt = (int)strtim(".15"); /* 150 milliseconds */ - if (start) + if (start) { start = strtim(argv[(int)start]); + if (start < (WFDB_Time)0) start = -start; + } else start = strtim("5:0"); /* 5 minutes */ - if (end_time) + if (end_time) { end_time = strtim(argv[(int)end_time]); + if (end_time < (WFDB_Time)0) end_time = -end_time; + } else if ((end_time = strtim("e")) == 0L) end_time = -1L; /* record length unavailable -- go to end of reference annotation file */ diff -Naur wfdb-10.2.5/app/sqrs.c wfdb-10.2.6/app/sqrs.c --- wfdb-10.2.5/app/sqrs.c Mon Dec 17 21:52:00 2001 +++ wfdb-10.2.6/app/sqrs.c Tue May 28 11:22:10 2002 @@ -1,9 +1,9 @@ /* file: sqrs.c G. Moody 27 October 1990 - Last revised: 17 December 2001 + Last revised: 28 May 2002 ------------------------------------------------------------------------------- sqrs: Single-channel QRS detector -Copyright (C) 2001 George B. Moody +Copyright (C) 2002 George B. Moody This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -34,10 +34,9 @@ `sqrs' can process records containing any number of signals, but it uses only one signal for QRS detection (signal 0 by default; this can be changed using -the `-s' option, see below). For best results on adult human ECGs, use `xform' -to resample the input signal at 250 Hz if a different sampling frequency was -used originally. For other ECGs, it may be necessary to experiment with the -input sampling frequency and the time constants indicated below. +the `-s' option, see below). 'sqrs' has been optimized for adult human ECGs. +For other ECGs, it may be necessary to experiment with the input sampling +frequency and the time constants indicated below. This program is provided as an example only, and is not intended for any clinical application. At the time the algorithm was originally published, @@ -170,11 +169,8 @@ } a.name = "qrs"; a.stat = WFDB_WRITE; if ((nsig = wfdbinit(record, &a, 1, s, nsig)) < 1) exit(2); - if (sampfreq((char *)NULL) < 200. || sampfreq((char *)NULL) > 300.) { - (void)fprintf(stderr, "warning: %s is designed for 250 Hz input\n", - argv[0]); - (void)fprintf(stderr, " Consider resampling using `xform'.\n"); - } + if (sampfreq((char *)NULL) < 240. || sampfreq((char *)NULL) > 260.) + setifreq(250.); if (from > 0L) { if ((from = strtim(argv[from])) < 0L) from = -from; diff -Naur wfdb-10.2.5/app/sqrs125.c wfdb-10.2.6/app/sqrs125.c --- wfdb-10.2.5/app/sqrs125.c Mon Dec 17 21:51:41 2001 +++ wfdb-10.2.6/app/sqrs125.c Tue May 28 11:59:42 2002 @@ -1,9 +1,9 @@ /* file: sqrs125.c G. Moody 27 October 1990 - Last revised: 17 December 2001 + Last revised: 28 May 2002 ------------------------------------------------------------------------------- sqrs125: Single-channel QRS detector for data sampled at 100 - 150 Hz -Copyright (C) 2001 George B. Moody +Copyright (C) 2002 George B. Moody This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -177,11 +177,8 @@ } a.name = "qrs"; a.stat = WFDB_WRITE; if ((nsig = wfdbinit(record, &a, 1, s, nsig)) < 1) exit(2); - if (sampfreq((char *)NULL) < 100. || sampfreq((char *)NULL) > 150.) { - (void)fprintf(stderr, "warning: %s is designed for 125 Hz input\n", - argv[0]); - (void)fprintf(stderr, " Consider resampling using `xform'.\n"); - } + if (sampfreq((char *)NULL) < 120. || sampfreq((char *)NULL) > 130.) + setifreq(125.); if (from > 0L) { if ((from = strtim(argv[from])) < 0L) from = -from; diff -Naur wfdb-10.2.5/app/wfdb-config.c wfdb-10.2.6/app/wfdb-config.c --- wfdb-10.2.5/app/wfdb-config.c Wed Dec 31 19:00:00 1969 +++ wfdb-10.2.6/app/wfdb-config.c Mon Jun 17 19:07:26 2002 @@ -0,0 +1,107 @@ +/* file: wfdb-config.c G. Moody 27 April 2002 + +------------------------------------------------------------------------------- +wfdb-config: Print WFDB library version and linking information +Copyright (C) 2002 George B. Moody + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place - Suite 330, Boston, MA 02111-1307, USA. + +You may contact the author by e-mail (george@mit.edu) or postal mail +(MIT Room E25-505A, Cambridge, MA 02139 USA). For updates to this software, +please visit PhysioNet (http://www.physionet.org/). +_______________________________________________________________________________ + +*/ + +#include +#ifndef __STDC__ +extern void exit(); +#endif + +#include + +#ifndef VERSION +#define VERSION "VERSION not defined" +#endif + +#ifndef LDFLAGS +#define LDFLAGS "LDFLAGS not defined" +#endif + +#ifndef CFLAGS +#define CFLAGS "CFLAGS not defined" +#endif + +char *pname; + +main(argc, argv) +int argc; +char *argv[]; +{ + char *filename, *prog_name(); + int i; + void help(); + + pname = prog_name(argv[0]); + if (argc == 1) { + help(); + exit(1); + } + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "--version") == 0) + printf("%s\n", VERSION); + else if (strcmp(argv[i], "--libs") == 0) + printf("%s\n", LDFLAGS); + else if (strcmp(argv[i], "--cflags") == 0) + printf("%s\n", CFLAGS); + else + help(); + } + exit(0); +} + +char *prog_name(s) +char *s; +{ + char *p = s + strlen(s); + +#ifdef MSDOS + while (p >= s && *p != '\\' && *p != ':') { + if (*p == '.') + *p = '\0'; /* strip off extension */ + if ('A' <= *p && *p <= 'Z') + *p += 'a' - 'A'; /* convert to lower case */ + p--; + } +#else + while (p >= s && *p != '/') + p--; +#endif + return (p+1); +} + +static char *help_strings[] = { + "usage: %s [--version] [--libs] [--cflags]\n", + NULL +}; + +void help() +{ + int i; + + (void)fprintf(stderr, help_strings[0], pname); + for (i = 1; help_strings[i] != NULL; i++) + (void)fprintf(stderr, "%s\n", help_strings[i]); +} diff -Naur wfdb-10.2.5/app/xform.c wfdb-10.2.6/app/xform.c --- wfdb-10.2.5/app/xform.c Sun Oct 14 22:34:15 2001 +++ wfdb-10.2.6/app/xform.c Mon May 20 20:39:37 2002 @@ -1,9 +1,9 @@ /* file: xform.c G. Moody 8 December 1983 - Last revised: 14 October 2001 + Last revised: 20 May 2002 ------------------------------------------------------------------------------- xform: Sampling frequency, amplitude, and format conversion for WFDB records -Copyright (C) 2001 George B. Moody +Copyright (C) 2002 George B. Moody This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -502,7 +502,7 @@ if (from) startp = argv[(int)from]; from = strtim(startp); if (from < 0L) from = -from; - strcpy(btstring, timstr(-from)); + strcpy(btstring, mstimstr(-from)); if (to) { to = strtim(argv[(int)to]); if (to < 0L) to = -to; diff -Naur wfdb-10.2.5/checkpkg/Makefile wfdb-10.2.6/checkpkg/Makefile --- wfdb-10.2.5/checkpkg/Makefile Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/checkpkg/Makefile Mon Jun 24 22:43:07 2002 @@ -31,12 +31,12 @@ # directory). To print a set of source listings, type `make listing'. # _____________________________________________________________________________ # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables @@ -44,7 +44,7 @@ VDEFS = -DWFDB_MAJOR=$(MAJOR) -DWFDB_MINOR=$(MINOR) -DWFDB_RELEASE=$(RELEASE) # _____________________________________________________________________________ -PACKAGE=wfdb-10.2.5 +PACKAGE=wfdb-10.2.6 # file: linux.def G. Moody 31 May 2000 # Last revised: 17 December 2001 # 'make' definitions for compiling the WFDB Software Package under Linux diff -Naur wfdb-10.2.5/checkpkg/appcheck wfdb-10.2.6/checkpkg/appcheck --- wfdb-10.2.5/checkpkg/appcheck Tue Dec 18 10:20:31 2001 +++ wfdb-10.2.6/checkpkg/appcheck Thu May 23 20:22:15 2002 @@ -1,6 +1,6 @@ #!/bin/sh # file: appcheck G. Moody 7 September 2001 -# Last revised: 18 December 2001 +# Last revised: 23 May 2002 # # This script checks the functionality of the WFDB applications in the 'app' # directory. @@ -381,8 +381,9 @@ TESTS=`expr $TESTS + 1` done -( grep "WFDB_NETFILES 1" /usr/include/wfdb/wfdb.h >/dev/null 2>&1 ) && -( echo "Testing xform (with NETFILES) ..." +if ( grep "WFDB_NETFILES 1" /usr/include/wfdb/wfdb.h >/dev/null 2>&1 ) +then + echo "Testing xform (with NETFILES) ..." xform -i mimicdb/237/237 -s 1 2 0 3 -f 9:19:45 -t "[22:01:23 20/07/1995]" \ -a all -M -n xform -S input/xform >xform-2.out 2>&1 for F in xform-2.out xform.hea xform.dat xform.all @@ -396,7 +397,7 @@ fi TESTS=`expr $TESTS + 1` done -) +fi cat < 1 ? "s" :""); @@ -187,8 +254,10 @@ int check(char *record, char *orec) { + WFDB_Date d; WFDB_Frequency f; WFDB_Time t, tt; + double x; /* *** sampfreq *** */ if ((f = sampfreq(NULL)) != 0.0) { @@ -238,7 +307,79 @@ else if (vflag) printf("[OK]: annopen of 2 files succeeded\n"); - /* *** strtim *** */ + /* *** strecg, ecgstr *** */ + i = strecg("N"); + if (i != 1) { + printf("Error: strecg returned %d (should have been 1)\n", i); + errors++; + } + else if (vflag) + printf("[OK]: strecg returned %d\n", i); + + p = ecgstr(i); + if (strcmp(p, "N")) { + printf("Error: ecgstr returned '%s' (should have been 'N')\n", p); + errors++; + } + else if (vflag) + printf("[OK]: ecgstr returned '%s'\n", p); + + /* *** strann, annstr, anndesc *** */ + i = strann("N"); + if (i != 1) { + printf("Error: strann returned %d (should have been 1)\n", i); + errors++; + } + else if (vflag) + printf("[OK]: strann returned %d\n", i); + + p = annstr(i); + if (strcmp(p, "N")) { + printf("Error: annstr returned '%s' (should have been 'N')\n", p); + errors++; + } + else if (vflag) + printf("[OK]: annstr returned '%s'\n", p); + + p = anndesc(i); + if (strcmp(p, "Normal beat")) { + printf("Error: anndesc returned '%s' (should have been 'Normal beat')\n", + p); + errors++; + } + else if (vflag) + printf("[OK]: anndesc returned '%s'\n", p); + + /* *** setecgstr, setannstr, setanndesc *** */ + + i = setecgstr(1, "X"); + p = ecgstr(1); + if (i != 0 || strcmp(p, "X")) { + printf("Error: setecgstr failed\n"); + errors++; + } + else if (vflag) + printf("[OK]: setecgstr succeeded\n"); + + i = setannstr(-1, "Y"); + p = annstr(1); + if (i != 0 || strcmp(p, "Y")) { + printf("Error: setannstr failed\n"); + errors++; + } + else if (vflag) + printf("[OK]: setannstr succeeded\n"); + + i = setanndesc(-1, "ZZ zz"); + p = anndesc(1); + if (i != 0 || strcmp(p, "ZZ zz")) { + printf("Error: setanndesc failed\n"); + errors++; + } + else if (vflag) + printf("[OK]: setanndesc succeeded\n"); + + /* *** strtim, timstr *** */ t = strtim("0:5"); if (t != (WFDB_Time)(5.0 * f)) { printf("Error: strtim returned %ld (should have been %ld)\n", t, @@ -247,7 +388,32 @@ } else if (vflag) printf("[OK]: strtim returned %ld\n", t); - + + p = timstr(t); q = " 0:05"; + if (strcmp(p, q)) { + printf("Error: timstr returned '%s' (should have been '%s')\n", p, q); + errors++; + } + else if (vflag) + printf("[OK]: timstr returned '%s'\n", p); + + /* *** strdat, datstr *** */ + q = " 31/12/1999"; + d = strdat(q); + if (d != 2451544L) { + printf("Error: strdat returned %ld (should have been 2451544)\n", d); + errors++; + } + else if (vflag) + printf("[OK]: strdat returned %ld\n", d); + p = datstr(d); + if (strcmp(p, q)) { + printf("Error: datstr returned '%s' (should have been '%s')\n", p, q); + errors++; + } + else if (vflag) + printf("[OK]: datstr returned '%s'\n", p); + /* *** iannsettime *** */ stat = iannsettime(t); if (stat) { @@ -259,7 +425,7 @@ printf("[OK]: iannsettime skipping forward to %s\n", timstr(t)); - /* *** getann, annstr, mstimstr *** */ + /* *** getann, stimstr *** */ for (i = 0; i < 5; i++) { stat = getann(0, &annot); if (stat != 0 && stat != -1) { @@ -344,6 +510,40 @@ } } + /* *** aduphys, physadu *** */ + x = aduphys((WFDB_Signal)0, (WFDB_Sample)1000); + if (x != -0.12) { + printf("Error: aduphys returned %g (should have been -0.12)\n", x); + errors++; + } + else if (vflag) + printf("[OK]: aduphys returned %g\n", x); + + i = physadu((WFDB_Signal)0, x); + if (i != (WFDB_Sample)1000) { + printf("Error: physadu returned %d (should have been 1000)\n", i); + errors++; + } + else if (vflag) + printf("[OK]: physadu returned %d\n", i); + + /* *** adumuv, muvadu *** */ + i = adumuv((WFDB_Signal)0, (WFDB_Sample)1000); + if (i != 5000) { + printf("Error: adumuv returned %d (should have been 5000)\n", i); + errors++; + } + else if (vflag) + printf("[OK]: adumuv returned %d\n", i); + + i = muvadu((WFDB_Signal)0, i); + if (i != (WFDB_Sample)1000) { + printf("Error: muvadu returned %d (should have been 1000)\n", i); + errors++; + } + else if (vflag) + printf("[OK]: muvadu returned %d\n", i); + /* *** sampfreq *** */ f = sampfreq(NULL); if (f != 360.0) { @@ -362,6 +562,14 @@ } else if (vflag) printf("[OK]: strtim returned %ld\n", t); + + p = timstr(t); q = " 0:20"; + if (strcmp(p, q)) { + printf("Error: timstr returned '%s' (should have been '%s')\n", p, q); + errors++; + } + else if (vflag) + printf("[OK]: timstr returned '%s'\n", p); /* *** isigsettime *** */ stat = isigsettime(t); @@ -494,6 +702,9 @@ } wfdbquit(); + setecgstr(1, "N"); + setannstr(-1, "N"); + setanndesc(-1, "Normal beat"); } char *prog_name(s) @@ -542,25 +753,8 @@ printf("setgvmode\n"); printf("ungetann\n"); printf("isgsettime\n"); - printf("ecgstr\n"); - printf("strecg\n"); - printf("setecgstr\n"); - printf("strann\n"); - printf("setannstr\n"); - printf("anndesc\n"); - printf("setanndesc\n"); printf("iannclose\n"); printf("oannclose\n"); - printf("datstr\n"); - printf("strdat\n"); - printf("adumuv\n"); - printf("muvadu\n"); - printf("physadu\n"); - printf("calopen\n"); - printf("getcal\n"); - printf("putcal\n"); - printf("newcal\n"); - printf("flushcal\n"); printf("setheader\n"); printf("setmsheader\n"); printf("wfdbgetskew\n"); @@ -578,4 +772,6 @@ printf("setobsize\n"); printf("wfdbfile\n"); printf("wfdbflush\n"); + printf("setifreq\n"); + printf("getifreq\n"); } diff -Naur wfdb-10.2.5/checkpkg/libcheck wfdb-10.2.6/checkpkg/libcheck --- wfdb-10.2.5/checkpkg/libcheck Tue Dec 11 12:53:41 2001 +++ wfdb-10.2.6/checkpkg/libcheck Mon Jun 17 18:42:10 2002 @@ -1,6 +1,6 @@ #!/bin/sh # file: libcheck G. Moody 8 September 2001 -# Last revised: 11 December 2001 +# Last revised: 17 June 2002 # # This script checks the functionality of the WFDB library by comparing the # outputs of 'lcheck' with expected outputs. See 'lcheck.c' for details of @@ -28,7 +28,7 @@ ./lcheck -v >lcheck.log cp ../data/100s.atr expected/100s.chk cp ../data/100s.dat expected/100z.dat -CF="lcheck.log 100s.chk 100z.dat 100z.hea" +CF="lcheck.log lcheck_cal 100s.chk 100z.dat 100z.hea" if grep "WFDB supports NETFILES" lcheck.log >/dev/null 2>&1 then CF="$CF udb/100s.chk udb/100z.dat udb/100z.hea" @@ -50,6 +50,7 @@ PASS=`expr $PASS + 1` case $i in *.hea) rm -f $i ;; + lcheck_cal) rm -f $i ;; *) rm -f $i expected/$i ;; esac else diff -Naur wfdb-10.2.5/conf/version.def wfdb-10.2.6/conf/version.def --- wfdb-10.2.5/conf/version.def Tue Jan 15 15:42:39 2002 +++ wfdb-10.2.6/conf/version.def Mon Mar 11 11:50:47 2002 @@ -1,10 +1,10 @@ # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables diff -Naur wfdb-10.2.5/convert/Makefile wfdb-10.2.6/convert/Makefile --- wfdb-10.2.5/convert/Makefile Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/convert/Makefile Mon Jun 24 22:43:07 2002 @@ -33,12 +33,12 @@ # type `make listing'. # _____________________________________________________________________________ # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables @@ -46,7 +46,7 @@ VDEFS = -DWFDB_MAJOR=$(MAJOR) -DWFDB_MINOR=$(MINOR) -DWFDB_RELEASE=$(RELEASE) # _____________________________________________________________________________ -PACKAGE=wfdb-10.2.5 +PACKAGE=wfdb-10.2.6 # file: linux.def G. Moody 31 May 2000 # Last revised: 17 December 2001 # 'make' definitions for compiling the WFDB Software Package under Linux diff -Naur wfdb-10.2.5/data/Makefile wfdb-10.2.6/data/Makefile --- wfdb-10.2.5/data/Makefile Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/data/Makefile Mon Jun 24 22:43:07 2002 @@ -33,12 +33,12 @@ # listing'. # _____________________________________________________________________________ # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables @@ -46,7 +46,7 @@ VDEFS = -DWFDB_MAJOR=$(MAJOR) -DWFDB_MINOR=$(MINOR) -DWFDB_RELEASE=$(RELEASE) # _____________________________________________________________________________ -PACKAGE=wfdb-10.2.5 +PACKAGE=wfdb-10.2.6 # file: linux.def G. Moody 31 May 2000 # Last revised: 17 December 2001 # 'make' definitions for compiling the WFDB Software Package under Linux diff -Naur wfdb-10.2.5/doc/Makefile wfdb-10.2.6/doc/Makefile --- wfdb-10.2.5/doc/Makefile Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/doc/Makefile Mon Jun 24 22:43:07 2002 @@ -1,10 +1,10 @@ # file: Makefile G. Moody 24 June 1989 -# Last revised: 18 December 2001 +# Last revised: 11 March 2002 # `make' description file for WFDB software documentation # # ----------------------------------------------------------------------------- # WFDB applications: programs for working with annotated signals -# Copyright (C) 2001 George B. Moody +# Copyright (C) 2002 George B. Moody # # These programs are free software; you can redistribute them and/or modify # them under the terms of the GNU General Public License as published by the @@ -69,25 +69,28 @@ # of available formats and the commands needed to produce them: # WFDB Applications Guide -# printed copy 'make ag' (requires troff, tbl, latex, dvips, & a printer) -# HTML 'make ag.html' (requires rman, latex2html, and perl) -# man pages 'make ag.man' -# PDF 'make ag.pdf' (requires troff, tbl, latex, dvips, and ps2pdf) -# PostScript 'make ag.ps' (requires troff, tbl, latex, and dvips) -# +# printed copy 'make wag-book' (requires troff, tbl, latex, dvips, a printer) +# HTML 'make wag.html' (requires rman, latex2html, and perl) +# man pages 'make wag.man' +# PDF 'make wag.pdf' (requires troff, tbl, latex, dvips, and ps2pdf) +# PostScript 'make wag.ps' (requires troff, tbl, latex, dvips, ps2pdf, and +# pdftops *) # WFDB Programmer's Guide -# printed copy 'make pg' (requires troff, texi2dvi, dvips, & a printer) -# Windows help 'make pg.hlp' (requires makertf and hcrtf) -# HTML 'make pg.html' (requires texi2html and perl) -# info 'make pg.info' (requires makeinfo or GNU emacs) -# PDF 'make pg.pdf' (requires texi2dvi) -# PostScript 'make pg.ps' (requires texi2dvi and dvips) +# printed copy 'make wpg-book' (requires troff, texi2dvi, dvips, & a printer) +# Windows help 'make wpg.hlp' (requires makertf and hcrtf) +# HTML 'make wpg.html' (requires texi2html and perl) +# info 'make wpg.info' (requires makeinfo or GNU emacs) +# PDF 'make wpg.pdf' (requires texi2dvi) +# PostScript 'make wpg.ps' (requires texi2dvi and dvips) # # WAVE User's Guide -# printed copy 'make ug' (requires troff, latex, dvips, and a printer) -# HTML 'make ug.html' (requires latex2html and perl) -# PDF 'make ug.pdf' (requires pdflatex) -# PostScript 'make ug.ps' (requires latex and dvips) +# printed copy 'make wug-book' (requires troff, latex, dvips, and a printer) +# HTML 'make wug.html' (requires latex2html and perl) +# PDF 'make wug.pdf' (requires pdflatex) +# PostScript 'make wug.ps' (requires latex and dvips) + +# * See 'wag-src/Makefile' for information about making a PostScript version +# of the WFDB Applications Guide without the use of ps2pdf or pdftops. # If GNU emacs or GNU info has been installed on your system, a hypertext # version of the WFDB Programmer's Guide may be installed by typing `make @@ -131,12 +134,12 @@ # `make ug'. To print the WFDB Programmer's Guide, type `make pg'. # _____________________________________________________________________________ # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables @@ -144,7 +147,7 @@ VDEFS = -DWFDB_MAJOR=$(MAJOR) -DWFDB_MINOR=$(MINOR) -DWFDB_RELEASE=$(RELEASE) # _____________________________________________________________________________ -PACKAGE=wfdb-10.2.5 +PACKAGE=wfdb-10.2.6 # file: linux.def G. Moody 31 May 2000 # Last revised: 17 December 2001 # 'make' definitions for compiling the WFDB Software Package under Linux @@ -266,8 +269,8 @@ lib-post-uninstall: echo "Nothing to be done for lib-post-uninstall" # _____________________________________________________________________________ -# file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 20 December 2001 +# file: Makefile.tpl G. Moody 24 May 2000 +# Last revised: 11 March 2002 # Change the settings below as appropriate for your setup. # Set COLORS to 'color' if you have a color printer and would like to print @@ -332,7 +335,8 @@ MAN7 = $(MANDIR)/man7 # If you want to put the man pages somewhere else, edit 'maninst.sh' first. -# PERL is the full pathname of your perl interpreter, needed for 'make htmlpg'. +# PERL is the full pathname of your perl interpreter, needed for +# 'make wpg.html'. PERL = /usr/bin/perl # PSPRINT is the name of the program that prints PostScript files. If your @@ -342,7 +346,7 @@ PSPRINT = lpr # TROFF is the name of the program that prints UNIX troff files (needed to -# 'make ag' and for the covers of the guides). Use 'groff' if you have +# 'make wag-book' and for the covers of the guides). Use 'groff' if you have # GNU groff (the preferred formatter). TROFF = groff # Use 'ptroff' if you have Adobe TranScript software. diff -Naur wfdb-10.2.5/doc/Makefile.top wfdb-10.2.6/doc/Makefile.top --- wfdb-10.2.5/doc/Makefile.top Tue Dec 18 14:16:58 2001 +++ wfdb-10.2.6/doc/Makefile.top Sat Jun 1 14:51:43 2002 @@ -1,10 +1,10 @@ # file: Makefile G. Moody 24 June 1989 -# Last revised: 18 December 2001 +# Last revised: 11 March 2002 # `make' description file for WFDB software documentation # # ----------------------------------------------------------------------------- # WFDB applications: programs for working with annotated signals -# Copyright (C) 2001 George B. Moody +# Copyright (C) 2002 George B. Moody # # These programs are free software; you can redistribute them and/or modify # them under the terms of the GNU General Public License as published by the @@ -69,25 +69,28 @@ # of available formats and the commands needed to produce them: # WFDB Applications Guide -# printed copy 'make ag' (requires troff, tbl, latex, dvips, & a printer) -# HTML 'make ag.html' (requires rman, latex2html, and perl) -# man pages 'make ag.man' -# PDF 'make ag.pdf' (requires troff, tbl, latex, dvips, and ps2pdf) -# PostScript 'make ag.ps' (requires troff, tbl, latex, and dvips) -# +# printed copy 'make wag-book' (requires troff, tbl, latex, dvips, a printer) +# HTML 'make wag.html' (requires rman, latex2html, and perl) +# man pages 'make wag.man' +# PDF 'make wag.pdf' (requires troff, tbl, latex, dvips, and ps2pdf) +# PostScript 'make wag.ps' (requires troff, tbl, latex, dvips, ps2pdf, and +# pdftops *) # WFDB Programmer's Guide -# printed copy 'make pg' (requires troff, texi2dvi, dvips, & a printer) -# Windows help 'make pg.hlp' (requires makertf and hcrtf) -# HTML 'make pg.html' (requires texi2html and perl) -# info 'make pg.info' (requires makeinfo or GNU emacs) -# PDF 'make pg.pdf' (requires texi2dvi) -# PostScript 'make pg.ps' (requires texi2dvi and dvips) +# printed copy 'make wpg-book' (requires troff, texi2dvi, dvips, & a printer) +# Windows help 'make wpg.hlp' (requires makertf and hcrtf) +# HTML 'make wpg.html' (requires texi2html and perl) +# info 'make wpg.info' (requires makeinfo or GNU emacs) +# PDF 'make wpg.pdf' (requires texi2dvi) +# PostScript 'make wpg.ps' (requires texi2dvi and dvips) # # WAVE User's Guide -# printed copy 'make ug' (requires troff, latex, dvips, and a printer) -# HTML 'make ug.html' (requires latex2html and perl) -# PDF 'make ug.pdf' (requires pdflatex) -# PostScript 'make ug.ps' (requires latex and dvips) +# printed copy 'make wug-book' (requires troff, latex, dvips, and a printer) +# HTML 'make wug.html' (requires latex2html and perl) +# PDF 'make wug.pdf' (requires pdflatex) +# PostScript 'make wug.ps' (requires latex and dvips) + +# * See 'wag-src/Makefile' for information about making a PostScript version +# of the WFDB Applications Guide without the use of ps2pdf or pdftops. # If GNU emacs or GNU info has been installed on your system, a hypertext # version of the WFDB Programmer's Guide may be installed by typing `make diff -Naur wfdb-10.2.5/doc/Makefile.tpl wfdb-10.2.6/doc/Makefile.tpl --- wfdb-10.2.5/doc/Makefile.tpl Thu Dec 20 18:27:51 2001 +++ wfdb-10.2.6/doc/Makefile.tpl Mon Jun 24 10:19:00 2002 @@ -1,5 +1,5 @@ -# file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 20 December 2001 +# file: Makefile.tpl G. Moody 24 May 2000 +# Last revised: 11 March 2002 # Change the settings below as appropriate for your setup. # Set COLORS to 'color' if you have a color printer and would like to print @@ -64,7 +64,8 @@ MAN7 = $(MANDIR)/man7 # If you want to put the man pages somewhere else, edit 'maninst.sh' first. -# PERL is the full pathname of your perl interpreter, needed for 'make htmlpg'. +# PERL is the full pathname of your perl interpreter, needed for +# 'make wpg.html'. PERL = /usr/bin/perl # PSPRINT is the name of the program that prints PostScript files. If your @@ -74,7 +75,7 @@ PSPRINT = lpr # TROFF is the name of the program that prints UNIX troff files (needed to -# 'make ag' and for the covers of the guides). Use 'groff' if you have +# 'make wag-book' and for the covers of the guides). Use 'groff' if you have # GNU groff (the preferred formatter). TROFF = groff # Use 'ptroff' if you have Adobe TranScript software. diff -Naur wfdb-10.2.5/doc/README wfdb-10.2.6/doc/README --- wfdb-10.2.5/doc/README Sun Mar 10 17:07:18 2002 +++ wfdb-10.2.6/doc/README Mon Jun 24 09:59:40 2002 @@ -1,5 +1,5 @@ file: README G. Moody 7 September 1989 - Last revised: 10 March 2002 + Last revised: 24 June 2002 This directory and its subdirectories contain documentation for the WFDB Software Package, including UNIX man pages in troff source format for the WFDB @@ -10,12 +10,12 @@ installed on-line by following the instructions in `Makefile'. If you follow the instructions for a standard installation of the WFDB Software -Package, the man pages from the wfdb-apps subdirectory will be installed so -they can be read using 'man', 'xman', etc. If you have the necessary -formatting software, these man pages and a large amount of other documentation -can be produced in a wide variety of formats from the sources in in this -directory (see 'Makefile'). Here is a brief list of available formats and the -commands needed to produce them: +Package, the man pages from the wag-src subdirectory will be installed so they +can be read using 'man', 'xman', etc. If you have the necessary formatting +software, these man pages and a large amount of other documentation can be +produced in a wide variety of formats from the sources in in this directory +(see 'Makefile'). Here is a brief list of available formats and the commands +needed to produce them: WFDB Applications Guide printed copy 'make wag-book'(requires troff, tbl, latex, dvips, & a printer) @@ -34,7 +34,7 @@ WAVE User's Guide printed copy 'make wug-book'(requires troff, latex, dvips, and a printer) - HTML 'make wug.html'(requires latex2html and perl) + HTML 'make wug.html'(requires latex2html and perl) ** PDF 'make wug.pdf' (requires pdflatex) PostScript 'make wug.ps' (requires latex and dvips) @@ -45,6 +45,13 @@ references properly. If you encounter errors while attempting to make wpg.pdf, try replacing pdflatex's copy of texinfo.tex with a version dated June 2001 or later. This problem occurs under Red Hat Linux 7.2. + +** Recent versions of Red Hat Linux have included several different versions + of latex2html and of the utilities it uses, with a variety of bugs in the + image-generation process. If some of the images generated using 'make + wug.html' have a black border at the left and lower edges, replace + /usr/bin/pstoimg with the version found in wug-src/wave/misc and try again. + These problems occur under Red Hat Linux 7.1, 7.2, and 7.3. The following files will be found in this directory: diff -Naur wfdb-10.2.5/doc/wag-src/Makefile wfdb-10.2.6/doc/wag-src/Makefile --- wfdb-10.2.5/doc/wag-src/Makefile Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/doc/wag-src/Makefile Mon Jun 24 22:43:07 2002 @@ -59,12 +59,12 @@ # PostScript 'make wag.ps' (requires troff, tbl, latex, and dvips) # _____________________________________________________________________________ # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables @@ -72,7 +72,7 @@ VDEFS = -DWFDB_MAJOR=$(MAJOR) -DWFDB_MINOR=$(MINOR) -DWFDB_RELEASE=$(RELEASE) # _____________________________________________________________________________ -PACKAGE=wfdb-10.2.5 +PACKAGE=wfdb-10.2.6 # file: linux.def G. Moody 31 May 2000 # Last revised: 17 December 2001 # 'make' definitions for compiling the WFDB Software Package under Linux @@ -195,7 +195,7 @@ echo "Nothing to be done for lib-post-uninstall" # _____________________________________________________________________________ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 20 December 2001 +# Last revised: 24 June 2002 # Change the settings below as appropriate for your setup. # D2PARGS is a list of options for dvips. Uncomment one of these to set the @@ -263,6 +263,31 @@ # Use the following definition to get the GNU groff version of the 'ms' macros. TMS = -mgs +# WAGPSREQ is the target that must be made in order to make the PostScript +# version of the manual (wag.ps), and MAKEWAGPS is the command that must be +# run in order to do this. The process is a bit convoluted, because the +# simple PostScript version (wag0.ps) is concatenated from several PostScript +# files and thus lacks DSCs (document structuring comments). wag0.ps can be +# printed or viewed directly, but most (perhaps all) viewers are incapable of +# allowing the user to jump to a random page in a PostScript file that lacks +# DSCs, and it's not easy to select a subset of pages to print in such a +# file. If you have ghostscript version 7.x or later (earlier versions will +# not work properly), ps2pdf (included with ghostscript) and acroread (or +# pdftops), you can translate wag0.ps into PDF (adding the DSCs in the +# process), and then translate the PDF file back into PostScript with DSCs. +# A disadvantage of this is that the PDF version is roughly 25% larger than +# wag0.ps, and the final PostScript version is nearly twice as large as +# wag0.ps, and takes longer to render as a result. To enable creation of +# PostScript with DSCs in this way, uncomment the next two lines: +WAGPSREQ = wag.pdf +MAKEWAGPS = acroread -toPostScript wag.pdf +# You can use pdftops instead of acroread by commenting out the previous line +# and uncommenting the next one. +# MAKEWAGPS = pdftops wag.pdf +# Otherwise, uncomment the next two lines instead: +# WAGPSREQ = wag0.ps +# MAKEWAGPS = cp wag0.ps wag.ps + # It should not be necessary to modify anything below this line. # ----------------------------------------------------------------------------- @@ -282,9 +307,9 @@ rm -f ../wag/* # 'make wag-book': print a copy of the WFDB Applications Guide -wag-book: wag.ps +wag-book: wag0.ps $(TROFF) wag.cover >wagcover.ps - $(PSPRINT) wagcover.ps wag.ps + $(PSPRINT) wagcover.ps wag0.ps # 'make wag.html': format the WFDB Applications Guide as HTML wag.html: @@ -322,22 +347,25 @@ $(LN) $(MAN1)/view.1 $(MAN1)/vsetup.1 # 'make wag.pdf': format the WFDB Applications Guide as PDF -wag.pdf: wag.ps - ps2pdf wag.ps wag.pdf - # The PDF produced this way is not so great -- a better way - # of generating PDF will be implemented in the future +wag.pdf: wag0.ps + ps2pdf wag0.ps wag.pdf + +# 'make wag.ps': format the WFDB Applications Guide as PostScript +wag.ps: $(WAGPSREQ) + $(MAKEWAGPS) -# 'make ag.ps': format the WFDB Applications Guide as PostScript -wag.ps: +wag0.ps: latex wag dvips -o wag1.ps wag.dvi tbl appguide.int | $(TROFF) $(TMS) >wag2.ps tbl *.1 *.3 *.5 | $(TROFF) $(TMAN) >wag3.ps + latex blankpage + dvips $(D2PARGS) -o blankpage.ps blankpage.dvi latex install dvips $(D2PARGS) -o wag4.ps install.dvi latex eval dvips $(D2PARGS) -o wag5.ps eval.dvi - cat wag[12345].ps | grep -v '^%%' >wag.ps + cat wag[123].ps blankpage.ps wag4.ps blankpage.ps wag5.ps | grep -v '^%%' >wag0.ps # 'make clean': remove intermediate and backup files clean: diff -Naur wfdb-10.2.5/doc/wag-src/Makefile.tpl wfdb-10.2.6/doc/wag-src/Makefile.tpl --- wfdb-10.2.5/doc/wag-src/Makefile.tpl Thu Dec 20 15:10:28 2001 +++ wfdb-10.2.6/doc/wag-src/Makefile.tpl Mon Jun 24 20:06:36 2002 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 20 December 2001 +# Last revised: 24 June 2002 # Change the settings below as appropriate for your setup. # D2PARGS is a list of options for dvips. Uncomment one of these to set the @@ -67,6 +67,31 @@ # Use the following definition to get the GNU groff version of the 'ms' macros. TMS = -mgs +# WAGPSREQ is the target that must be made in order to make the PostScript +# version of the manual (wag.ps), and MAKEWAGPS is the command that must be +# run in order to do this. The process is a bit convoluted, because the +# simple PostScript version (wag0.ps) is concatenated from several PostScript +# files and thus lacks DSCs (document structuring comments). wag0.ps can be +# printed or viewed directly, but most (perhaps all) viewers are incapable of +# allowing the user to jump to a random page in a PostScript file that lacks +# DSCs, and it's not easy to select a subset of pages to print in such a +# file. If you have ghostscript version 7.x or later (earlier versions will +# not work properly), ps2pdf (included with ghostscript) and acroread (or +# pdftops), you can translate wag0.ps into PDF (adding the DSCs in the +# process), and then translate the PDF file back into PostScript with DSCs. +# A disadvantage of this is that the PDF version is roughly 25% larger than +# wag0.ps, and the final PostScript version is nearly twice as large as +# wag0.ps, and takes longer to render as a result. To enable creation of +# PostScript with DSCs in this way, uncomment the next two lines: +WAGPSREQ = wag.pdf +MAKEWAGPS = acroread -toPostScript wag.pdf +# You can use pdftops instead of acroread by commenting out the previous line +# and uncommenting the next one. +# MAKEWAGPS = pdftops wag.pdf +# Otherwise, uncomment the next two lines instead: +# WAGPSREQ = wag0.ps +# MAKEWAGPS = cp wag0.ps wag.ps + # It should not be necessary to modify anything below this line. # ----------------------------------------------------------------------------- @@ -86,9 +111,9 @@ rm -f ../wag/* # 'make wag-book': print a copy of the WFDB Applications Guide -wag-book: wag.ps +wag-book: wag0.ps $(TROFF) wag.cover >wagcover.ps - $(PSPRINT) wagcover.ps wag.ps + $(PSPRINT) wagcover.ps wag0.ps # 'make wag.html': format the WFDB Applications Guide as HTML wag.html: @@ -126,22 +151,25 @@ $(LN) $(MAN1)/view.1 $(MAN1)/vsetup.1 # 'make wag.pdf': format the WFDB Applications Guide as PDF -wag.pdf: wag.ps - ps2pdf wag.ps wag.pdf - # The PDF produced this way is not so great -- a better way - # of generating PDF will be implemented in the future +wag.pdf: wag0.ps + ps2pdf wag0.ps wag.pdf + +# 'make wag.ps': format the WFDB Applications Guide as PostScript +wag.ps: $(WAGPSREQ) + $(MAKEWAGPS) -# 'make ag.ps': format the WFDB Applications Guide as PostScript -wag.ps: +wag0.ps: latex wag dvips -o wag1.ps wag.dvi tbl appguide.int | $(TROFF) $(TMS) >wag2.ps tbl *.1 *.3 *.5 | $(TROFF) $(TMAN) >wag3.ps + latex blankpage + dvips $(D2PARGS) -o blankpage.ps blankpage.dvi latex install dvips $(D2PARGS) -o wag4.ps install.dvi latex eval dvips $(D2PARGS) -o wag5.ps eval.dvi - cat wag[12345].ps | grep -v '^%%' >wag.ps + cat wag[123].ps blankpage.ps wag4.ps blankpage.ps wag5.ps | grep -v '^%%' >wag0.ps # 'make clean': remove intermediate and backup files clean: diff -Naur wfdb-10.2.5/doc/wag-src/ann2rr.1 wfdb-10.2.6/doc/wag-src/ann2rr.1 --- wfdb-10.2.5/doc/wag-src/ann2rr.1 Tue Jan 15 15:20:44 2002 +++ wfdb-10.2.6/doc/wag-src/ann2rr.1 Sat Jun 1 15:05:39 2002 @@ -12,7 +12,7 @@ .PP Use \fBann2rr\fR to extract a list of intervals, in text format, from an annotation file. By default, the intervals are listed in units of sample -intervals (use \fBsampfreq\fR(1) to determine the sampling frequency of the +intervals (use \fIsampfreq\fR(1) to determine the sampling frequency of the input record if necessary). Options for \fBann2rr\fR include: .TP \fB-c\fR @@ -85,7 +85,7 @@ Multiply input by \fIn\fR to obtain intervals (or, if \fB-T\fR is also used, times of occurrence) in units of sample intervals). Default: \fIn\fR = 1. .PP -Note that \fBwrann\fR(1) also provides a way to generate an annotation file from +Note that \fIwrann\fR(1) also provides a way to generate an annotation file from text. Unlike that of \fBrr2ann\fR, \fBwrann\fR's input format permits specifying annotation types and other fields in addition to the times of occurrence. .PP diff -Naur wfdb-10.2.5/doc/wag-src/appguide.int wfdb-10.2.6/doc/wag-src/appguide.int --- wfdb-10.2.5/doc/wag-src/appguide.int Thu Dec 20 14:03:23 2001 +++ wfdb-10.2.6/doc/wag-src/appguide.int Mon Jun 24 16:17:13 2002 @@ -1,5 +1,5 @@ \" file: appguide.int G. Moody July 1989 -\" Last revised: 15 November 2001 +\" Last revised: 1 June 2002 \" Table of contents and introduction to the WFDB Applications Guide. \" \" To print this document using GNU groff, use: @@ -42,58 +42,59 @@ fir general-purpose FIR filter for WFDB records 17 hrfft, hrlomb, hrmem, hrplot calculate and plot heart rate power spectra 19 ihr calculate instantaneous heart rate 21 -log10 calculate common logarithms of two-column data 22 -lomb estimate power spectrum using the Lomb periodogram method 23 -memse estimate power spectrum using maximum entropy (all poles) method 24 -mfilt general-purpose median filter for WFDB records 26 -mrgann merge annotation files 27 -mxm ANSI/AAMI-standard measurement-by-measurement comparator 29 -nst noise stress test for ECG analysis programs 31 -plot2d, plot3d make 2-D or 3-D plots from text files of data, using \fIgnuplot\fR 34 -plotstm produce scatter plot of ST measurement errors on a PostScript device 36 -plt make 2-D plots 37 -pschart produce annotated `chart recordings' on a PostScript device 42 -psfd produce annotated `full-disclosure' plots on a PostScript device 46 -rdann read a WFDB annotation file 50 -rdsamp read WFDB signal files 52 -rxr ANSI/AAMI-standard run-by-run annotation comparator 53 -sampfreq show sampling frequency for a record 55 -sample digitize and replay analog signals (MS-DOS only) 56 -setwfdb, cshsetwfdb set WFDB environment variables 60 -sigamp measure signal amplitudes of a WFDB record 62 -skewedit edit skew fields of header file(s) 63 -snip copy an excerpt of a WFDB record 64 -sortann rearrange annotations in canonical order 65 -sqrs, sqrs125 single-channel QRS detector 67 -sumann summarize the contents of a WFDB annotation file 69 -sumstats derive aggregate statistics from bxb, rxr, etc., line-format output 70 -tach heart rate tachometer 71 -view, vsetup WFDB browser for MS-DOS 73 -wave waveform analyzer, viewer, and editor for the X Window System 76 -wfdbcat copy WFDB records to standard output 86 -wfdbcollate collate WFDB records into a multi-segment record 87 -wfdbdesc read signal specifications 89 -wfdbwhich find a WFDB file and print its pathname 90 -wrann write a WFDB annotation file 91 -wrsamp write WFDB signal files 92 -wview WFDB browser for MS Windows 94 -xform sampling frequency, amplitude, and format conversion for WFDB records 98 +log10 calculate common logarithms of two-column data 23 +lomb estimate power spectrum using the Lomb periodogram method 24 +memse estimate power spectrum using maximum entropy (all poles) method 25 +mfilt general-purpose median filter for WFDB records 27 +mrgann merge annotation files 28 +mxm ANSI/AAMI-standard measurement-by-measurement comparator 30 +nst noise stress test for ECG analysis programs 32 +plot2d, plot3d make 2-D or 3-D plots from text files of data, using \fIgnuplot\fR 35 +plotstm produce scatter plot of ST measurement errors on a PostScript device 37 +plt make 2-D plots 38 +pschart produce annotated `chart recordings' on a PostScript device 43 +psfd produce annotated `full-disclosure' plots on a PostScript device 47 +rdann read a WFDB annotation file 51 +rdsamp read WFDB signal files 53 +rxr ANSI/AAMI-standard run-by-run annotation comparator 54 +sampfreq show sampling frequency for a record 56 +sample digitize and replay analog signals (MS-DOS only) 57 +setwfdb, cshsetwfdb set WFDB environment variables 61 +sigamp measure signal amplitudes of a WFDB record 63 +skewedit edit skew fields of header file(s) 64 +snip copy an excerpt of a WFDB record 65 +sortann rearrange annotations in canonical order 66 +sqrs, sqrs125 single-channel QRS detector 68 +sumann summarize the contents of a WFDB annotation file 70 +sumstats derive aggregate statistics from bxb, rxr, etc., line-format output 71 +tach heart rate tachometer 72 +view, vsetup WFDB browser for MS-DOS 74 +wave waveform analyzer, viewer, and editor for the X Window System 77 +wfdbcat copy WFDB records to standard output 87 +wfdbcollate collate WFDB records into a multi-segment record 88 +wfdb-config print WFDB library info 90 +wfdbdesc read signal specifications 91 +wfdbwhich find a WFDB file and print its pathname 92 +wrann write a WFDB annotation file 93 +wrsamp write WFDB signal files 94 +wview WFDB browser for MS Windows 96 +xform sampling frequency, amplitude, and format conversion for WFDB records 100 \fBSection 3: WFDB library\fP -wfdb Waveform Database library 100 - +wfdb Waveform Database library 102 +wfdbf Waveform Database library wrappers for Fortran 105 \fBSection 5: WFDB file formats\fP -annot WFDB annotation file formats 103 -header WFDB header file format 104 -signal WFDB signal file formats 111 -wfdbcal WFDB calibration file format 113 +annot WFDB annotation file formats 108 +header WFDB header file format 109 +signal WFDB signal file formats 116 +wfdbcal WFDB calibration file format 118 \fBAppendices\fP - \fIInstalling the WFDB Software Package\fP 115 - \fIEvaluating ECG Analyzers\fP 119 + \fIInstalling the WFDB Software Package\fP 121 + \fIEvaluating ECG Analyzers\fP 125 .TE .LP @@ -128,21 +129,36 @@ Certain types of command arguments are used by many of the applications described in this guide. These include: .IP \fIrecord\fP 15 -Where this appears, substitute the name of a WFDB record. MIT-BIH Arrhythmia -Database record names are 3-digit numbers, AHA Database record names are -4-digit numbers, and European ST-T Database record names begin with lowercase -`e', followed by a 4-digit number. Record names may contain letters, digits, -and underscores. Case is significant in record names that contain letters, -even in environments such as MS-Windows for which case translation is normally -performed by the operating system on file names; thus `e0104' is the name -of a record found in the European ST-T Database, whereas `E0104' is not. -A record name is \fInot\fP a file name. See the \fIWFDB Programmer's Guide\fP -for further details on record names. +Where this appears, substitute the name of a WFDB record. \fBA record +name is \fInot\fB a file name!\fR The first part of the name of a .hea +file is the name of the record to which the .hea file belongs; so the +record name corresponding to `100.hea' is `100'. MIT-BIH Arrhythmia +Database record names are 3-digit numbers, AHA Database record names +are 4-digit numbers, and European ST-T Database record names begin +with lowercase `e', followed by a 4-digit number. Record names may +contain letters, digits, and underscores. Case is significant in +record names that contain letters, even in environments such as +MS-Windows for which case translation is normally performed by the +operating system on file names; thus `e0104' is the name of a record +found in the European ST-T Database, whereas `E0104' is not. Once +again: a record name is \fBnot\fP a file name; record names never +include an extension (.hea, .dat, etc.). +.PP +Wherever a record name can be supplied to a WFDB application, you may include +path information if necessary. For example, if the WFDB path includes the +current directory, and if the current directory includes a subdirectory named +`my_records', and that directory contains a record named `record_23', you +can supply `my_records/record_23' in place of a record name. See the \fIWFDB +Programmer's Guide\fP for further details on record names. .IP \fIannotator\fP -Where this appears, substitute an annotator name. The annotator name -`atr' is used to name the set of \fIreference annotations\fP supplied by -the database developers. Annotator names may contain letters, digits, and -underscores, as for record names. +Where this appears, substitute an annotator name. \fBAnnotator names +are \fInot\fB file names!\fR The suffix (extension) of the name of an +annotation file is the annotator name for that file; so, for example, +the annotator name for `e0104.atr' is `atr'. The special annotator +name `atr' is used to name the set of \fIreference annotations\fP +supplied by the database developers. Other annotation sets have +annotator names that may contain letters, digits, and underscores, as +for record names. .IP \fItime\fP Where this appears, substitute a string in \fIstandard time format\fP. \fITime\fP arguments generally specify elapsed times from the beginning @@ -166,12 +182,15 @@ beneath, etc. Where the notation `\fIsignal-list\fP' (or `\fIsignal ...\fP') appears in this guide, you may specify more than one signal in any desired order; separate the signal numbers using spaces. -.bp .PP -Under UNIX, if the WFDB Software Package has been installed on your -system, you can also access the information contained in this guide -using \fIman\fR and related programs. In some cases you may need -to add \fB/usr/local/man\fR to your \fBMANPATH\fR environment variable, in +Under Linux or Unix, if the WFDB Software Package has been installed +on your system, you can also access the information contained in the +main sections of this guide using \fIman\fR and related programs. For +example, to see the manual page for \fIrdsamp\fR, run the command `man +rdsamp'. (This also works under MS-Windows if you have installed the +Cygwin package, which includes the \fIman\fR utility for formatting +and reading manual pages.) In some cases you may need to add +\fB/usr/local/man\fR to your \fBMANPATH\fR environment variable, in order to make these pages accessible to \fIman\fR. .PP An HTML version of this guide is also available; point your Web browser to diff -Naur wfdb-10.2.5/doc/wag-src/blankpage.tex wfdb-10.2.6/doc/wag-src/blankpage.tex --- wfdb-10.2.5/doc/wag-src/blankpage.tex Wed Dec 31 19:00:00 1969 +++ wfdb-10.2.6/doc/wag-src/blankpage.tex Sat Jun 1 14:01:47 2002 @@ -0,0 +1,8 @@ +\documentclass{article} +\usepackage{rawfonts} +\IfFileExists{times.sty}{\usepackage{times}}{\@missingfileerror{times}{sty}} +\pagestyle{empty} +\begin{document} +\newpage +\center{[This page intentionally left blank.]} +\end{document} diff -Naur wfdb-10.2.5/doc/wag-src/eval.tex wfdb-10.2.6/doc/wag-src/eval.tex --- wfdb-10.2.5/doc/wag-src/eval.tex Thu Dec 20 14:03:13 2001 +++ wfdb-10.2.6/doc/wag-src/eval.tex Sat Jun 1 14:07:04 2002 @@ -1,4 +1,6 @@ \documentclass[twoside]{article} +\usepackage{rawfonts} +\IfFileExists{times.sty}{\usepackage{times}}{\@missingfileerror{times}{sty}} \oddsidemargin 0.1in \evensidemargin -0.1in \def\textwidth{6.375 in} @@ -9,7 +11,7 @@ \date{} \begin{document} -\setcounter{page}{119} +\setcounter{page}{125} \maketitle diff -Naur wfdb-10.2.5/doc/wag-src/fixag.sed wfdb-10.2.6/doc/wag-src/fixag.sed --- wfdb-10.2.5/doc/wag-src/fixag.sed Tue Dec 18 16:52:32 2001 +++ wfdb-10.2.6/doc/wag-src/fixag.sed Mon Jun 24 20:16:49 2002 @@ -1,4 +1,5 @@ s/sampfreq-1.htm/sampfr-1.htm/g +s/wfdbcal-5.htm/wfdbca-5.htm/g s/wfdbwhich-1.htm/wfdbwh-1.htm/g s/sumstats-1.htm/sumsta-1.htm/g s/ecgeval-1.htm/ecgeva-1.htm/g @@ -7,15 +8,34 @@ s/wfdbcollate-1.htm/wfdbco-1.htm/g s/plotstm-1.htm/plotst-1.htm/g s/setwfdb-1.htm/setwfd-1.htm/g +s/wfdb-config-1.htm/wfdb-c-1.htm/g +s/cc<\/I>(1)<\/A>/cc<\/I>(1)/g +s/gcc<\/I>(1)<\/A>/gcc<\/I>(1)/g +s/ld<\/I>(1)<\/A>/ld<\/I>(1)/g s/scanf<\/I>(3)<\/A>/scanf<\/I>(3)/g s/fseek<\/I>(3)<\/A>/fseek<\/I>(3)/g s/gnuplot<\/I>(1)<\/A>/gnuplot<\/I>(1)/g s/plot<\/I>(1)<\/A>/plot<\/I>(1)/g s/plot<\/I>(3)<\/A>/plot<\/I>(3)/g s/X<\/I>(1)<\/A>/X<\/I>(1)/g -s/xview<\/I>(1)<\/A>/xview<\/I>(1)/g s/sh<\/I>(1)<\/A>/sh<\/I>(1)/g +s/xview<\/I>(1)<\/A>/xview<\/I>(1)/g +s/F(n)<\/I><\/A>/F(n)<\/I>/g +s/F(n)<\/A>/F(n)/g +s/osigfopen(nsig)<\/A>/osigfopen(nsig)/g +s/N (1)<\/A>/N (1)/g +s/N (2)<\/A>/N (2)/g +s/N (3)<\/A>/N (3)/g +s/N (4)<\/A>/N (4)/g +s/N (8)<\/A>/N (8)/g +s/iconedit<\/B>(1)<\/A>/iconedit<\/B>(1)/g +s/openwin<\/B>(1)<\/A>/openwin<\/B>(1)/g +s/xdpyinfo<\/B>(1)<\/A>/xdpyinfo<\/B>(1)/g s/xdpyinfo<\/I>(1)<\/A>/xdpyinfo<\/I>(1)/g +s/xhost<\/B>(1)<\/A>/xhost<\/B>(1)/g +s/xlsfonts<\/B>(1)<\/A>/xlsfonts<\/B>(1)/g +s/xmodmap<\/B>(1)<\/A>/xmodmap<\/B>(1)/g +s/xnews<\/B>(1)<\/A>/xnews<\/B>(1)/g s/\n<\/BODY>/<\/UL>\n



\nGeorge B. Moody (george@mit.edu<\tt>)<\/A>\n<\/ADDRESS><\I>\n<\/BODY>/ s//WFDB Applications Guide<\/A>/ diff -Naur wfdb-10.2.5/doc/wag-src/install.tex wfdb-10.2.6/doc/wag-src/install.tex --- wfdb-10.2.5/doc/wag-src/install.tex Thu Dec 20 14:02:41 2001 +++ wfdb-10.2.6/doc/wag-src/install.tex Sat Jun 1 14:10:00 2002 @@ -1,4 +1,6 @@ \documentclass[twoside]{article} +\usepackage{rawfonts} +\IfFileExists{times.sty}{\usepackage{times}}{\@missingfileerror{times}{sty}} \oddsidemargin 0.1in \evensidemargin -0.1in \def\textwidth{6.375 in} @@ -9,7 +11,7 @@ \date{} \begin{document} -\setcounter{page}{115} +\setcounter{page}{121} \maketitle @@ -84,7 +86,7 @@ \subsection*{MS-Windows} If you have not already done so, install the Cygwin development environment -(freely available from {\tt http://sources.redhat.com/cygwin/}). This includes +(freely available from {\tt http://\-sources.\-red\-hat.\-com/\-cygwin/}). This includes {\tt gcc} (the GNU C/C++ compiler) as well as a comprehensive assortment of other Unix utilities ported to MS-Windows. Accept the defaults suggested by the installer. @@ -184,6 +186,4 @@ The UNIX and MS-DOS {\tt make} description files ({\tt Makefile} and {\tt Makefile.dos} in {\tt wfdb} and in each of its subdirectories) should get you started. -\newpage -\center{[This page intentionally left blank.]} \end{document} diff -Naur wfdb-10.2.5/doc/wag-src/intro.ht0 wfdb-10.2.6/doc/wag-src/intro.ht0 --- wfdb-10.2.5/doc/wag-src/intro.ht0 Tue Oct 16 22:53:00 2001 +++ wfdb-10.2.6/doc/wag-src/intro.ht0 Mon Jun 24 14:44:47 2002 @@ -4,7 +4,7 @@

-Up: WFDB Applications Guide +Up: WFDB Applications Guide

Introduction

@@ -30,16 +30,19 @@ your environment is set up properly so that WFDB applications can find their input files. See setwfdb(1) for information about doing this; a more detailed discussion may be found in the first chapter of -the WFDB Programmer's Guide, in -the section about the database path. +the WFDB Programmer's Guide, in +the section about the database path.

Certain types of command arguments are used by many of the applications described in this guide. These include:

record -
Where this appears, substitute the name of a WFDB record. MIT-BIH -Arrhythmia Database record names are 3-digit numbers, AHA Database +
Where this appears, substitute the name of a WFDB record. A record +name is not a file name! The first part of the name of a +.hea file is the name of the record to which the .hea file +belongs; so the record name corresponding to 100.hea is 100. +MIT-BIH Arrhythmia Database record names are 3-digit numbers, AHA Database record names are 4-digit numbers, and European ST-T Database record names begin with lowercase `e', followed by a 4-digit number. Record names may contain letters, digits, and underscores. Case is @@ -47,22 +50,34 @@ such as MS-Windows for which case translation is normally performed by the operating system on file names; thus `e0104' is the name of a record found in the European ST-T Database, whereas `E0104' is not. -A record name is not a file name. See the -WFDB Programmer's Guide for -further details on record names. +Once again: a record name is not a file name; record names +never include an extension (.hea, .dat, etc.). +

+Wherever a record name can be supplied to a WFDB application, you may include +path information if necessary. For example, if the WFDB path includes the +current directory, and if the current directory includes a subdirectory named +my_records, and that directory contains a record named +record_23, you can supply my_records/record_23 in place of a +record name. See the WFDB Programmer's +Guide for further details on record +names.

annotator -
Where this appears, substitute an annotator name. The annotator name +
Where this appears, substitute an annotator name. Annotator names are +not file names! The suffix (extension) of the name of an annotation +file is the annotator name for that file; so, for example, the annotator name +for `e0104.atr' is `atr'. The special annotator name `atr' is used to name the set of reference annotations -supplied by the database developers. Annotator names may contain letters, -digits, and underscores, as for record names. +supplied by the database developers. Other annotation sets have annotator +names that may contain letters, digits, and underscores, as for record names.
time
Where this appears, substitute a string in standard time format. Time arguments generally specify elapsed times from the beginning of the record (for exceptions to this rule, see the section on the -strtim function in the -WFDB Programmer's Guide). Examples of standard time format: +strtim function in the +WFDB Programmer's Guide). Examples of +standard time format: @@ -83,11 +98,14 @@

-Under UNIX, if the WFDB Software Package has been installed on your +Under Linux or UNIX, if the WFDB Software Package has been installed on your system, you can also access the information contained in this guide -using man and related programs. In some cases you may need -to add /usr/local/man to your MANPATH environment variable, -in order to make these pages accessible to man. +using man and related programs. For example, to see the manual +page for rdsamp, run the command man rdsamp. (This also +works under MS-Windows if you have installed the Cygwin package, which includes +the man utility for formatting and reading manual pages.) In some +cases you may need to add /usr/local/man to your MANPATH +environment variable, in order to make these pages accessible to man.


@@ -95,6 +113,6 @@ welcome. Please send them to:

George B. Moody (george@mit.edu)

-16 October 2001 +24 June 2002 diff -Naur wfdb-10.2.5/doc/wag-src/sqrs.1 wfdb-10.2.6/doc/wag-src/sqrs.1 --- wfdb-10.2.5/doc/wag-src/sqrs.1 Tue Oct 16 22:56:12 2001 +++ wfdb-10.2.6/doc/wag-src/sqrs.1 Tue May 28 11:57:50 2002 @@ -1,4 +1,4 @@ -.TH SQRS 1 "16 October 2001" "WFDB software 10.2" "WFDB applications" +.TH SQRS 1 "28 May 2002" "WFDB software 10.2" "WFDB applications" .SH NAME sqrs \- single-channel QRS detector .SH SYNOPSIS @@ -18,14 +18,24 @@ normal; the annotation file may also contain `artifact' annotations at locations that \fIsqrs\fR believes are noise-corrupted. .PP -\fIsqrs\fR can process records containing any number of signals, but it uses -only one signal for QRS detection (signal 0 by default; this can be changed -using the \fB-s\fR option, see below). For best results on adult human ECGs, -use \fIxform\fR to resample the input signal at 250 Hz if a different sampling -frequency was used originally (or use \fIsqrs125\fR, a variant of \fIsqrs\fR -designed for signals sampled at 125 Hz). For other ECGs, it may be necessary to -experiment with the input sampling frequency and the time constants indicated -in the source file. +\fIsqrs\fR can process records containing any number of signals, but +it uses only one signal for QRS detection (signal 0 by default; this +can be changed using the \fB-s\fR option, see below). \fIsqrs\fR is +optimized for use with adult human ECGs. For other ECGs, it may be +necessary to experiment with the sampling frequency as recorded in the +input record's header file (see \fIheader\fR(5)) and the time constants +indicated in the source file. +.PP +\fIsqrs\fR uses the WFDB library's \fIsetifreq\fR function to resample +the input signal at 250 Hz if a significantly different sampling frequency +is indicated in the header file. \fIsqrs125\fR is identical to \fIsqrs\fR +except that its filter and time constants have been designed for 125 Hz +input, so that its speed is roughly twice that of \fIsqrs\fR. If the input +signal has been sampled at a frequency near 125 Hz, the quality of the +outputs of \fIsqrs\fR and \fIsqrs125\fR will be nearly identical. (Note +that older versions of these programs did not resample their inputs; rather, +they warned if the sampling frequency was significantly different than the +ideal frequency, and suggested using \fIxform\fR(1) to resample the input.) .PP This program is provided as an example only, and is not intended for any clinical application. At the time the algorithm was originally published, diff -Naur wfdb-10.2.5/doc/wag-src/wag.cover wfdb-10.2.6/doc/wag-src/wag.cover --- wfdb-10.2.5/doc/wag-src/wag.cover Sun Mar 10 11:05:25 2002 +++ wfdb-10.2.6/doc/wag-src/wag.cover Sat Jun 1 14:58:03 2002 @@ -45,7 +45,7 @@ -MARCH 2002 +JUNE 2002 .bp diff -Naur wfdb-10.2.5/doc/wag-src/wag.ht0 wfdb-10.2.6/doc/wag-src/wag.ht0 --- wfdb-10.2.5/doc/wag-src/wag.ht0 Sun Mar 10 11:06:18 2002 +++ wfdb-10.2.6/doc/wag-src/wag.ht0 Mon Jun 24 14:45:37 2002 @@ -11,8 +11,8 @@ Up:Books about PhysioToolkit

WFDB Applications Guide

Tenth Edition
-(Revised for release 10.2.5)
-10 March 2002
+(Revised for release 10.2.6)
+24 June 2002



@@ -61,6 +61,7 @@

  • calsig: calibrate signals of a WFDB record
  • coherence: estimate coherence and cross-spectrum of two time series +
  • dfa: detrended fluctuation analysis
  • ecgeval: generate and run ECG analyzer evaluation script
  • epic: ANSI/AAMI-standard episode-by-episode @@ -117,6 +118,7 @@
  • wfdbcat: copy WFDB files to standard output
  • wfdbcollate: collate WFDB records into a multi-segment record +
  • wfdb-config: print WFDB library info
  • wfdbdesc: read signal specifications
  • wfdbwhich: find a WFDB file and print its pathname @@ -129,6 +131,8 @@

    Functions

    • wfdb: Waveform Database library +
    • wfdbf: Waveform Database library bindings for + Fortran

    File formats

      diff -Naur wfdb-10.2.5/doc/wag-src/wag.tex wfdb-10.2.6/doc/wag-src/wag.tex --- wfdb-10.2.5/doc/wag-src/wag.tex Thu Dec 20 13:09:56 2001 +++ wfdb-10.2.6/doc/wag-src/wag.tex Mon Jun 24 12:19:47 2002 @@ -1,10 +1,12 @@ \documentclass[twoside]{book} +\usepackage{rawfonts} +\IfFileExists{times.sty}{\usepackage{times}}{\@missingfileerror{times}{sty}} \pagenumbering{roman} \title{WFDB Applications Guide} \author{Tenth Edition\\ -(revised and with corrections for WFDB 10.2.4)\\ -20 December 2001\\ +(revised and with corrections for WFDB 10.2.6)\\ +24 June 2002\\ \\ \\ \\ @@ -18,7 +20,7 @@ \pagestyle{empty} \vspace*{\fill} \noindent -Copyright \copyright 1992 -- 2001 George B. Moody +Copyright \copyright 1992 -- 2002 George B. Moody \vspace{1 in} \noindent @@ -34,6 +36,7 @@ USA\\ \end{quote} +\noindent An HTML version of this guide is available; point your web browser to {\tt http://www.\-physio\-net.\-org/\-physio\-tools/\-wug/} to view it. diff -Naur wfdb-10.2.5/doc/wag-src/wfdb-config.1 wfdb-10.2.6/doc/wag-src/wfdb-config.1 --- wfdb-10.2.5/doc/wag-src/wfdb-config.1 Wed Dec 31 19:00:00 1969 +++ wfdb-10.2.6/doc/wag-src/wfdb-config.1 Thu May 30 14:47:24 2002 @@ -0,0 +1,35 @@ +.TH WFDB-CONFIG 1 "30 May 2002" "WFDB software 10.2.6" "WFDB applications" +.SH NAME +wfdb-config \- print WFDB library version and configuration info +.SH SYNOPSIS +\fBwfdb-config\fR [ \fB--cflags\fR ] [ \fB--libs\fR ] [ \fB--version\fR ] +.SH DESCRIPTION +This program prints information about the WFDB library installation. Use +it with one of these options: +.TP +\fB--cflags\fR +Print options needed by \fIcc\fR(1) or \fIgcc\fR(1) to find the WFDB +library's 'include' (*.h) files. +.TP +\fB--libs\fR +Print options needed by \fIcc\fR(1), \fIgcc\fR(1), or \fIld\fR(1) to find +and link a program with the WFDB library (and, if NETFILES support is +compiled into the WFDB library, with the \fIlibwww\fR libraries). +.TP +\fB--version\fR +Print the version number of the most recent version of the WFDB library +that has been installed. + +.SS Example +.PP +To compile \fIprog.c\fR with the WFDB library, use: +.br + \fBgcc `wfdb-config --cflags` prog.c `wfdb-config --libs`\fR +.br +Additional options may be added to the command if needed (for example, +to link to other libraries). + +.SH AUTHOR +George B. Moody (george@mit.edu) +.SH SOURCE +http://www.physionet.org/physiotools/wfdb/app/wfdb-config.c diff -Naur wfdb-10.2.5/doc/wag-src/wfdb.3 wfdb-10.2.6/doc/wag-src/wfdb.3 --- wfdb-10.2.5/doc/wag-src/wfdb.3 Wed Oct 31 20:48:53 2001 +++ wfdb-10.2.6/doc/wag-src/wfdb.3 Sat Jun 1 13:24:27 2002 @@ -1,4 +1,4 @@ -.TH WFDB 3 "31 October 2001" "WFDB software 10.2.1" "WFDB library" +.TH WFDB 3 "1 June 2002" "WFDB software 10.2.6" "WFDB library" .SH NAME wfdb \- Waveform Database library .SH SYNOPSIS @@ -30,6 +30,8 @@ .br WFDB_Frequency getcfreq(void) .br +WFDB_Frequency getifreq(void) +.br char *getwfdb(void) .br int getframe(WFDB_Sample *\fIvector\fP) @@ -86,6 +88,8 @@ .br void setcfreq(WFDB_Frequency \fIcounter_frequency\fP) .br +int setifreq(WFDB_Frequency \fIgetvec_frequency\fP) +.br void setwfdb(char *\fIdatabase_path_string\fP) .br int setecgstr(int \fIannotation_code\fP, char *\fIannotation_mnemonic_string\fP) @@ -177,11 +181,11 @@ .SH SEE ALSO .TP \fIWFDB Programmer's Guide\fR -(On systems that support GNU emacs, the \fIGuide\fR may be available on-line +On systems that support GNU emacs, the \fIGuide\fR may be available on-line using emacs \fIinfo\fR; from within \fIemacs\fR, type control-H followed by \fIi\fR to find out. An HTML version may be installed on your system (in -\fI/usr/help/html/dbpg\fP); the most recent version can be viewed on-line at -\fBhttp://www.physionet.org/physiotools/dbpg/\fP. +\fI/usr/help/html/wpg\fP); the most recent version can be viewed on-line at +\fBhttp://www.physionet.org/physiotools/wpg/\fP. .PP The WFDB library can also be used with Fortran programs; see the \fIGuide\fR for details. diff -Naur wfdb-10.2.5/doc/wag-src/wfdbf.3 wfdb-10.2.6/doc/wag-src/wfdbf.3 --- wfdb-10.2.5/doc/wag-src/wfdbf.3 Wed Dec 31 19:00:00 1969 +++ wfdb-10.2.6/doc/wag-src/wfdbf.3 Mon Jun 24 17:15:19 2002 @@ -0,0 +1,224 @@ +.TH WFDBF 3 "24 June 2002" "WFDB software 10.2.6" "WFDB library" +.SH NAME +wfdbf \- Waveform Database library wrappers for Fortran +.SH SYNOPSIS +implicit integer(a-z) +.br +real aduphys, getbasecount, getcfreq, getifreq, sampfreq +.br +character aux(256), desc(80), filetype(32), fname(40), name(20), pathname(80), record(16), string(32), units(20) +.br +integer a, adcres, adczero, ampl, anntyp, baseline, bsize, caltype, chan, cksum, date, dummy, fmt, group, initval, microvolts, mode, nann, nsamp, nsig, num, s, spf, stat, subtyp, time, v(32), value +.br +real gain, frequency, high, low, scale +.PP +setanninfo(a, name, stat) +.br +getsiginfo(s, fname, desc, units, gain, initval, group, fmt, spf, bsize, adcres, adczero, baseline, nsamp, cksum) +.br +setsiginfo(s, fname, desc, units, gain, initval, group, fmt, spf, bsize, adcres, adczero, baseline, nsamp, cksum) +.br +annopen(record, nann) +.br +isigopen(record, nsig) +.br +osigopen(record, nsig) +.br +osigfopen(nsig) +.br +wfdbinit(record, nann, nsig) +.br +setgvmode(mode) +.br +getspf(dummy) +.br +getvec(v) +.br +getframe(v) +.br +putvec(v) +.br +getann(a, time, anntyp, subtyp, chan, num, aux) +.br +ungetann(a, time, anntyp, subtyp, chan, num, aux) +.br +putann(a, time, anntyp, subtyp, chan, num, aux) +.br +isigsettime(time) +.br +isgsettime(group, time) +.br +iannsettime(time) +.br +ecgstr(code, string) +.br +strecg(string) +.br +setecgstr(code, string) +.br +annstr(code, string) +.br +strann(string) +.br +setannstr(code, string) +.br +anndesc(code, string) +.br +setanndesc(code, string) +.br +iannclose(a) +.br +oannclose(a) +.br +timstr(time, string) +.br +mstimstr(time, string) +.br +strtim(string) +.br +datstr(date, string) +.br +strdat(string) +.br +adumuv(s, ampl) +.br +muvadu(s, microvolts) +.br +aduphys(s, ampl) +.br +physadu(s, value) +.br +calopen(fname) +.br +getcal(desc, units, low, high, scale, caltype) +.br +putcal(desc, units, low, high, scale, caltype) +.br +newcal(fname) +.br +flushcal(dummy) +.br +getinfo(record, string) +.br +putinfo(string) +.br +newheader(record) +.br +setheader(record, nsig) +.br +wfdbgetskew(s) +.br +wfdbsetskew(s, value) +.br +wfdbgetstart(s) +.br +wfdbsetstart(s, value) +.br +wfdbquit(dummy) +.br +sampfreq(record) +.br +setsampfreq(frequency) +.br +getcfreq(dummy) +.br +setcfreq(frequency) +.br +getifreq(dummy) +.br +setifreq(frequency) +.br +getbasecount(dummy) +.br +setbasecount(frequency) +.br +setbasetime(string) +.br +wfdbquiet(dummy) +.br +wfdbverbose(dummy) +.br +wfdberror(string) +.br +setwfdb(string) +.br +getwfdb(string) +.br +setibsize(value) +.br +setobsize(value) +.br +wfdbfile(filetype, record, pathname) +.br +wfdbflush(dummy) +.br +isann(anntyp) +.br +isqrs(anntyp) +.br +setisqrs(anntyp, value) +.br +map1(anntyp) +.br +setmap1(anntyp, value) +.br +map2(anntyp) +.br +setmap2(anntyp, value) +.br +ammap(anntyp) +.br +mamap(anntyp, subtyp) +.br +annpos(anntyp) +.br +setannpos(anntyp, value) +.br + +.SH DESCRIPTION +Fortran programs can use the WFDB library to read and write waveform database +files. Differences in argument-passing conventions between Fortran and C +(the language of the WFDB library) require the use of a set of wrappers +as an interface between the library and Fortran code that invokes its +functions. These wrappers are contained within 'wfdbf.c', provided in +the 'fortran' directory of the WFDB software package. + +.PP +Most of these wrapper subroutines behave like their similarly-named +counterparts in the WFDB library. The functions setanninfo, setsiginfo, and +getsiginfo do not have direct equivalents in the WFDB library; they are +provided in order to permit Fortran programs to read and write data structures +passed to and from several of the WFDB library functions. Since the contents +of these structures are directly accessible by C programs, these functions are +not needed in the C library. + +.PP +Before using annopen, set up the annotation information structures +using setanninfo. After using isigopen or osigopen, use getsiginfo to +obtain the contents of the signal information structures if necessary. +Before using osigfopen or setheader, use setsiginfo to set the +contents of the signal information structures. Before using wfdbinit, +use setanninfo and setsiginfo to set the contents of the annotation +and signal information structures. + +.PP +To use these wrappers, call them as shown above, then compile your +code together with wfdbf.c and link to the WFDB library. If you are +using the GNU g77 compiler, do so using a command such as: +.br +g77 -o foo -fwritable-strings foo.f wfdbf.c -lwfdb +.br +See 'fortran/README' for further information about using the WFDB Fortran +wrappers. +.SH SEE ALSO +.TP +\fIWFDB Programmer's Guide\fR +On systems that support GNU emacs, the \fIGuide\fR may be available on-line +using emacs \fIinfo\fR; from within \fIemacs\fR, type control-H followed by +\fIi\fR to find out. An HTML version may be installed on your system (in +\fI/usr/help/html/wpg\fP); the most recent version can be viewed on-line at +\fBhttp://www.physionet.org/physiotools/wpg/\fP. +.SH AUTHOR +George B. Moody (george@mit.edu) +.SH SOURCES +http://www.physionet.org/physiotools/wfdb/fortran/wfdbf.c diff -Naur wfdb-10.2.5/doc/wpg/info/wpg wfdb-10.2.6/doc/wpg/info/wpg --- wfdb-10.2.5/doc/wpg/info/wpg Sun Mar 10 11:37:36 2002 +++ wfdb-10.2.6/doc/wpg/info/wpg Mon Jun 24 22:20:24 2002 @@ -3,140 +3,143 @@  Indirect: wpg-1: 62 -wpg-2: 49549 -wpg-3: 99433 -wpg-4: 149034 -wpg-5: 192519 -wpg-6: 229812 -wpg-7: 274496 -wpg-8: 298818 +wpg-2: 44729 +wpg-3: 93152 +wpg-4: 142593 +wpg-5: 191051 +wpg-6: 238508 +wpg-7: 282721 +wpg-8: 307050  Tag Table: (Indirect) Node: Top62 -Node: Overview1833 -Node: Concepts 14201 -Node: Concepts 26188 -Node: Concepts 38167 -Node: Applications10119 -Node: Guide12010 -Node: Recent changes19382 -Node: Usage28204 -Node: print samples29245 -Node: compiling30815 -Node: other languages32726 -Node: WFDB path35852 -Node: running example38525 -Node: name restrictions39155 -Node: WFDB path syntax40192 -Node: exercises 146229 -Node: Functions48634 -Node: introduction to functions49549 -Node: selecting52376 -Node: annopen52805 -Node: isigopen55410 -Node: osigopen59972 -Node: osigfopen62186 -Node: wfdbinit63842 -Node: signal and annotation I/O65127 -Node: getvec65600 -Node: getframe67494 -Node: putvec68817 -Node: getann70842 -Node: ungetann72212 -Node: putann72908 -Node: non-sequential73942 -Node: isigsettime74444 -Node: isgsettime75177 -Node: iannsettime75685 -Node: conversion76879 -Node: annstr and strann77509 -Node: timstr and strtim82445 -Node: datstr and strdat87195 -Node: aduphys and physadu88235 -Node: calibration90821 -Node: calopen91485 -Node: getcal92381 -Node: putcal93580 -Node: newcal93942 -Node: flushcal94461 -Node: miscellaneous functions94807 -Node: newheader96567 -Node: setheader97869 -Node: setmsheader99433 -Node: wfdbquit100973 -Node: iannclose and oannclose102173 -Node: wfdbquiet and wfdbverbose103064 -Node: wfdberror103554 -Node: sampfreq104545 -Node: setsampfreq105473 -Node: setbasetime106009 -Node: setgvmode106832 -Node: getspf108314 -Node: counter conversion108867 -Node: setwfdb111470 -Node: getwfdb113982 -Node: wfdbfile114706 -Node: wfdbflush115832 -Node: getinfo116127 -Node: putinfo117004 -Node: setibsize117745 -Node: setobsize118747 -Node: wfdbgetskew119769 -Node: wfdbsetskew121334 -Node: wfdbgetstart121976 -Node: wfdbsetstart123078 -Node: Data Types123716 -Node: WFDB_Siginfo structures125712 -Node: WFDB_Calinfo structures132055 -Node: WFDB_Anninfo structures134100 -Node: WFDB_Annotation structures136856 -Node: Annotation Codes139740 -Node: Mapping macros144400 -Node: Database Files146347 -Node: Header Files149034 -Node: Signal Files149901 -Node: Annotation Files150720 -Node: Calibration Files151129 -Node: AHA Format Files151894 -Node: Standard I/O153363 -Node: Multiplexed Signal Files154607 -Node: Multi-Frequency Records155788 -Node: Multi-Segment Records159038 -Node: Multiple Record Access160991 -Node: Special Files162436 -Node: Piped and Local Records165340 -Node: NETFILES167191 -Node: Annotation Order169908 -Node: Examples173311 -Node: Example 1174411 -Node: Example 2178366 -Node: Example 3180607 -Node: Example 4182420 -Node: Example 5185301 -Node: Example 6189418 -Node: Example 7192519 -Node: Example 8199397 -Node: Example 9207661 -Node: Example 10214330 -Node: Exercises221689 -Node: Glossary229812 -Node: Installation250321 -Node: Distribution251214 -Node: Unix installation251765 -Node: MS-Windows installation254164 -Node: Other installation257462 -Node: WFDB Applications258622 -Node: Using259618 -Node: Annotation I/O261410 -Node: Evaluation263051 -Node: Signal processing269974 -Node: Graphics272966 -Node: Extensions274496 -Node: Sources283353 -Node: Answers295056 -Node: Concept Index298818 -Node: Function and Macro Index327194 -Node: Copying331876 +Node: Overview1887 +Node: Concepts 14255 +Node: Concepts 26242 +Node: Concepts 38221 +Node: Applications10173 +Node: Guide12064 +Node: Recent changes19434 +Node: Usage29831 +Node: print samples30872 +Node: compiling32442 +Node: other languages37217 +Node: WFDB path40343 +Node: running example43018 +Node: name restrictions43692 +Node: WFDB path syntax44729 +Node: exercises 150770 +Node: Functions53175 +Node: introduction to functions54166 +Node: selecting57071 +Node: annopen57494 +Node: isigopen60099 +Node: osigopen64661 +Node: osigfopen66875 +Node: wfdbinit68531 +Node: special input modes69816 +Node: setifreq70296 +Node: getifreq72518 +Node: setgvmode73003 +Node: getspf74478 +Node: signal and annotation I/O75021 +Node: getvec75504 +Node: getframe78201 +Node: putvec79524 +Node: getann81549 +Node: ungetann82919 +Node: putann83615 +Node: non-sequential84649 +Node: isigsettime85151 +Node: isgsettime85884 +Node: iannsettime86392 +Node: conversion87586 +Node: annstr and strann88216 +Node: timstr and strtim93152 +Node: datstr and strdat97902 +Node: aduphys and physadu98942 +Node: calibration101528 +Node: calopen102192 +Node: getcal103088 +Node: putcal104287 +Node: newcal104649 +Node: flushcal105168 +Node: miscellaneous functions105514 +Node: newheader107081 +Node: setheader108383 +Node: setmsheader109947 +Node: wfdbquit111487 +Node: iannclose and oannclose112687 +Node: wfdbquiet and wfdbverbose113578 +Node: wfdberror114068 +Node: sampfreq115059 +Node: setsampfreq115987 +Node: setbasetime116523 +Node: counter conversion117355 +Node: setwfdb119963 +Node: getwfdb122475 +Node: wfdbfile123199 +Node: wfdbflush124325 +Node: getinfo124620 +Node: putinfo125497 +Node: setibsize126238 +Node: setobsize127240 +Node: wfdbgetskew128262 +Node: wfdbsetskew129827 +Node: wfdbgetstart130469 +Node: wfdbsetstart131571 +Node: Data Types132209 +Node: WFDB_Siginfo structures134205 +Node: WFDB_Calinfo structures140548 +Node: WFDB_Anninfo structures142593 +Node: WFDB_Annotation structures145349 +Node: Annotation Codes148233 +Node: Mapping macros152893 +Node: Database Files154840 +Node: Header Files157527 +Node: Signal Files158394 +Node: Annotation Files159213 +Node: Calibration Files159622 +Node: AHA Format Files160387 +Node: Standard I/O161856 +Node: Multiplexed Signal Files163100 +Node: Multi-Frequency Records164281 +Node: Multi-Segment Records167531 +Node: Multiple Record Access169484 +Node: Special Files170929 +Node: Piped and Local Records173833 +Node: NETFILES175684 +Node: Annotation Order178401 +Node: Examples181804 +Node: Example 1183042 +Node: Example 2186997 +Node: Example 3189238 +Node: Example 4191051 +Node: Example 5193932 +Node: Example 6198049 +Node: Example 7201150 +Node: Example 8208028 +Node: Example 9216292 +Node: Example 10222961 +Node: Exercises230301 +Node: Glossary238508 +Node: Installation258843 +Node: Distribution259736 +Node: Unix installation260287 +Node: MS-Windows installation262686 +Node: Other installation265687 +Node: WFDB Applications266847 +Node: Using267843 +Node: Annotation I/O269635 +Node: Evaluation271276 +Node: Signal processing278199 +Node: Graphics281191 +Node: Extensions282721 +Node: Sources291585 +Node: Answers303288 +Node: Concept Index307050 +Node: Function and Macro Index336368 +Node: Copying341315  End Tag Table diff -Naur wfdb-10.2.5/doc/wpg/info/wpg-1 wfdb-10.2.6/doc/wpg/info/wpg-1 --- wfdb-10.2.5/doc/wpg/info/wpg-1 Sun Mar 10 11:37:36 2002 +++ wfdb-10.2.6/doc/wpg/info/wpg-1 Mon Jun 24 22:20:24 2002 @@ -5,8 +5,8 @@ This guide documents the Waveform Database interface library (the WFDB library). This file contains the text of the Tenth Edition of the -`WFDB Programmer's Guide' (March, 2002), with revisions for release -10.2.5 of the WFDB library. +`WFDB Programmer's Guide' (June, 2002), with revisions for release +10.2.6 of the WFDB library. * Menu: @@ -17,7 +17,8 @@ the WFDB library. * Functions:: Call and return syntax of each function, with descriptions and program examples. -* Data Types:: Annotator and signal information structures, +* Data Types:: Simple and compound types, including annotator, + calibration, and signal information structures, and annotation structures. * Annotation Codes:: Table of codes, descriptions of mapping macros. * Database Files:: A description of the standard file types, and @@ -319,9 +320,9 @@ a wide variety of machines and operating systems, including Unix (BSD 4.x, System V, SunOS, Solaris, HP-UX, OSF/1, Version 7, XENIX, VENIX, ULTRIX, GNU/Linux, OpenBSD, IRIX, AIX, AUX, Darwin, MacOS/X, SCO, -Coherent, and more), MS-DOS, MS-Windows, VMS, and the Macintosh OS. -This guide was written for Unix users (with notes for MS-Windows and -MS-DOS users where differences exist), but others should find only minor +Coherent, and more), MS-DOS, MS-Windows, VMS, and classic MacOS. This +guide was written for Unix users (with notes for MS-Windows and MS-DOS +users where differences exist), but others should find only minor differences. At the end of the guide is a list of sources for databases and other @@ -332,7 +333,7 @@ Greenwald, David Israel, Roger Mark, Joe Mietus, Warren Muldrow, and especially to Paul Schluter, whose elegant 8080 assembly language functions inspired these (long live `getann'!). Pat Hamilton and Bob -Farrell contributed ports, to the Macintosh and the MS 32-bit Windows +Farrell contributed ports, to classic MacOS and the MS 32-bit Windows environments, respectively. Jose Garcia Moros and Salvador Olmos contributed Matlab/Octave reimplementations of a useful subset of the WFDB library. Thanks also to the many readers of earlier versions of @@ -386,6 +387,38 @@ WFDB Software Package distribution, for information on any more recent changes that may not be described here. +Changes in version 10.2.6 +------------------------- + + The new functions `setifreq' and `getifreq' allow an application to +choose any convenient sampling frequency for reading input signals. +Samples read from signal files using `getvec' are buffered, resampled, +and delivered to the calling application as if the original signals had +been sampled at the desired frequency. Times expressed in sample +intervals passed to or from other WFDB library functions (`getann', +`putann', `mstimstr', `timstr', and `strtim') are rescaled as needed to +match intervals corresponding to the chosen frequency. Thanks to Pat +Hamilton for the inspiration! + + The WFDB library now records the base time with millisecond precision +(previous versions did so with one-second precision), and `xform' +provides starting times to the library function `setbasetime' with +millisecond precision. Thanks to Allavatam Venugopal for providing +examples that illustrated the need for these features. + + Fixed deskewing buffer initialization in `getframe', broken by the +10.2.0 update, which introduced an infinite loop when reading a record +that requires skew correction starting at sample 0. Thanks to Andrew +Walsh for finding an example that triggered this bug. + + Fixed rounding errors in `adumuv', `muvadu', and `physadu'. +Previous versions rounded negative values toward zero; to obtain +consistent conversions, however, it is necessary to round all values +down (e.g., from -1.5 to -2 rather than up to -1). + + Fixed a memory leak in wfdb_fclose() (in lib/wfdbio.h). Thanks to +Ion Gaztan~aga. + Changes in version 10.2.5 ------------------------- @@ -670,6 +703,29 @@ will need additional libraries, and the corresponding `-l' options can usually be given before or after the `-lwfdb' option. + If the WFDB library was installed with NETFILES support, it will make +use of functions contained in the `libwww' libraries. If you have +dynamically linkable versions of the `libwww' libraries, as under +GNU/Linux, these will be loaded automatically when you run `psamples'. +If you have only static versions of these libraries, as under Solaris +or MS-Windows, however, it is necessary to provide additional arguments +in the `cc' command line in order to compile successfully. One way to +do this is to follow the model used to compile the standard WFDB +applications supplied with the WFDB library; see `Makefile' in the +`app' directory of the WFDB software package source tree. + + If you are using WFDB version 10.2.6 or a later version and `gcc' or +a compatible compiler, the `wfdb-config' utility is available to help +construct commands for compiling programs that use the WFDB library +(and the `libwww' libraries, if available). Use it like this: + + gcc `wfdb-config --cflags` -o psamples `wfdb-config --libs` + +Note that this command contains backticks (`), not apostrophes ('). +`wfdb-config' is particularly useful if the WFDB library or its `*.h' +files are installed in non-standard locations, or if you have only +static `libwww' libraries. + Under MS-Windows, it will be easiest to use `gcc', the GNU C/C++ compiler, which is included in the freely available Cygwin software development system (`http://source.redhat.com/cygwin/'), and also in @@ -679,18 +735,40 @@ terminal emulator window or an MS-DOS box in exactly the same way as described above for Unix C compilers. - Each proprietary C or C++ compiler has its own idiosyncratic syntax, -so no general rule can be given for these. With Microsoft C/C++, use: - - cl psamples.c -link wfdb - -With Borland C/C++, use: - - bcc -LLIBDIR psamples.c wfdb.lib - -where LIBDIR is the directory in which `wfdb.lib' (the WFDB library) -has been installed. (Substitute `tcc' for `bcc' if you are using Turbo -C or C++.) See your compiler manual for further information. + The WFDB library is developed and tested using `gcc', but careful +attention has been given to making it usable with any K&R or ANSI/ISO C +compiler. Note, however, that binary versions of the WFDB library that +have been compiled using `gcc' are _not_ compatible with most +proprietary C/C++ compilers (except under Unix). Since `gcc' is free, +high quality, and supported, it is highly recommended that you use it +for compiling your WFDB applications. + + If you choose to use an incompatible proprietary compiler, you are on +your own! You may be able to create a linkable version of the WFDB +library from the sources in the `lib' directory of the WFDB source tree +using a proprietary compiler, but doing so is unsupported (see your +compiler's documentation, and if you are using MS-DOS or MS-Windows, see +`Makefile.dos' for hints). If you are not able to build the WFDB +library using your compiler, you can compile the library sources +together with the source file(s) for your application. It may be +easiest to copy the library sources (both the `*.c' and the `*.h' +files) into the same directory as the application sources. If you +follow this approach, find the directory that contains `stdio.h' on +your system and make a `wfdb' subdirectory within that directory, then +copy the WFDB library's `*.h' files into the `wfdb' subdirectory (this +is necessary so that statements of the form `#include ' +will be handled properly by your compiler). For example, to compile +`psamples.c' with Microsoft C/C++, set up the WFDB library source files +as just described, then use this command: + + cl psamples.c wfdbio.c signal.c annot.c calib.c wfdbinit.c + +With Borland C/C++ or Turbo C or C++, substitute `bcc' or `tcc', +respectively, for `cl' in the command above. You will find that some +WFDB applications do not need to be compiled with all of the WFDB +library sources (for example, `psamples' needs only `wfdbio.c' and +`signal.c'); in such cases, you may omit the unneeded sources for +faster compilation and smaller executable binaries.  File: wpg, Node: other languages, Next: WFDB path, Prev: compiling, Up: Usage @@ -785,8 +863,8 @@ so that the WFDB path can be examined by the running program. The WFDB software package includes easily customizable shell scripts (batch files) that illustrate how to do this for popular shells and command -interpreters; see _setwfdb_(1), in the `WFDB Applications Guide'. (On -the Macintosh, for which the concept of environment variables is +interpreters; see _setwfdb_(1), in the `WFDB Applications Guide'. +(Under classic MacOS, for which the concept of environment variables is foreign, the WFDB path may be set only by using `DEFWFDB'.) For further information, *note WFDB path syntax::. @@ -818,7 +896,8 @@ psamples -and its output will appear as: +(Try `./psamples' if `psamples' doesn't work.) Its output will appear +as: 995 1011 995 1011 @@ -856,185 +935,4 @@ External identifiers beginning with `WFDB_' are used for constants and data types defined within `'. Use these identifiers as needed in your programs, but avoid redefining them. - - -File: wpg, Node: WFDB path syntax, Next: exercises 1, Prev: name restrictions, Up: Usage - -More About the WFDB Path -======================== - - When a WFDB file must be opened for input, the WFDB library attempts -to locate it by attaching each of the components of the WFDB path (one -at a time) as a prefix to the file name. If two or more matching files -exist in different locations in the WFDB path, the WFDB library opens -only the file that resides in the first of these locations. Any other -matching files are effectively invisible to WFDB applications unless -the WFDB path is rearranged. - - The default WFDB path is specified at the time the WFDB library is -compiled, by defining a value for the symbol `DEFWFDB' in `wfdblib.h'. -Current versions of the WFDB library are compiled with a -three-component default WFDB path; the first component is empty (i.e., -it refers to the current directory), the second component names the -"system-wide database directory" (which contains the sample WFDB files -supplied with the WFDB software package), and the third component is -`http://www.physionet.org/physiobank/database' (referring to the -PhysioBank data archives). Note that this default may be changed at the -time the WFDB library is compiled. Normally, however, this means that -any record available from PhysioBank is readable by any WFDB application -provided that PhysioBank is accessible from the user's computer and that -the database name is included in the record name (for example, -`slpdb/slp60' or `nsrdb/16265'). - - Under Unix and VMS, the WFDB path can be given as a colon-separated -list of prefixes, in the format used for the Bourne shell's `PATH' -variable. Under MS-Windows, MS-DOS, and MacOS, the WFDB path can be -given in the format used for the MS-DOS `PATH' variable, with -semicolons used to separate prefixes (colons retain their customary -meanings, as drive letter suffixes under MS-DOS, or as directory -separators on the Macintosh). Alternatively, components of the WFDB -path may be separated by whitespace (under any operating system); this -also implies that embedded spaces are not permitted within path -components. *For this reason, avoid using directories with names such -as `My Documents', or their subdirectories, to store WFDB files.* - - When WFDB applications _write_ database files, these files are -generally written to the current directory. (As an example, an -application that analyzes one or more signals in a record may record its -findings in an annotation file in the current directory.) If the record -name (as provided by the application to the WFDB library) contains path -information, however, output files are written to the corresponding -subdirectory of the current directory. (For example, if a WFDB -application writes an annotation file for record `edb/e0103', the file -will be written in the `edb' subdirectory of the current directory. -The `edb' subdirectory will be created by the WFDB library if does not -exist already. This feature was introduced in WFDB library version -10.2.0.) - - Note particularly that the current directory is _not_ necessarily -part of the WFDB path. If you modify your WFDB path, you must -explicitly include an empty (null) component, which corresponds to the -current directory, in order to be sure that your WFDB applications can -read any WFDB files that you have previously written. In most cases, -this null component should be the first in the WFDB path. Thus, if you -write into the current directory a modified version of an existing WFDB -file, any later actions that would read this file will read your -modified version rather than the original. - - The WFDB path may contain `http://' and `ftp://' URL prefixes (other -schema, such as `file://' and `https://', may also be supported if they -are supported by your version of `libwww'). If NETFILES support is not -compiled into the WFDB library, any WFDB path components containing -`://' are ignored. (These features were first introduced in WFDB -library version 10.1.0.) - - If the WFDB library finds that the value assigned to the WFDB path -is of the form `@FILE', it replaces that value with the contents of the -specified FILE. (This feature was first introduced in WFDB library -version 8.0.) Indirect WFDB path files may be nested up to ten levels -(this arbitrary limit is imposed to avoid infinite recursion if the -contents of the indirect file are incorrect). This method of indirect -assignment is useful on the Macintosh, where recompilation of the WFDB -library would otherwise be necessary in order to change the WFDB path. -It may also be useful under MS-DOS to reduce the need for environment -space, or if the length of the command needed to set the `WFDB' -environment variable would otherwise approach or exceed the 128-byte -limit for MS-DOS commands. - - If a WFDB header file (*note Database Files::) specifies that a -signal file is to be found in a directory that is not already in the -WFDB path, that directory is appended to the end of the WFDB path; in -this case, if the WFDB path is not set, it is created with an initial -null component followed by the directory that contains the signal file. -(This feature was first introduced in WFDB library version 6.2.) - - The string `%r' is replaced by the current record name wherever it -appears in the WFDB path; `%Nr' is replaced by the first N digits of -the record name, if N is a non-zero digit. For example, if (under -Unix) the WFDB path is `:/cdrom/mimicdb/%3r:/cdrom/mitdb', a request to -read a file associated with record 055n will cause the WFDB library to -look first in the current directory (since the WFDB path begins with an -empty component), then in `/cdrom/mimicdb/055', and then in -`/cdrom/mitdb'. If `%' is followed by any character other than `r' or -a non-zero digit followed by `r', that character is used as is in the -WFDB path; thus a literal `%' can be included in the WFDB path by -`escaping' it as `%%'. (Substitutions of `%'-strings in the WFDB path -were first introduced in WFDB library version 9.7.) - - -File: wpg, Node: exercises 1, Prev: WFDB path syntax, Up: Usage - -Exercises -========= - - These exercises should require only a few minutes. If you work -through them, you will have an opportunity to become acquainted with a -few of the most common errors in using the WFDB library. - - 1. Compile the example program in this chapter and run it. If the - WFDB Software Package has not already been installed on your - system, download and install the most recent version from - PhysioNet first (*note Installing the WFDB Software Package: - Installation.). - - 2. Find out where database records are kept on your system. What - records are available locally? - - 3. Modify the example program so that you can specify the record to be - opened, either as a command-line argument or by having the program - prompt you to type a record name. If you are unfamiliar with - command-line argument processing, *note Example 2::. - - 4. Use the modified version of the example to read samples from - records `mitdb/200', `edb/e0103', `slpdb/slp04', and - `mimicdb/237/237'. The last two of these records have 4 and 6 - signals respectively, so you will need to make a few additional - changes to the program in order to read these records successfully. - - 5. Once again using the modified version of the example, what happens - if you omit the path information from one of the records in the - previous exercise (for example, if you try to open `e0103' instead - of `edb/e0103'? Figure out how to set the WFDB path so that the - program will work properly in this case. (Hint: use the - application `wfdbwhich', included with the WFDB Software Package, - to find the header file for record `edb/e0103'; this information - will help you to determine how to set the WFDB path.) - - 6. If you use MS-DOS or MS-Windows, explore and explain what happens - in the previous exercise if you type the record name using - upper-case letters, or if you type a `\' (backslash) instead of `/' - (forward slash). (Hint: record names are _not_ filenames!) - - 7. What happens when you compile the example program as shown, but - with the `#include' statement omitted? with the `-lwfdb' (`-link - wfdb', etc.) omitted? - - 8. What is the type of the argument to `getvec'? Why can't `getvec' - simply return the value it reads, as in `v = getvec()'? - - -File: wpg, Node: Functions, Next: Data Types, Prev: Usage, Up: Top - -WFDB Library Functions -********************** - - This chapter describes the functions that are available to programs -compiled with the `-lwfdb' option. The functions are introduced in -several groups, with examples to illustrate their usage. - -* Menu: - -* introduction to functions:: General notes on functions. - This node discusses arguments, return codes, - and the organization of this section of - the guide. - -The remainder of the nodes in this section describe functions for: - -* selecting:: Selecting database records (opening files). -* signal and annotation I/O:: Reading and writing signals and annotations. -* non-sequential:: Non-sequential access to WFDB files. -* conversion:: Time and other conversion functions. -* calibration:: Calibrating signals. -* miscellaneous functions:: Attribute-reading and other functions. diff -Naur wfdb-10.2.5/doc/wpg/info/wpg-2 wfdb-10.2.6/doc/wpg/info/wpg-2 --- wfdb-10.2.5/doc/wpg/info/wpg-2 Sun Mar 10 11:37:36 2002 +++ wfdb-10.2.6/doc/wpg/info/wpg-2 Mon Jun 24 22:20:24 2002 @@ -1,6 +1,188 @@ This is wpg, produced by makeinfo version 4.0b from wpg.tex.  +File: wpg, Node: WFDB path syntax, Next: exercises 1, Prev: name restrictions, Up: Usage + +More About the WFDB Path +======================== + + When a WFDB file must be opened for input, the WFDB library attempts +to locate it by attaching each of the components of the WFDB path (one +at a time) as a prefix to the file name. If two or more matching files +exist in different locations in the WFDB path, the WFDB library opens +only the file that resides in the first of these locations. Any other +matching files are effectively invisible to WFDB applications unless +the WFDB path is rearranged. + + The default WFDB path is specified at the time the WFDB library is +compiled, by defining a value for the symbol `DEFWFDB' in `wfdblib.h'. +Current versions of the WFDB library are compiled with a +three-component default WFDB path; the first component is empty (i.e., +it refers to the current directory), the second component names the +"system-wide database directory" (which contains the sample WFDB files +supplied with the WFDB software package), and the third component is +`http://www.physionet.org/physiobank/database' (referring to the +PhysioBank data archives). Note that this default may be changed at the +time the WFDB library is compiled. Normally, however, this means that +any record available from PhysioBank is readable by any WFDB application +provided that PhysioBank is accessible from the user's computer and that +the database name is included in the record name (for example, +`slpdb/slp60' or `nsrdb/16265'). + + Under Unix and VMS, the WFDB path can be given as a colon-separated +list of prefixes, in the format used for the Bourne shell's `PATH' +variable. Under MS-Windows, MS-DOS, and MacOS, the WFDB path can be +given in the format used for the MS-DOS `PATH' variable, with +semicolons used to separate prefixes (colons retain their customary +meanings, as drive letter suffixes under MS-DOS, or as directory +separators on the Macintosh). Alternatively, components of the WFDB +path may be separated by whitespace (under any operating system); this +also implies that embedded spaces are not permitted within path +components. *For this reason, avoid using directories with names such +as `My Documents', or their subdirectories, to store WFDB files.* + + When WFDB applications _write_ database files, these files are +generally written to the current directory. (As an example, an +application that analyzes one or more signals in a record may record its +findings in an annotation file in the current directory.) If the record +name (as provided by the application to the WFDB library) contains path +information, however, output files are written to the corresponding +subdirectory of the current directory. (For example, if a WFDB +application writes an annotation file for record `edb/e0103', the file +will be written in the `edb' subdirectory of the current directory. +The `edb' subdirectory will be created by the WFDB library if does not +exist already. This feature was introduced in WFDB library version +10.2.0.) + + Note particularly that the current directory is _not_ necessarily +part of the WFDB path. If you modify your WFDB path, you must +explicitly include an empty (null) component, which corresponds to the +current directory, in order to be sure that your WFDB applications can +read any WFDB files that you have previously written. In most cases, +this null component should be the first in the WFDB path. Thus, if you +write into the current directory a modified version of an existing WFDB +file, any later actions that would read this file will read your +modified version rather than the original. + + The WFDB path may contain `http://' and `ftp://' URL prefixes (other +schema, such as `file://' and `https://', may also be supported if they +are supported by your version of `libwww'). If NETFILES support is not +compiled into the WFDB library, any WFDB path components containing +`://' are ignored. (These features were first introduced in WFDB +library version 10.1.0.) + + If the WFDB library finds that the value assigned to the WFDB path +is of the form `@FILE', it replaces that value with the contents of the +specified FILE. (This feature was first introduced in WFDB library +version 8.0.) Indirect WFDB path files may be nested up to ten levels +(this arbitrary limit is imposed to avoid infinite recursion if the +contents of the indirect file are incorrect). This method of indirect +assignment is useful under classic MacOS, where recompilation of the +WFDB library would otherwise be necessary in order to change the WFDB +path. It may also be useful under MS-DOS to reduce the need for +environment space, or if the length of the command needed to set the +`WFDB' environment variable would otherwise approach or exceed the +128-byte limit for MS-DOS commands. + + If a WFDB header file (*note Database Files::) specifies that a +signal file is to be found in a directory that is not already in the +WFDB path, that directory is appended to the end of the WFDB path; in +this case, if the WFDB path is not set, it is created with an initial +null component followed by the directory that contains the signal file. +(This feature was first introduced in WFDB library version 6.2.) + + The string `%r' is replaced by the current record name wherever it +appears in the WFDB path; `%Nr' is replaced by the first N digits of +the record name, if N is a non-zero digit. For example, if (under +Unix) the WFDB path is `:/cdrom/mimicdb/%3r:/cdrom/mitdb', a request to +read a file associated with record 055n will cause the WFDB library to +look first in the current directory (since the WFDB path begins with an +empty component), then in `/cdrom/mimicdb/055', and then in +`/cdrom/mitdb'. If `%' is followed by any character other than `r' or +a non-zero digit followed by `r', that character is used as is in the +WFDB path; thus a literal `%' can be included in the WFDB path by +`escaping' it as `%%'. (Substitutions of `%'-strings in the WFDB path +were first introduced in WFDB library version 9.7.) + + +File: wpg, Node: exercises 1, Prev: WFDB path syntax, Up: Usage + +Exercises +========= + + These exercises should require only a few minutes. If you work +through them, you will have an opportunity to become acquainted with a +few of the most common errors in using the WFDB library. + + 1. Compile the example program in this chapter and run it. If the + WFDB Software Package has not already been installed on your + system, download and install the most recent version from + PhysioNet first (*note Installing the WFDB Software Package: + Installation.). + + 2. Find out where database records are kept on your system. What + records are available locally? + + 3. Modify the example program so that you can specify the record to be + opened, either as a command-line argument or by having the program + prompt you to type a record name. If you are unfamiliar with + command-line argument processing, *note Example 2::. + + 4. Use the modified version of the example to read samples from + records `mitdb/200', `edb/e0103', `slpdb/slp04', and + `mimicdb/237/237'. The last two of these records have 4 and 6 + signals respectively, so you will need to make a few additional + changes to the program in order to read these records successfully. + + 5. Once again using the modified version of the example, what happens + if you omit the path information from one of the records in the + previous exercise (for example, if you try to open `e0103' instead + of `edb/e0103'? Figure out how to set the WFDB path so that the + program will work properly in this case. (Hint: use the + application `wfdbwhich', included with the WFDB Software Package, + to find the header file for record `edb/e0103'; this information + will help you to determine how to set the WFDB path.) + + 6. If you use MS-DOS or MS-Windows, explore and explain what happens + in the previous exercise if you type the record name using + upper-case letters, or if you type a `\' (backslash) instead of `/' + (forward slash). (Hint: record names are _not_ filenames!) + + 7. What happens when you compile the example program as shown, but + with the `#include' statement omitted? with the `-lwfdb' (`-link + wfdb', etc.) omitted? + + 8. What is the type of the argument to `getvec'? Why can't `getvec' + simply return the value it reads, as in `v = getvec()'? + + +File: wpg, Node: Functions, Next: Data Types, Prev: Usage, Up: Top + +WFDB Library Functions +********************** + + This chapter describes the functions that are available to programs +compiled with the WFDB library. The functions are introduced in +several groups, with examples to illustrate their usage. + +* Menu: + +* introduction to functions:: General notes on functions. + This node discusses arguments, return codes, + and the organization of this section of + the guide. + +The remainder of the nodes in this section describe functions for: + +* selecting:: Selecting database records (opening files). +* special input modes:: Setting the input sampling frequency and more. +* signal and annotation I/O:: Reading and writing signals and annotations. +* non-sequential:: Non-sequential access to WFDB files. +* conversion:: Time and other conversion functions. +* calibration:: Calibrating signals. +* miscellaneous functions:: Attribute-reading and other functions. + + File: wpg, Node: introduction to functions, Next: selecting, Prev: Functions, Up: Functions About these functions @@ -44,15 +226,16 @@ for opening signal files find them by reading the header file (which contains their names) first. - The first part of this chapter describes functions that extract -information from header files in order to gain access to signal and -annotation files. The following two sections describe functions that -deal with signal and annotation files. Many readers will not need to -go any further; the remaining sections deal with special-purpose + The first two sections of this chapter describes functions that +extract information from header files in order to gain access to signal +and annotation files, and functions that control how these files are +read and written. The following two sections describe functions that +read and write signal and annotation files. Many readers will not need +to go any further; the remaining sections deal with special-purpose functions that exist to serve unusual applications.  -File: wpg, Node: selecting, Next: signal and annotation I/O, Prev: introduction to functions, Up: Functions +File: wpg, Node: selecting, Next: special input modes, Prev: introduction to functions, Up: Functions Selecting Database Records ========================== @@ -385,7 +568,147 @@ files.  -File: wpg, Node: signal and annotation I/O, Next: non-sequential, Prev: selecting, Up: Functions +File: wpg, Node: special input modes, Next: signal and annotation I/O, Prev: selecting, Up: Functions + +Special Input Modes +=================== + +* Menu: + +* setifreq:: Setting the input sampling frequency. +* getifreq:: Determining the input sampling frequency. +* setgvmode:: Setting the resolution for a multifrequency + record. +* getspf:: Determining the number of samples per frame. + + +File: wpg, Node: setifreq, Next: getifreq, Prev: special input modes, Up: special input modes + +setifreq +-------- + + void setifreq(WFDB_Frequency FREQUENCY) + +This function sets the current input sampling frequency (in samples per +second per signal). It should be invoked after opening the input +signals (using `isigopen' or `wfdbinit'), and before using any of +`getvec', `getann', `putann', `isigsettime', `isgsettime', `timstr', +`mstimstr', or `strtim'. _Note that the operation of `getframe' is +unaffected by `setifreq'._ + + Use `setifreq' when your application requires input samples at a +specific frequency. After invoking `setifreq', `getvec' resamples the +digitized signals from the input signals at the desired frequency +(*note getvec::), and all of the WFDB library functions that accept or +return times in sample intervals automatically convert between the +actual sampling intervals and those corresponding to the desired +frequency. This slightly elaborated version of the example program from +the previous chapter invokes `setifreq', passing it the desired sampling +frequency from the command line, then prints the samples in record 100s, +beginning 1 second (`t0') and ending 2 seconds (`t1') from the +beginning of the record: + + #include + + main(int argc, char **argv) + { + WFDB_Frequency f = (WFDB_Frequency)0; + WFDB_Sample v[2]; + WFDB_Siginfo s[2]; + WFDB_Time t, t0, t1; + + if (argc > 1) sscanf(argv[1], "%lf", &f); + if (f <= (WFDB_Frequency)0) f = sampfreq("100s"); + + if (isigopen("100s", s, 2) < 1) + exit(1); + setifreq(f); + t0 = strtim("1"); + isigsettime(t0); + t1 = strtim("2"); + for (t = t0; t <= t1; t++) { + if (getvec(v) < 0) + break; + printf("%d\t%d\n", v[0], v[1]); + } + exit(0); + } + +(The source for this program, `psamplex.c', can be found in the +`examples' directory of the WFDB source tree. Compile it as shown in +the previous chapter, then run it using a command such as `psamplex +100'.) The QRS detector in chapter 6 also illustrates the use of +`setifreq' (*note Example 10::). + + +File: wpg, Node: getifreq, Next: setgvmode, Prev: setifreq, Up: special input modes + +getifreq +-------- + + WFDB_Frequency getifreq(void) + +*Return:* +(WFDB_Frequency) + the input sampling frequency + +This function returns the current input sampling frequency (in samples +per second per signal), which is either the raw sampling frequency for +the record (as would be returned by `sampfreq', *note sampfreq::), or +the frequency chosen using a previous invocation of `setifreq'. + + +File: wpg, Node: setgvmode, Next: getspf, Prev: getifreq, Up: special input modes + +setgvmode +--------- + + void setgvmode(int *MODE) + +This function sets the mode used by `getvec' when reading a +multi-frequency record (*note Multi-Frequency Records::). If MODE is +`WFDB_LOWRES', `getvec' decimates any signals sampled at multiples of +the frame rate, so that one sample is returned per signal per frame +(i.e., the oversampled signals are resampled by simple averaging of the +samples for each signal within each frame). If MODE is `WFDB_HIGHRES', +each sample of any oversampled signal is returned by successive +invocations of `getvec', and each sample of any signal sampled at a +lower frequency is returned by two or more successive invocations of +`getvec' (i.e., the less frequently sampled signals are resampled using +zero-order interpolation). `getvec' operates in `WFDB_LOWRES' mode by +default. `WFDB_LOWRES' and `WFDB_HIGHRES' are defined in +`'. + + In WFDB library version 9.6 and later versions, `setgvmode' also +affects how annotations are read and written. If +`setgvmode(WFDB_HIGHRES)' is invoked _before_ using `annopen', +`wfdbinit', `getvec', `sampfreq', `strtim', or `timstr', then all +`WFDB_Time' data (including the `time' attributes of annotations read +by `getann' or written by `putann') visible to the application are in +units of the high-resolution sampling intervals. (Otherwise, +`WFDB_Time' data are in units of frame intervals.) + + +File: wpg, Node: getspf, Prev: setgvmode, Up: special input modes + +getspf +------ + + int getspf(void) + +*Return:* +(int) + the number of samples per signal per frame + +Unless the application is operating in `WFDB_HIGHRES' mode (*note +setgvmode::) and has then opened a multi-frequency record, this +function returns 1. For the case of a multi-frequency record being read +in high resolution mode, however, `getspf' returns the number of +samples per signal per frame (hence `sampfreq(NULL)/getspf()' is the +number of frames per second). + + +File: wpg, Node: signal and annotation I/O, Next: non-sequential, Prev: special input modes, Up: Functions Reading and Writing Signals and Annotations =========================================== @@ -461,6 +784,19 @@ example programs in chapter 6 illustrate the use of `getvec'; for example, *note Example 6::. + If `setifreq' has been used to modify the input sampling rate, +`getvec' resamples the input signals at the desired rate, using linear +interpolation between the pair of samples nearest in time to that of +the sample to be returned. The results will generally be satisfactory, +provided that the original signals do not contain frequencies near or +above the Nyquist limit (half of the desired sampling frequency). If +this is a concern, you may wish to low-pass filter the input signals +using, for example, `fir' (see the `WFDB Applications Guide') before +resampling them. If you use `setifreq' to _increase_ the sampling +frequency by a large factor, you may wish to filter the resampled +signals within your application to remove harmonics of the original +sampling frequency introduced by resampling. +  File: wpg, Node: getframe, Next: putvec, Prev: getvec, Up: signal and annotation I/O @@ -897,481 +1233,4 @@ strings for two or more codes; the behavior of `strann' and `strecg' in such cases is implementation-dependent. (`setannstr' and `setanndesc' were first introduced in WFDB library version 5.3.) - - -File: wpg, Node: timstr and strtim, Next: datstr and strdat, Prev: annstr and strann, Up: conversion - - The next three functions convert between "standard time format" -strings and times in units of sample intervals. Normally they should be -invoked after `isigopen', `wfdbinit', or `sampfreq', any of which will -determine the duration of a sample interval and the base time from a -header file, or after defining these quantities using `setsampfreq' and -`setbasetime'. If this is not done, or if these time-conversion -functions are used after `wfdbquit', they will perform conversions in -units of seconds (i.e., the sample interval is taken to be one second -in such cases). - -[ms]timstr ----------- - - char *timstr(WFDB_Time T) - char *mstimstr(WFDB_Time T) - -*Return:* -(char *) - pointer to a string that represents the time - -These functions convert times or time intervals into null-terminated -ASCII strings. If the argument, T, is greater than zero, it is treated -as a time interval, and converted directly into HH:MM:SS format by -`timstr', or to HH:MM:SS.SSS format by `mstimstr', with leading zero -digits and colons suppressed. If T is zero or negative, it is taken to -represent negated elapsed time from the beginning of the record, and it -is converted to a time of day using the base time for the record as -indicated by the `hea' file or the caller (*note setbasetime::); in -this case, if the base time is defined, the string will contain all -digits even if there are leading zeroes, it will include the date if a -base date is defined, and it will be marked as a time of day by being -bracketed (e.g., `[08:45:00 23/04/1989]'). The result of the -conversion is truncated to a multiple of a second by `timstr', or to a -multiple of a millisecond by `mstimstr'. Note in each case that the -returned pointer addresses static data (shared by `timstr' and -`mstimstr'), the contents of which are overwritten by subsequent calls. -*Note Example 3::, for an illustration of the use of `mstimstr'; also -*note Example 5::, for an example of the use of `timstr'. - -strtim ------- - - WFDB_Time strtim(char *STRING) - -*Return:* -(WFDB_Time) >0 - number of sample intervals corresponding to the argument - interpreted as a time interval - -(WFDB_Time) <0 - (negated) elapsed time in sample intervals from the beginning of - the record, corresponding to the argument interpreted as a time of - day - -(WFDB_Time) 0 - a legal return if the argument matches the base time; otherwise - an error return indicating an incorrectly formatted argument - -This function converts an ASCII string in "standard time format" to a -time in units of sample intervals. Examples of standard time format: -`2:14.875' - 2 minutes + 14.875 seconds - -`[13:6:0]' - 13:06 (1:06 PM) - -`[8:0:0 1]' - 8 AM on the day following the base date - -`[12:0:0 1/3/1992]' - noon on 1 March 1992 - -`143' - 143 seconds (2 minutes + 23 seconds) - -`4:02:01' - 4 hours + 2 minutes + 1 second - -`s12345' - 12345 sample intervals - -`c350.5' - counter value 350.5 - -`e' - time of the end of the record (if defined) - -`i' - time of the next sample in input signal 0 - -`o' - (the letter `o') time of the next sample in output signal 0 - - If the argument is bracketed (as in the second, third, and fourth -examples), it is taken as a time of day, and `strtim' uses the base -time defined by the header file or by the caller (*note setbasetime::); -in this case, the value returned is zero or negative (and can be -converted into elapsed time from the beginning of the record by simply -negating it). If the argument is not bracketed, it is taken as a time -interval, and converted directly into a positive number of sample -intervals. These notations match those used by `timstr' and -`mstimstr', which are (approximately) inverse functions of `strtim'; in -fact, for MIT DB and AHA DB records (and any others with sampling -frequencies below 1 KHz), `strtim(mstimstr(T))' = T, for any T. The -`s'-format (as in the seventh example above) is provided to allow -"conversion" of time intervals already expressed in sample intervals. -The similar `c'-format converts counter values (*note counter -conversion::) into sample intervals. The length of the record in -sample intervals can be obtained using `strtim("e")', which evaluates -to zero if this quantity is undefined. The sample number of the next -sample to be read or written can be determined using `strtim("i")' or -`strtim("o")'. If the argument string is incorrectly formatted, -`strtim' returns zero (indistinguishable from a correct input that -evokes a zero output); this may be considered a feature. Several of -the programs in chapter 6 illustrate the use of `strtim' (for example, -*note Example 7::). - - -File: wpg, Node: datstr and strdat, Next: aduphys and physadu, Prev: timstr and strtim, Up: conversion - - The next two functions convert between Julian dates and ASCII -strings. Julian dates as defined by astronomers begin at noon GMT; -these begin at midnight local time. - -datstr ------- - - char *datstr(WFDB_Date DATE) - -*Return:* -(char *) - pointer to a string that represents the date - -This function converts the Julian date represented by DATE into an -ASCII string in the form DD/MM/YYYY. - -strdat ------- - - WFDB_Date strdat(char *STRING) - -*Return:* -(WFDB_Date) - Julian date corresponding to the argument - -This function converts STRING into a Julian date. The argument should -be in the format used by `datstr'; if STRING is improperly formatted, -`strdat' returns zero. Note that dates such as `15/3/89' refer to the -first century A.D., not the twentieth. For example, the interval in -days between the events commemorated by the French and American -national holidays is `strdat("14/7/1789")' - `strdat("4/7/1776")'. - - - - -File: wpg, Node: aduphys and physadu, Prev: datstr and strdat, Up: conversion - - The next four functions convert between analog-to-digital converter -(ADC) units and physical units, using as a conversion factor the gain -for the specified input signal. The first two (`aduphys' and -`physadu') are general-purpose functions that convert absolute levels -(i.e., they account for non-zero `baseline' values); the last two -(`adumuv' and `muvadu') are for use with millivolt-dimensioned signals -only, and convert potential differences (i.e., `adumuv(S, 0)' = -`muvadu(S, 0)' = 0 for all S, irrespective of the `baseline' values -specified in the header file). Normally, these functions should be -invoked after `isigopen' or `wfdbinit', either of which will determine -the gain from the `hea' file. If this is not done, or if the header -file indicates that the gain is uncalibrated, or if the specified input -signal is not currently open, a gain of `WFDB_DEFGAIN' (defined in -`') ADC units per millivolt, and a baseline of zero, are -assumed. If the physical units (*note WFDB_Siginfo structures::) are -not millivolts, `adumuv' and `muvadu' convert to and from thousandths -of the defined physical units. Note that `adumuv' and `muvadu' deal -exclusively with integers, but `aduphys' returns and `physadu' accepts -double-precision floating point physical values. - -aduphys -------- - - double aduphys(WFDB_Signal S, WFDB_Sample A) - -*Return:* -(double) - physical value corresponding to a sample value of A ADC units - -This function converts the sample value A from ADC units to physical -units, based on the `gain' and `baseline' for input signal S. -(`aduphys' was first introduced in WFDB library version 6.0.) - -physadu -------- - - WFDB_Sample physadu(WFDB_Signal S, double V) - -*Return:* -(WFDB_Sample) - sample value, in ADC units, corresponding to V, in physical units - -This function converts the value V from physical units to ADC units, -based on the `gain' and `baseline' for input signal S. (`physadu' was -first introduced in WFDB library version 6.0.) - -adumuv ------- - - int adumuv(WFDB_Signal S, WFDB_Sample A) - -*Return:* -(int) - number of microvolts corresponding to A ADC units - -This function converts the potential difference A from ADC units to -microvolts, based on the `gain' for input signal S. - -muvadu ------- - - WFDB_Sample muvadu(WFDB_Signal S, int V) - -*Return:* -(int) - number of ADC units corresponding to V microvolts - -This function converts the potential difference V from microvolts to -ADC units, based on the `gain' for input signal S. - - -File: wpg, Node: calibration, Next: miscellaneous functions, Prev: conversion, Up: Functions - -Calibration Functions -===================== - - Functions in this section are used to determine specifications for -calibration pulses and customary scales for plotting signals. All of -them make use of the "calibration list", which is maintained in memory -and which contains entries for various types of signals. - -* Menu: - -* calopen:: read a calibration file into list -* getcal:: retrieve calibration data from list -* putcal:: append calibration data to list -* newcal:: write calibration list to a file -* flushcal:: discard contents of calibration list - - -File: wpg, Node: calopen, Next: getcal, Prev: calibration, Up: calibration - -calopen -------- - - int calopen(char *FILE) - -*Return:* - 0 - Success - --1 - Failure: insufficient memory for calibration list - --2 - Failure: unable to open calibration file - -This function reads the specified calibration FILE (which must be -located in one of the directories specified by `WFDB', *note WFDB -path::) into the calibration list. If FILE is `NULL', the file named -by `WFDBCAL' is read. Normally, the current contents of the -calibration list are discarded before reading the calibration file; if -FILE begins with `+', however, the `+' is stripped from the file name -and the contents of the file are appended to the current calibration -list. If FILE is `-', `calopen' reads the standard input rather than a -calibration file. (This function was first introduced in WFDB library -version 6.0.) - - -File: wpg, Node: getcal, Next: putcal, Prev: calopen, Up: calibration - -getcal ------- - - int getcal(char *DESC, char *UNITS, WFDB_Calinfo *CAL) - -*Return:* - 0 - Success; `*CAL' contains the requested data - --1 - Failure: no match found - -This function attempts to find calibration data for signals of type -DESC, having physical units as given by UNITS. If successful, it fills -in the contents of the `WFDB_Calinfo' structure (*note WFDB_Calinfo -structures::) pointed to by CAL. The caller must allocate storage for -the `WFDB_Calinfo' structure, and must not modify the contents of the -strings addressed by the `sigtype' and `units' fields of the -`WFDB_Calinfo' structure after `getcal' returns. `getcal' returns data -from the first entry in the calibration list that contains a `sigtype' -field that is either an exact match or a prefix of DESC, and a `units' -field that is an exact match of UNITS; if either DESC or UNITS is -`NULL', however, it is ignored for the purpose of finding a match. -`getcal' cannot succeed unless the calibration list has been -initialized by a previous invocation of `calopen' or `putcal'. (This -function was first introduced in WFDB library version 6.0.) - - -File: wpg, Node: putcal, Next: newcal, Prev: getcal, Up: calibration - -putcal ------- - - int putcal(WFDB_Calinfo *CAL) - -*Return:* - 0 - Success - --1 - Failure: insufficient memory - -This function adds the `WFDB_Calinfo' structure pointed to by CAL to -the end of the calibration list. (This function was first introduced -in WFDB library version 6.0.) - - -File: wpg, Node: newcal, Next: flushcal, Prev: putcal, Up: calibration - -newcal ------- - - int newcal(char *FILE) - -*Return:* - 0 - Success - --1 - Failure: unable to open FILE - -This function creates a new calibration FILE (in the current directory) -containing the contents of the calibration list (which is not -modified). FILE must satisfy the standard conditions for a WFDB file -name, i.e., it may contain letters, digits, or underscores. (This -function was first introduced in WFDB library version 6.0.) - - -File: wpg, Node: flushcal, Prev: newcal, Up: calibration - -flushcal --------- - - void flushcal() - -This function discards the current calibration list and returns the -memory that it occupied to the heap. Note that `wfdbquit' does _not_ -perform the function of `flushcal'. (This function was first -introduced in WFDB library version 6.0.) - - -File: wpg, Node: miscellaneous functions, Prev: calibration, Up: Functions - -Miscellaneous WFDB Functions -============================ - -* Menu: - -* newheader:: Creating a `hea' file for a new WFDB - record. -* setheader:: Creating or changing a `hea' file. -* setmsheader:: Creating a `hea' for a multi-segment - record. -* wfdbquit:: Closing WFDB files. -* iannclose and oannclose:: Closing annotation files. -* wfdbquiet and wfdbverbose:: Suppressing error messages from the WFDB library. -* wfdberror:: Retrieving error messages from the WFDB library. -* sampfreq:: Reading the sampling frequency of a WFDB record. -* setsampfreq:: Setting the sampling frequency. -* setbasetime:: Setting the base time. -* setgvmode:: Setting the resolution for a multifrequency - record. -* getspf:: Determining the number of samples per frame. -* counter conversion:: Functions for reading and setting counter - conversion parameters. -* setwfdb:: Dynamically changing the database path. -* getwfdb:: Reading the database path. -* wfdbfile:: Obtaining the pathname of a WFDB file. -* wfdbflush:: Flushing buffered output annotations and - samples. -* getinfo:: Reading info strings from a `hea' file. -* putinfo:: Writing info strings into a `hea' file. -* setibsize:: Setting the default input buffer size. -* setobsize:: Setting the default output buffer size. -* wfdbgetskew:: Reading intersignal skew. -* wfdbsetskew:: Recording intersignal skew. -* wfdbgetstart:: Reading the prolog size in a signal file. -* wfdbsetstart:: Recording the prolog size in a signal file. - - -File: wpg, Node: newheader, Next: setheader, Prev: miscellaneous functions, Up: miscellaneous functions - -newheader ---------- - - int newheader(char *RECORD) - -*Return:* - 0 - Success - --1 - Failure: unable to create header file - -This function creates a `hea' file (in the current directory, unless -RECORD includes path information). Use `newheader' just after you have -finished writing the signal files, but before calling `wfdbquit'. If -RECORD begins with `+', the `+' is discarded and the remainder of -RECORD is taken as the record name. Otherwise, all of RECORD -(excluding any path information) is taken to be the record name. If -the record name is `-', the header file is written to the standard -output. Record names may include letters in lower or upper case, -digits, and underscores (`_'); they may not include any other -characters. If RECORD does not conform to these requirements, -`newheader' will return -1; *note Example 8::, for an illustration of -the use of `newheader' to check the validity of a record name. For -compatibility with the widest range of operating systems, keep record -names short (6 characters or less) and avoid those that are -distinguished by case alone. To avoid confusion with MIT DB and AHA DB -records, do not use three- or four-digit record names. - - -File: wpg, Node: setheader, Next: setmsheader, Prev: newheader, Up: miscellaneous functions - -setheader ---------- - - int setheader(char *RECORD, WFDB_Siginfo *SIARRAY, unsigned int NSIG) - -*Return:* - 0 - Success - --1 - Failure: unable to create header file - -This function creates or recreates a header file (in the current -directory) for the specified RECORD, based on the contents of the first -NSIG members of SIARRAY. The preferred way to create a header file for -a new record is using `newheader', which records signal checksum and -length variables maintained by `putvec'. The intended use of -`setheader' is for editing header files, e.g., to change recorded -signal gains from a calibration program, or to add signal descriptions -or "info" strings. In the following code fragment, the header file for -record `old' is used to create a header file for record `new': - - ... - int nsig, status; - WFDB_Siginfo *s; - - nsig = isigopen("old", NULL, 0); - s = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo)); - nsig = isigopen("old", s, -nsig); - if (nsig > 0) { - s[0].gain = 100.0; - status = setheader("new", s, (unsigned int)nsig); - } - ... - -The header file for record `new' will contain the same signal -information as that for record `old', except that the `gain' for signal -0 will have been changed as shown. Any "info" strings in the `hea' -file for record `old' must be copied explicitly; *note getinfo::, and -*note putinfo::. (This function was first introduced in WFDB library -version 5.0.) diff -Naur wfdb-10.2.5/doc/wpg/info/wpg-3 wfdb-10.2.6/doc/wpg/info/wpg-3 --- wfdb-10.2.5/doc/wpg/info/wpg-3 Sun Mar 10 11:37:36 2002 +++ wfdb-10.2.6/doc/wpg/info/wpg-3 Mon Jun 24 22:20:24 2002 @@ -1,6 +1,480 @@ This is wpg, produced by makeinfo version 4.0b from wpg.tex.  +File: wpg, Node: timstr and strtim, Next: datstr and strdat, Prev: annstr and strann, Up: conversion + + The next three functions convert between "standard time format" +strings and times in units of sample intervals. Normally they should be +invoked after `isigopen', `wfdbinit', or `sampfreq', any of which will +determine the duration of a sample interval and the base time from a +header file, or after defining these quantities using `setsampfreq' and +`setbasetime'. If this is not done, or if these time-conversion +functions are used after `wfdbquit', they will perform conversions in +units of seconds (i.e., the sample interval is taken to be one second +in such cases). + +[ms]timstr +---------- + + char *timstr(WFDB_Time T) + char *mstimstr(WFDB_Time T) + +*Return:* +(char *) + pointer to a string that represents the time + +These functions convert times or time intervals into null-terminated +ASCII strings. If the argument, T, is greater than zero, it is treated +as a time interval, and converted directly into HH:MM:SS format by +`timstr', or to HH:MM:SS.SSS format by `mstimstr', with leading zero +digits and colons suppressed. If T is zero or negative, it is taken to +represent negated elapsed time from the beginning of the record, and it +is converted to a time of day using the base time for the record as +indicated by the `hea' file or the caller (*note setbasetime::); in +this case, if the base time is defined, the string will contain all +digits even if there are leading zeroes, it will include the date if a +base date is defined, and it will be marked as a time of day by being +bracketed (e.g., `[08:45:00 23/04/1989]'). The result of the +conversion is truncated to a multiple of a second by `timstr', or to a +multiple of a millisecond by `mstimstr'. Note in each case that the +returned pointer addresses static data (shared by `timstr' and +`mstimstr'), the contents of which are overwritten by subsequent calls. +*Note Example 3::, for an illustration of the use of `mstimstr'; also +*note Example 5::, for an example of the use of `timstr'. + +strtim +------ + + WFDB_Time strtim(char *STRING) + +*Return:* +(WFDB_Time) >0 + number of sample intervals corresponding to the argument + interpreted as a time interval + +(WFDB_Time) <0 + (negated) elapsed time in sample intervals from the beginning of + the record, corresponding to the argument interpreted as a time of + day + +(WFDB_Time) 0 + a legal return if the argument matches the base time; otherwise + an error return indicating an incorrectly formatted argument + +This function converts an ASCII string in "standard time format" to a +time in units of sample intervals. Examples of standard time format: +`2:14.875' + 2 minutes + 14.875 seconds + +`[13:6:0]' + 13:06 (1:06 PM) + +`[8:0:0 1]' + 8 AM on the day following the base date + +`[12:0:0 1/3/1992]' + noon on 1 March 1992 + +`143' + 143 seconds (2 minutes + 23 seconds) + +`4:02:01' + 4 hours + 2 minutes + 1 second + +`s12345' + 12345 sample intervals + +`c350.5' + counter value 350.5 + +`e' + time of the end of the record (if defined) + +`i' + time of the next sample in input signal 0 + +`o' + (the letter `o') time of the next sample in output signal 0 + + If the argument is bracketed (as in the second, third, and fourth +examples), it is taken as a time of day, and `strtim' uses the base +time defined by the header file or by the caller (*note setbasetime::); +in this case, the value returned is zero or negative (and can be +converted into elapsed time from the beginning of the record by simply +negating it). If the argument is not bracketed, it is taken as a time +interval, and converted directly into a positive number of sample +intervals. These notations match those used by `timstr' and +`mstimstr', which are (approximately) inverse functions of `strtim'; in +fact, for MIT DB and AHA DB records (and any others with sampling +frequencies below 1 KHz), `strtim(mstimstr(T))' = T, for any T. The +`s'-format (as in the seventh example above) is provided to allow +"conversion" of time intervals already expressed in sample intervals. +The similar `c'-format converts counter values (*note counter +conversion::) into sample intervals. The length of the record in +sample intervals can be obtained using `strtim("e")', which evaluates +to zero if this quantity is undefined. The sample number of the next +sample to be read or written can be determined using `strtim("i")' or +`strtim("o")'. If the argument string is incorrectly formatted, +`strtim' returns zero (indistinguishable from a correct input that +evokes a zero output); this may be considered a feature. Several of +the programs in chapter 6 illustrate the use of `strtim' (for example, +*note Example 7::). + + +File: wpg, Node: datstr and strdat, Next: aduphys and physadu, Prev: timstr and strtim, Up: conversion + + The next two functions convert between Julian dates and ASCII +strings. Julian dates as defined by astronomers begin at noon GMT; +these begin at midnight local time. + +datstr +------ + + char *datstr(WFDB_Date DATE) + +*Return:* +(char *) + pointer to a string that represents the date + +This function converts the Julian date represented by DATE into an +ASCII string in the form DD/MM/YYYY. + +strdat +------ + + WFDB_Date strdat(char *STRING) + +*Return:* +(WFDB_Date) + Julian date corresponding to the argument + +This function converts STRING into a Julian date. The argument should +be in the format used by `datstr'; if STRING is improperly formatted, +`strdat' returns zero. Note that dates such as `15/3/89' refer to the +first century A.D., not the twentieth. For example, the interval in +days between the events commemorated by the French and American +national holidays is `strdat("14/7/1789")' - `strdat("4/7/1776")'. + + + + +File: wpg, Node: aduphys and physadu, Prev: datstr and strdat, Up: conversion + + The next four functions convert between analog-to-digital converter +(ADC) units and physical units, using as a conversion factor the gain +for the specified input signal. The first two (`aduphys' and +`physadu') are general-purpose functions that convert absolute levels +(i.e., they account for non-zero `baseline' values); the last two +(`adumuv' and `muvadu') are for use with millivolt-dimensioned signals +only, and convert potential differences (i.e., `adumuv(S, 0)' = +`muvadu(S, 0)' = 0 for all S, irrespective of the `baseline' values +specified in the header file). Normally, these functions should be +invoked after `isigopen' or `wfdbinit', either of which will determine +the gain from the `hea' file. If this is not done, or if the header +file indicates that the gain is uncalibrated, or if the specified input +signal is not currently open, a gain of `WFDB_DEFGAIN' (defined in +`') ADC units per millivolt, and a baseline of zero, are +assumed. If the physical units (*note WFDB_Siginfo structures::) are +not millivolts, `adumuv' and `muvadu' convert to and from thousandths +of the defined physical units. Note that `adumuv' and `muvadu' deal +exclusively with integers, but `aduphys' returns and `physadu' accepts +double-precision floating point physical values. + +aduphys +------- + + double aduphys(WFDB_Signal S, WFDB_Sample A) + +*Return:* +(double) + physical value corresponding to a sample value of A ADC units + +This function converts the sample value A from ADC units to physical +units, based on the `gain' and `baseline' for input signal S. +(`aduphys' was first introduced in WFDB library version 6.0.) + +physadu +------- + + WFDB_Sample physadu(WFDB_Signal S, double V) + +*Return:* +(WFDB_Sample) + sample value, in ADC units, corresponding to V, in physical units + +This function converts the value V from physical units to ADC units, +based on the `gain' and `baseline' for input signal S. (`physadu' was +first introduced in WFDB library version 6.0.) + +adumuv +------ + + int adumuv(WFDB_Signal S, WFDB_Sample A) + +*Return:* +(int) + number of microvolts corresponding to A ADC units + +This function converts the potential difference A from ADC units to +microvolts, based on the `gain' for input signal S. + +muvadu +------ + + WFDB_Sample muvadu(WFDB_Signal S, int V) + +*Return:* +(int) + number of ADC units corresponding to V microvolts + +This function converts the potential difference V from microvolts to +ADC units, based on the `gain' for input signal S. + + +File: wpg, Node: calibration, Next: miscellaneous functions, Prev: conversion, Up: Functions + +Calibration Functions +===================== + + Functions in this section are used to determine specifications for +calibration pulses and customary scales for plotting signals. All of +them make use of the "calibration list", which is maintained in memory +and which contains entries for various types of signals. + +* Menu: + +* calopen:: read a calibration file into list +* getcal:: retrieve calibration data from list +* putcal:: append calibration data to list +* newcal:: write calibration list to a file +* flushcal:: discard contents of calibration list + + +File: wpg, Node: calopen, Next: getcal, Prev: calibration, Up: calibration + +calopen +------- + + int calopen(char *FILE) + +*Return:* + 0 + Success + +-1 + Failure: insufficient memory for calibration list + +-2 + Failure: unable to open calibration file + +This function reads the specified calibration FILE (which must be +located in one of the directories specified by `WFDB', *note WFDB +path::) into the calibration list. If FILE is `NULL', the file named +by `WFDBCAL' is read. Normally, the current contents of the +calibration list are discarded before reading the calibration file; if +FILE begins with `+', however, the `+' is stripped from the file name +and the contents of the file are appended to the current calibration +list. If FILE is `-', `calopen' reads the standard input rather than a +calibration file. (This function was first introduced in WFDB library +version 6.0.) + + +File: wpg, Node: getcal, Next: putcal, Prev: calopen, Up: calibration + +getcal +------ + + int getcal(char *DESC, char *UNITS, WFDB_Calinfo *CAL) + +*Return:* + 0 + Success; `*CAL' contains the requested data + +-1 + Failure: no match found + +This function attempts to find calibration data for signals of type +DESC, having physical units as given by UNITS. If successful, it fills +in the contents of the `WFDB_Calinfo' structure (*note WFDB_Calinfo +structures::) pointed to by CAL. The caller must allocate storage for +the `WFDB_Calinfo' structure, and must not modify the contents of the +strings addressed by the `sigtype' and `units' fields of the +`WFDB_Calinfo' structure after `getcal' returns. `getcal' returns data +from the first entry in the calibration list that contains a `sigtype' +field that is either an exact match or a prefix of DESC, and a `units' +field that is an exact match of UNITS; if either DESC or UNITS is +`NULL', however, it is ignored for the purpose of finding a match. +`getcal' cannot succeed unless the calibration list has been +initialized by a previous invocation of `calopen' or `putcal'. (This +function was first introduced in WFDB library version 6.0.) + + +File: wpg, Node: putcal, Next: newcal, Prev: getcal, Up: calibration + +putcal +------ + + int putcal(WFDB_Calinfo *CAL) + +*Return:* + 0 + Success + +-1 + Failure: insufficient memory + +This function adds the `WFDB_Calinfo' structure pointed to by CAL to +the end of the calibration list. (This function was first introduced +in WFDB library version 6.0.) + + +File: wpg, Node: newcal, Next: flushcal, Prev: putcal, Up: calibration + +newcal +------ + + int newcal(char *FILE) + +*Return:* + 0 + Success + +-1 + Failure: unable to open FILE + +This function creates a new calibration FILE (in the current directory) +containing the contents of the calibration list (which is not +modified). FILE must satisfy the standard conditions for a WFDB file +name, i.e., it may contain letters, digits, or underscores. (This +function was first introduced in WFDB library version 6.0.) + + +File: wpg, Node: flushcal, Prev: newcal, Up: calibration + +flushcal +-------- + + void flushcal() + +This function discards the current calibration list and returns the +memory that it occupied to the heap. Note that `wfdbquit' does _not_ +perform the function of `flushcal'. (This function was first +introduced in WFDB library version 6.0.) + + +File: wpg, Node: miscellaneous functions, Prev: calibration, Up: Functions + +Miscellaneous WFDB Functions +============================ + +* Menu: + +* newheader:: Creating a `hea' file for a new WFDB + record. +* setheader:: Creating or changing a `hea' file. +* setmsheader:: Creating a `hea' for a multi-segment + record. +* wfdbquit:: Closing WFDB files. +* iannclose and oannclose:: Closing annotation files. +* wfdbquiet and wfdbverbose:: Suppressing error messages from the WFDB library. +* wfdberror:: Retrieving error messages from the WFDB library. +* sampfreq:: Reading the sampling frequency of a WFDB record. +* setsampfreq:: Setting the sampling frequency. +* setbasetime:: Setting the base time. +* counter conversion:: Functions for reading and setting counter + conversion parameters. +* setwfdb:: Dynamically changing the database path. +* getwfdb:: Reading the database path. +* wfdbfile:: Obtaining the pathname of a WFDB file. +* wfdbflush:: Flushing buffered output annotations and + samples. +* getinfo:: Reading info strings from a `hea' file. +* putinfo:: Writing info strings into a `hea' file. +* setibsize:: Setting the default input buffer size. +* setobsize:: Setting the default output buffer size. +* wfdbgetskew:: Reading intersignal skew. +* wfdbsetskew:: Recording intersignal skew. +* wfdbgetstart:: Reading the prolog size in a signal file. +* wfdbsetstart:: Recording the prolog size in a signal file. + + +File: wpg, Node: newheader, Next: setheader, Prev: miscellaneous functions, Up: miscellaneous functions + +newheader +--------- + + int newheader(char *RECORD) + +*Return:* + 0 + Success + +-1 + Failure: unable to create header file + +This function creates a `hea' file (in the current directory, unless +RECORD includes path information). Use `newheader' just after you have +finished writing the signal files, but before calling `wfdbquit'. If +RECORD begins with `+', the `+' is discarded and the remainder of +RECORD is taken as the record name. Otherwise, all of RECORD +(excluding any path information) is taken to be the record name. If +the record name is `-', the header file is written to the standard +output. Record names may include letters in lower or upper case, +digits, and underscores (`_'); they may not include any other +characters. If RECORD does not conform to these requirements, +`newheader' will return -1; *note Example 8::, for an illustration of +the use of `newheader' to check the validity of a record name. For +compatibility with the widest range of operating systems, keep record +names short (6 characters or less) and avoid those that are +distinguished by case alone. To avoid confusion with MIT DB and AHA DB +records, do not use three- or four-digit record names. + + +File: wpg, Node: setheader, Next: setmsheader, Prev: newheader, Up: miscellaneous functions + +setheader +--------- + + int setheader(char *RECORD, WFDB_Siginfo *SIARRAY, unsigned int NSIG) + +*Return:* + 0 + Success + +-1 + Failure: unable to create header file + +This function creates or recreates a header file (in the current +directory) for the specified RECORD, based on the contents of the first +NSIG members of SIARRAY. The preferred way to create a header file for +a new record is using `newheader', which records signal checksum and +length variables maintained by `putvec'. The intended use of +`setheader' is for editing header files, e.g., to change recorded +signal gains from a calibration program, or to add signal descriptions +or "info" strings. In the following code fragment, the header file for +record `old' is used to create a header file for record `new': + + ... + int nsig, status; + WFDB_Siginfo *s; + + nsig = isigopen("old", NULL, 0); + s = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo)); + nsig = isigopen("old", s, -nsig); + if (nsig > 0) { + s[0].gain = 100.0; + status = setheader("new", s, (unsigned int)nsig); + } + ... + +The header file for record `new' will contain the same signal +information as that for record `old', except that the `gain' for signal +0 will have been changed as shown. Any "info" strings in the `hea' +file for record `old' must be copied explicitly; *note getinfo::, and +*note putinfo::. (This function was first introduced in WFDB library +version 5.0.) + + File: wpg, Node: setmsheader, Next: wfdbquit, Prev: setheader, Up: miscellaneous functions setmsheader @@ -195,7 +669,7 @@ an illustration of the use of `setsampfreq'.  -File: wpg, Node: setbasetime, Next: setgvmode, Prev: setsampfreq, Up: miscellaneous functions +File: wpg, Node: setbasetime, Next: counter conversion, Prev: setsampfreq, Up: miscellaneous functions setbasetime ----------- @@ -219,59 +693,10 @@ a header file (*note newheader::). *Note Example 8::, for an illustration of the use of `setbasetime'. - -File: wpg, Node: setgvmode, Next: getspf, Prev: setbasetime, Up: miscellaneous functions -setgvmode ---------- - - void setgvmode(int *MODE) - -This function sets the mode used by `getvec' when reading a -multi-frequency record (*note Multi-Frequency Records::). If MODE is -`WFDB_LOWRES', `getvec' decimates any signals sampled at multiples of -the frame rate, so that one sample is returned per signal per frame -(i.e., the oversampled signals are resampled by simple averaging of the -samples for each signal within each frame). If MODE is `WFDB_HIGHRES', -each sample of any oversampled signal is returned by successive -invocations of `getvec', and each sample of any signal sampled at a -lower frequency is returned by two or more successive invocations of -`getvec' (i.e., the less frequently sampled signals are resampled using -zero-order interpolation). `getvec' operates in `WFDB_LOWRES' mode by -default. `WFDB_LOWRES' and `WFDB_HIGHRES' are defined in -`'. - - In WFDB library version 9.6 and later versions, `setgvmode' also -affects how annotations are read and written. If -`setgvmode(WFDB_HIGHRES)' is invoked _before_ using `annopen', -`wfdbinit', `getvec', `sampfreq', `strtim', or `timstr', then all -`WFDB_Time' data (including the `time' attributes of annotations read -by `getann' or written by `putann') visible to the application are in -units of the high-resolution sampling intervals. (Otherwise, -`WFDB_Time' data are in units of frame intervals.)  -File: wpg, Node: getspf, Next: counter conversion, Prev: setgvmode, Up: miscellaneous functions - -getspf ------- - - int getspf(void) - -*Return:* -(int) - the number of samples per signal per frame - -Unless the application has used `setgvmode(WFDB_HIGHRES)' and has then -opened a multi-frequency record, this function returns 1. For the case -of a multi-frequency record being read in high resolution mode, -however, `getspf' returns the number of samples per signal per frame -(hence `sampfreq(NULL)/getspf()' is the number of frames per second). - - - - -File: wpg, Node: counter conversion, Next: setwfdb, Prev: getspf, Up: miscellaneous functions +File: wpg, Node: counter conversion, Next: setwfdb, Prev: setbasetime, Up: miscellaneous functions Database records are sometimes obtained from analog tapes for which a tape counter is available. Since many analog tape recorders lack @@ -913,333 +1338,4 @@ The calibration list is a memory-resident linked list of `WFDB_Calinfo' structures. It is accessible only via `calopen', `getcal', `putcal', `newcal', and `flushcal'. - - -File: wpg, Node: WFDB_Anninfo structures, Next: WFDB_Annotation structures, Prev: WFDB_Calinfo structures, Up: Data Types - -Annotator Information Structures -================================ - - The AIARRAY argument for `annopen' and `wfdbinit' is a pointer to an -array of objects of type `WFDB_Anninfo'. Each member of the array -contains information provided to `annopen' and `wfdbinit' about an -annotation file associated with the record: - -`char *name' - the annotator name. The name `atr' is reserved for a "reference - annotation file" supplied by the creator of the database record to - document its contents as accurately and thoroughly as possible. - You may use other annotator names to identify annotation files - that you create; unless there are compelling reasons not to do so, - follow the convention that the annotator name is the name of the - file's creator (a program or a person). To avoid confusion, do - not use `dat', `dataN', `dN', or `hea' (all of which are commonly - used as parts of WFDB file names) as annotator names. The special - name `-' refers to the standard input or output. Other annotator - names may contain upper- or lower-case letters, digits, and - underscores. Annotation files are normally created in the current - directory and found in any of the directories in the database path - (*note WFDB path::). - -`int stat' - the file type/access code. Usually, `stat' is either `WFDB_READ' - or `WFDB_WRITE', to specify standard ("MIT format") annotation - files to be read by `getann' or to be written by `putann'. Both - MIT DB and AHA DB annotation files are kept on-line in MIT format. - The symbols `WFDB_READ' and `WFDB_WRITE' are defined in - `'. An AHA-format annotation file can be read by - `getann' or written by `putann' if the `stat' field is set to - `WFDB_AHA_READ' or `WFDB_AHA_WRITE' before calling `annopen' or - `wfdbinit' (*note Example 2::). Other formats may be supported - via a similar mechanism; consult `' for more - information. - - The number of `WFDB_Anninfo' objects in AIARRAY is given by the NANN -argument of `annopen' and `wfdbinit'. The annotation-reading function, -`getann', knows the annotators by number only; `annopen' and `wfdbinit' -assign input annotator numbers beginning with 0 in the order in which -they are given in the array of `WFDB_Anninfo' objects. Output -annotator numbers used by `putann' also start at 0; note that input -annotator 0 and output annotator 0 are distinct. Annotator numbers are -supplied to `getann' and `putann' in their first arguments. *Note -annopen::, for an example of how to set the contents of an array of -`WFDB_Anninfo' objects. - - -File: wpg, Node: WFDB_Annotation structures, Prev: WFDB_Anninfo structures, Up: Data Types - -Annotation Structures -===================== - - The ANNOT argument of `getann' and `putann' is an object of type -`WFDB_Annotation' containing these fields: - -`long time' - time of the annotation, in samples from the beginning of the - record. The times of beat annotations in the `atr' files for the - MIT DB generally coincide with the R-wave peak in signal 0; for - the AHA DB, they generally coincide with the PQ-junction. - -`char anntyp' - annotation code; an integer between 1 and `ACMAX'. *Note - Annotation Codes::, for a list of legal annotation codes. `ACMAX' - is defined in `'. - -`signed char subtyp' -`signed char chan' -`signed char num' - numbers between -128 and 127. In MIT DB `atr' files, the `subtyp' - field is used with noise and artifact annotations to indicate - which signals are affected (*note Annotation Codes::). The `chan' - field is intended to indicate the signal to which the annotation - is attached. More than one annotation may be written with the - same `time' if the `chan' fields are distinct and in ascending - order. The semantics of the `chan' field are unspecified, - however; users may assign any desired meaning, which need not have - anything to do with signal numbers. In user-created annotation - files, these fields can be used to store arbitrary small integers. - The `subtyp' field requires no space in a standard annotation file - unless it is non-zero; the `chan' and `num' fields require no - space unless they have changed since the previous annotation. - -`char *aux' - a free text string. The first byte is interpreted as an `unsigned - char' that specifies the number of bytes that follow (up to 255). - In MIT DB `atr' files, the `aux' field is used with rhythm change - annotations to specify the new rhythm, and with comment - annotations to store the text of the comment The string can - contain arbitrary binary data, including embedded nulls. It is - unwise to store anything but ASCII strings, however, if the - annotation file may be transported to a system with a different - architecture (e.g., on which multiple-byte quantities may have - different sizes or byte layouts). The `aux' field requires no - space in a standard annotation file if it is `NULL'. Note that - conversion of annotation files to other formats may entail - truncation or loss of the `aux' string. Note also that the `aux' - pointer returned by `getann' points to a small static buffer - (separately allocated for each input annotator beginning with WFDB - library version 9.4) that may be overwritten by subsequent calls. - - *Note Example 3::, for a short program that examines the contents of -a `WFDB_Annotation'. - - -File: wpg, Node: Annotation Codes, Next: Database Files, Prev: Data Types, Up: Top - -Annotation Codes -**************** - -* Menu: - -* Mapping macros:: Macros for mapping annotation codes. - - Application programs that deal with annotations should include the -line - - #include - -which provides the symbolic definitions of annotation codes given in the -first column of the table below. (The second column of the table shows -the strings returned by `annstr' and `ecgstr'.) - - _Beat annotation codes:_ - NORMAL N Normal beat - LBBB L Left bundle branch block beat - RBBB R Right bundle branch block beat - BBB B Bundle branch block beat (unspecified) - APC A Atrial premature beat - ABERR a Aberrated atrial premature beat - NPC J Nodal (junctional) premature beat - SVPB S Supraventricular premature or ectopic beat (atrial or nodal) - PVC V Premature ventricular contraction - RONT r R-on-T premature ventricular contraction - FUSION F Fusion of ventricular and normal beat - AESC e Atrial escape beat - NESC j Nodal (junctional) escape beat - SVESC n Supraventricular escape beat (atrial or nodal) [1] - VESC E Ventricular escape beat - PACE / Paced beat - PFUS f Fusion of paced and normal beat - UNKNOWN Q Unclassifiable beat - LEARN ? Beat not classified during learning - - _Non-beat annotation codes:_ - VFON [ Start of ventricular flutter/fibrillation - FLWAV ! Ventricular flutter wave - VFOFF ] End of ventricular flutter/fibrillation - NAPC x Non-conducted P-wave (blocked APC) [4] - WFON ( Waveform onset [4] - WFOFF ) Waveform end [4] - PWAVE p Peak of P-wave [4] - TWAVE t Peak of T-wave [4] - UWAVE u Peak of U-wave [4] - PQ ` PQ junction - JPT ' J-point - PACESP ^ (Non-captured) pacemaker artifact - ARFCT | Isolated QRS-like artifact [2] - NOISE ~ Change in signal quality [2] - RHYTHM + Rhythm change [3] - STCH s ST segment change [1,3] - TCH T T-wave change [1,3,4] - SYSTOLE * Systole [1] - DIASTOLE D Diastole [1] - MEASURE = Measurement annotation [1,3] - NOTE " Comment annotation [3] - LINK @ Link to external data [5] - -*Notes:* - 1. Codes `SVESC', `STCH', and `TCH' were first introduced in WFDB - library version 4.0. Codes `SYSTOLE', `DIASTOLE', and `MEASURE' - were first introduced in WFDB library version 7.0. - - 2. In MIT and ESC DB `atr' files, each non-zero bit in the `subtyp' - field indicates that the corresponding signal contains noise (the - least significant bit corresponds to signal 0). - - 3. The `aux' field contains an ASCII string (with prefixed byte count) - describing the rhythm, ST segment, T-wave change, measurement, or - the nature of the comment. By convention, the character that - follows the byte count in the `aux' field of a `RHYTHM' annotation - is `('. See the `MIT-BIH Arrhythmia Database Directory' for a - list of rhythm annotation strings. - - 4. Codes `WFON', `WFOFF', `PWAVE', `TWAVE', and `UWAVE' were first - introduced in DB library version 8.3. The `p' mnemonic now - assigned to `PWAVE' was formerly assigned to `NAPC', and the `t' - mnemonic now assigned to `TWAVE' was formerly assigned to `TCH'. - The obsolete codes `PQ' (designating the PQ junction) and `JPT' - (designating the J-point) are still defined in - `', but are identical to `WFON' and `WFOFF' - respectively. - - 5. The `LINK' code was first introduced in WFDB library version 9.6. - The `aux' field of a `LINK' annotation contains a URL (a uniform - resource locator, in the form `http://machine.name/some/data', - suitable for passing to a Web browser such as Netscape or Mosaic). - `LINK' annotations may be used to associate extended text, - images, or other data with an annotation file. If the `aux' field - contains any whitespace, text following the first whitespace is - taken as descriptive text to be displayed by a WFDB browser such - as `WAVE'. - - - The annotation codes in the table above are the predefined values of -the `anntyp' field in a `WFDB_Annotation'. Other values in the range -of 1 to `ACMAX' (defined in `') are legal but do not -have preassigned meanings. The constant `NOTQRS', also defined in -`', is not a legal value for `anntyp', but is a -possible output of the macros discussed below. - - -File: wpg, Node: Mapping macros, Prev: Annotation Codes, Up: Annotation Codes - -Macros for Mapping Annotation Codes -=================================== - - Application programs that use the macros described in this section -should include the line - #include - -which will make their definitions, and those in `', -available. - -`isann(C)' - true (1) if C is a legal annotation code, false (0) otherwise - -`isqrs(C)' - true (1) if C denotes a QRS complex, false (0) otherwise - -`map1(C)' - maps C into one of the set {`NOTQRS', `NORMAL', `PVC', `FUSION', - `LEARN'} - -`map2(C)' - maps C into one of the set {`NOTQRS', `NORMAL', `SVPB', `PVC', - `FUSION', `LEARN'} - -`annpos(C)' - maps C into one of the set {`APUNDEF', `APSTD', `APHIGH', `APLOW', - `APATT', `APAHIGH', `APALOW'} (see `' for - definitions of these symbols; this macro was first introduced in - WFDB library version 6.0) - - If you define your own annotation codes, you may wish to modify the -tables used by the macros above. The file `' also -defines `setisqrs(C, X)', `setmap1(C, X)', `setmap2(C, X)', and -`setannpos(C, X)' for this purpose. In each case, X is the value to be -returned when the corresponding mapping macro is invoked with an -argument of C. (These macros were first introduced in WFDB library -version 6.0.) - - The macros below convert between AHA and MIT annotation codes; they -are also defined in `'. - -`ammap(A)' - maps A (an AHA annotation code) into an MIT annotation code (one - of the set {`NORMAL', `PVC', `FUSION', `RONT', `VESC', `PACE', - `UNKNOWN', `VFON', `VFOFF', `NOISE', `NOTE'}), or `NOTQRS' - -`mamap(C, S)' - maps C (an MIT annotation code) into an AHA annotation code (one - of the set {`N', `V', `F', `R', `E', `P', `Q', `[', `]', `U', - `O'}); S is the MIT annotation `subtyp' (significant only if C is - `NOISE') - - -File: wpg, Node: Database Files, Next: Examples, Prev: Annotation Codes, Up: Top - -Database Files -************** - - The WFDB library has been constructed to provide a standard interface -between the database files and application programs. Alternate means of -access to database files is strongly discouraged, since file formats may -change. Database files are located in the directories specified by -`WFDB' (*note WFDB path::). - - Recall that a WFDB record is not a file; rather, it is an extensible -_collection_ of database files (*note Records: Concepts 1.). Thus, for -example, record 100 of the MIT-BIH Arrhythmia Database consists of the -files named `100.hea', `100.dat', and `100.atr' in the `mitdb' -directory of the MIT-BIH Arrhythmia Database CD-ROM (or in PhysioBank, -within `http://www.physionet.org/physiobank/database/mitdb/'), together -with any additional files in other directories that you may have -associated with record 100 (such as your own annotation file). All -files associated with a given record include the record name as the -first part of the file name. No explicit action (other than choosing -the file name, and locating the file in the WFDB path) is needed in -order to associate a new file with an existing WFDB record. - - To find the location of a database file easily, you can use -`wfdbwhich', an application included with the WFDB Software Package. -Type `wfdbwhich' for brief instructions on its use, or see the `WFDB -Applications Guide'. - -File Types -========== - - There are four types of files supported by the WFDB library: - -* Menu: - -* Header Files:: contain signal file names and attributes. -* Signal Files:: contain signals. -* Annotation Files:: contain annotations. -* Calibration Files:: contain signal calibration specifications. - -The other topics in this section deal with special types of database access: - -* AHA Format Files:: not used for on-line WFDB records. -* Standard I/O:: pipes and I/O redirection for WFDB files. -* Multiplexed Signal Files:: signal groups. -* Multi-Frequency Records:: signals sampled at different frequencies within - within a given record. -* Multi-Segment Records:: concatenated records. -* Multiple Record Access:: how to have more than one record open. -* Special Files:: signal I/O using block and character devices. -* Piped and Local Records:: records for use with user-created signals. -* NETFILES:: input directly from web and FTP servers. -* Annotation Order:: the canonical order for annotations: - how and why to break the rules, and how - to deal with the consequences of doing so. diff -Naur wfdb-10.2.5/doc/wpg/info/wpg-4 wfdb-10.2.6/doc/wpg/info/wpg-4 --- wfdb-10.2.5/doc/wpg/info/wpg-4 Sun Mar 10 11:37:36 2002 +++ wfdb-10.2.6/doc/wpg/info/wpg-4 Mon Jun 24 22:20:24 2002 @@ -1,6 +1,335 @@ This is wpg, produced by makeinfo version 4.0b from wpg.tex.  +File: wpg, Node: WFDB_Anninfo structures, Next: WFDB_Annotation structures, Prev: WFDB_Calinfo structures, Up: Data Types + +Annotator Information Structures +================================ + + The AIARRAY argument for `annopen' and `wfdbinit' is a pointer to an +array of objects of type `WFDB_Anninfo'. Each member of the array +contains information provided to `annopen' and `wfdbinit' about an +annotation file associated with the record: + +`char *name' + the annotator name. The name `atr' is reserved for a "reference + annotation file" supplied by the creator of the database record to + document its contents as accurately and thoroughly as possible. + You may use other annotator names to identify annotation files + that you create; unless there are compelling reasons not to do so, + follow the convention that the annotator name is the name of the + file's creator (a program or a person). To avoid confusion, do + not use `dat', `dataN', `dN', or `hea' (all of which are commonly + used as parts of WFDB file names) as annotator names. The special + name `-' refers to the standard input or output. Other annotator + names may contain upper- or lower-case letters, digits, and + underscores. Annotation files are normally created in the current + directory and found in any of the directories in the database path + (*note WFDB path::). + +`int stat' + the file type/access code. Usually, `stat' is either `WFDB_READ' + or `WFDB_WRITE', to specify standard ("MIT format") annotation + files to be read by `getann' or to be written by `putann'. Both + MIT DB and AHA DB annotation files are kept on-line in MIT format. + The symbols `WFDB_READ' and `WFDB_WRITE' are defined in + `'. An AHA-format annotation file can be read by + `getann' or written by `putann' if the `stat' field is set to + `WFDB_AHA_READ' or `WFDB_AHA_WRITE' before calling `annopen' or + `wfdbinit' (*note Example 2::). Other formats may be supported + via a similar mechanism; consult `' for more + information. + + The number of `WFDB_Anninfo' objects in AIARRAY is given by the NANN +argument of `annopen' and `wfdbinit'. The annotation-reading function, +`getann', knows the annotators by number only; `annopen' and `wfdbinit' +assign input annotator numbers beginning with 0 in the order in which +they are given in the array of `WFDB_Anninfo' objects. Output +annotator numbers used by `putann' also start at 0; note that input +annotator 0 and output annotator 0 are distinct. Annotator numbers are +supplied to `getann' and `putann' in their first arguments. *Note +annopen::, for an example of how to set the contents of an array of +`WFDB_Anninfo' objects. + + +File: wpg, Node: WFDB_Annotation structures, Prev: WFDB_Anninfo structures, Up: Data Types + +Annotation Structures +===================== + + The ANNOT argument of `getann' and `putann' is an object of type +`WFDB_Annotation' containing these fields: + +`long time' + time of the annotation, in samples from the beginning of the + record. The times of beat annotations in the `atr' files for the + MIT DB generally coincide with the R-wave peak in signal 0; for + the AHA DB, they generally coincide with the PQ-junction. + +`char anntyp' + annotation code; an integer between 1 and `ACMAX'. *Note + Annotation Codes::, for a list of legal annotation codes. `ACMAX' + is defined in `'. + +`signed char subtyp' +`signed char chan' +`signed char num' + numbers between -128 and 127. In MIT DB `atr' files, the `subtyp' + field is used with noise and artifact annotations to indicate + which signals are affected (*note Annotation Codes::). The `chan' + field is intended to indicate the signal to which the annotation + is attached. More than one annotation may be written with the + same `time' if the `chan' fields are distinct and in ascending + order. The semantics of the `chan' field are unspecified, + however; users may assign any desired meaning, which need not have + anything to do with signal numbers. In user-created annotation + files, these fields can be used to store arbitrary small integers. + The `subtyp' field requires no space in a standard annotation file + unless it is non-zero; the `chan' and `num' fields require no + space unless they have changed since the previous annotation. + +`char *aux' + a free text string. The first byte is interpreted as an `unsigned + char' that specifies the number of bytes that follow (up to 255). + In MIT DB `atr' files, the `aux' field is used with rhythm change + annotations to specify the new rhythm, and with comment + annotations to store the text of the comment The string can + contain arbitrary binary data, including embedded nulls. It is + unwise to store anything but ASCII strings, however, if the + annotation file may be transported to a system with a different + architecture (e.g., on which multiple-byte quantities may have + different sizes or byte layouts). The `aux' field requires no + space in a standard annotation file if it is `NULL'. Note that + conversion of annotation files to other formats may entail + truncation or loss of the `aux' string. Note also that the `aux' + pointer returned by `getann' points to a small static buffer + (separately allocated for each input annotator beginning with WFDB + library version 9.4) that may be overwritten by subsequent calls. + + *Note Example 3::, for a short program that examines the contents of +a `WFDB_Annotation'. + + +File: wpg, Node: Annotation Codes, Next: Database Files, Prev: Data Types, Up: Top + +Annotation Codes +**************** + +* Menu: + +* Mapping macros:: Macros for mapping annotation codes. + + Application programs that deal with annotations should include the +line + + #include + +which provides the symbolic definitions of annotation codes given in the +first column of the table below. (The second column of the table shows +the strings returned by `annstr' and `ecgstr'.) + + _Beat annotation codes:_ + NORMAL N Normal beat + LBBB L Left bundle branch block beat + RBBB R Right bundle branch block beat + BBB B Bundle branch block beat (unspecified) + APC A Atrial premature beat + ABERR a Aberrated atrial premature beat + NPC J Nodal (junctional) premature beat + SVPB S Supraventricular premature or ectopic beat (atrial or nodal) + PVC V Premature ventricular contraction + RONT r R-on-T premature ventricular contraction + FUSION F Fusion of ventricular and normal beat + AESC e Atrial escape beat + NESC j Nodal (junctional) escape beat + SVESC n Supraventricular escape beat (atrial or nodal) [1] + VESC E Ventricular escape beat + PACE / Paced beat + PFUS f Fusion of paced and normal beat + UNKNOWN Q Unclassifiable beat + LEARN ? Beat not classified during learning + + _Non-beat annotation codes:_ + VFON [ Start of ventricular flutter/fibrillation + FLWAV ! Ventricular flutter wave + VFOFF ] End of ventricular flutter/fibrillation + NAPC x Non-conducted P-wave (blocked APC) [4] + WFON ( Waveform onset [4] + WFOFF ) Waveform end [4] + PWAVE p Peak of P-wave [4] + TWAVE t Peak of T-wave [4] + UWAVE u Peak of U-wave [4] + PQ ` PQ junction + JPT ' J-point + PACESP ^ (Non-captured) pacemaker artifact + ARFCT | Isolated QRS-like artifact [2] + NOISE ~ Change in signal quality [2] + RHYTHM + Rhythm change [3] + STCH s ST segment change [1,3] + TCH T T-wave change [1,3,4] + SYSTOLE * Systole [1] + DIASTOLE D Diastole [1] + MEASURE = Measurement annotation [1,3] + NOTE " Comment annotation [3] + LINK @ Link to external data [5] + +*Notes:* + 1. Codes `SVESC', `STCH', and `TCH' were first introduced in WFDB + library version 4.0. Codes `SYSTOLE', `DIASTOLE', and `MEASURE' + were first introduced in WFDB library version 7.0. + + 2. In MIT and ESC DB `atr' files, each non-zero bit in the `subtyp' + field indicates that the corresponding signal contains noise (the + least significant bit corresponds to signal 0). + + 3. The `aux' field contains an ASCII string (with prefixed byte count) + describing the rhythm, ST segment, T-wave change, measurement, or + the nature of the comment. By convention, the character that + follows the byte count in the `aux' field of a `RHYTHM' annotation + is `('. See the `MIT-BIH Arrhythmia Database Directory' for a + list of rhythm annotation strings. + + 4. Codes `WFON', `WFOFF', `PWAVE', `TWAVE', and `UWAVE' were first + introduced in DB library version 8.3. The `p' mnemonic now + assigned to `PWAVE' was formerly assigned to `NAPC', and the `t' + mnemonic now assigned to `TWAVE' was formerly assigned to `TCH'. + The obsolete codes `PQ' (designating the PQ junction) and `JPT' + (designating the J-point) are still defined in + `', but are identical to `WFON' and `WFOFF' + respectively. + + 5. The `LINK' code was first introduced in WFDB library version 9.6. + The `aux' field of a `LINK' annotation contains a URL (a uniform + resource locator, in the form `http://machine.name/some/data', + suitable for passing to a Web browser such as Netscape or Mosaic). + `LINK' annotations may be used to associate extended text, + images, or other data with an annotation file. If the `aux' field + contains any whitespace, text following the first whitespace is + taken as descriptive text to be displayed by a WFDB browser such + as `WAVE'. + + + The annotation codes in the table above are the predefined values of +the `anntyp' field in a `WFDB_Annotation'. Other values in the range +of 1 to `ACMAX' (defined in `') are legal but do not +have preassigned meanings. The constant `NOTQRS', also defined in +`', is not a legal value for `anntyp', but is a +possible output of the macros discussed below. + + +File: wpg, Node: Mapping macros, Prev: Annotation Codes, Up: Annotation Codes + +Macros for Mapping Annotation Codes +=================================== + + Application programs that use the macros described in this section +should include the line + #include + +which will make their definitions, and those in `', +available. + +`isann(C)' + true (1) if C is a legal annotation code, false (0) otherwise + +`isqrs(C)' + true (1) if C denotes a QRS complex, false (0) otherwise + +`map1(C)' + maps C into one of the set {`NOTQRS', `NORMAL', `PVC', `FUSION', + `LEARN'} + +`map2(C)' + maps C into one of the set {`NOTQRS', `NORMAL', `SVPB', `PVC', + `FUSION', `LEARN'} + +`annpos(C)' + maps C into one of the set {`APUNDEF', `APSTD', `APHIGH', `APLOW', + `APATT', `APAHIGH', `APALOW'} (see `' for + definitions of these symbols; this macro was first introduced in + WFDB library version 6.0) + + If you define your own annotation codes, you may wish to modify the +tables used by the macros above. The file `' also +defines `setisqrs(C, X)', `setmap1(C, X)', `setmap2(C, X)', and +`setannpos(C, X)' for this purpose. In each case, X is the value to be +returned when the corresponding mapping macro is invoked with an +argument of C. (These macros were first introduced in WFDB library +version 6.0.) + + The macros below convert between AHA and MIT annotation codes; they +are also defined in `'. + +`ammap(A)' + maps A (an AHA annotation code) into an MIT annotation code (one + of the set {`NORMAL', `PVC', `FUSION', `RONT', `VESC', `PACE', + `UNKNOWN', `VFON', `VFOFF', `NOISE', `NOTE'}), or `NOTQRS' + +`mamap(C, S)' + maps C (an MIT annotation code) into an AHA annotation code (one + of the set {`N', `V', `F', `R', `E', `P', `Q', `[', `]', `U', + `O'}); S is the MIT annotation `subtyp' (significant only if C is + `NOISE') + + +File: wpg, Node: Database Files, Next: Examples, Prev: Annotation Codes, Up: Top + +Database Files +************** + + The WFDB library has been constructed to provide a standard interface +between the database files and application programs. Alternate means of +access to database files is strongly discouraged, since file formats may +change. Database files are located in the directories specified by +`WFDB' (*note WFDB path::). + + Recall that a WFDB record is not a file; rather, it is an extensible +_collection_ of database files (*note Records: Concepts 1.). Thus, for +example, record 100 of the MIT-BIH Arrhythmia Database consists of the +files named `100.hea', `100.dat', and `100.atr' in the `mitdb' +directory of the MIT-BIH Arrhythmia Database CD-ROM (or in PhysioBank, +within `http://www.physionet.org/physiobank/database/mitdb/'), together +with any additional files in other directories that you may have +associated with record 100 (such as your own annotation file). All +files associated with a given record include the record name as the +first part of the file name. No explicit action (other than choosing +the file name, and locating the file in the WFDB path) is needed in +order to associate a new file with an existing WFDB record. + + To find the location of a database file easily, you can use +`wfdbwhich', an application included with the WFDB Software Package. +Type `wfdbwhich' for brief instructions on its use, or see the `WFDB +Applications Guide'. + +File Types +========== + + There are four types of files supported by the WFDB library: + +* Menu: + +* Header Files:: contain signal file names and attributes. +* Signal Files:: contain signals. +* Annotation Files:: contain annotations. +* Calibration Files:: contain signal calibration specifications. + +The other topics in this section deal with special types of database access: + +* AHA Format Files:: not used for on-line WFDB records. +* Standard I/O:: pipes and I/O redirection for WFDB files. +* Multiplexed Signal Files:: signal groups. +* Multi-Frequency Records:: signals sampled at different frequencies within + within a given record. +* Multi-Segment Records:: concatenated records. +* Multiple Record Access:: how to have more than one record open. +* Special Files:: signal I/O using block and character devices. +* Piped and Local Records:: records for use with user-created signals. +* NETFILES:: input directly from web and FTP servers. +* Annotation Order:: the canonical order for annotations: + how and why to break the rules, and how + to deal with the consequences of doing so. + + File: wpg, Node: Header Files, Next: Signal Files, Prev: Database Files, Up: Database Files Header Files @@ -363,9 +692,9 @@ (defined in the WFDB library source file `wfdblib.h', and used as the WFDB path if the WFDB environment variable is undefined) is `. /usr/database http://www.physionet.org/physiobank/database'. (The -second component,, after the `.' that specifies the current -directory,may vary, depending on your platform and the choices made -during installation.) The URL prefix (the third component) points to +second component, after the `.' that specifies the current directory, +may vary, depending on your platform and the choices made during +installation.) The URL prefix (the third component) points to PhysioBank, an on-line archive for a wide variety of standard databases of physiologic signals. The databases are kept in subdirectories of `http://www.physionet.org/physiobank/database'. For example, the @@ -467,6 +796,10 @@ examples can be compiled (under Unix) using a command of the form cc FILE.C -lwfdb +or, if the WFDB library or its `*.h' files are not in the standard +locations: + cc `wfdb-config --cflags` FILE.C `wfdb-config --libs` + where FILE.C is the name of the file containing the source; *note Using the WFDB Library: Usage., for further information. The sources for these examples are included in the WFDB Software Package, within the @@ -707,269 +1040,4 @@ This expression evaluates to an empty string unless the `aux' string is non-empty. It makes the assumption that `aux' is a printable ASCII string; the printable part follows the length byte. - - -File: wpg, Node: Example 4, Next: Example 5, Prev: Example 3, Up: Examples - -Example 4: Generating an R-R Interval Histogram -=============================================== - - This program reads an annotation file, determines the intervals -between beat annotations (assumed to be the R-R intervals), and -accumulates a histogram of them. - - 1 #include - 2 #include - 3 #include - 4 - 5 main(argc, argv) - 6 int argc; - 7 char *argv[]; - 8 { - 9 int rr, *rrhist, rrmax; - 10 long t; - 11 WFDB_Anninfo a; - 12 WFDB_Annotation annot; - 13 void *calloc(); - 14 - 15 if (argc < 3) { - 16 fprintf(stderr, "usage: %s annotator record\n", argv[0]); - 17 exit(1); - 18 } - 19 a.name = argv[1]; a.stat = WFDB_READ; - 20 if (annopen(argv[2], &a, 1) < 0) exit(2); - 21 if ((rrmax = (int)(3*sampfreq(argv[2]))) <= 0) exit(3); - 22 if ((rrhist = (int *)calloc(rrmax+1, sizeof(int))) == NULL) { - 23 fprintf(stderr, "%s: insufficient memory\n", argv[0]); - 24 exit(4); - 25 } - 26 while (getann(0, &annot) == 0 && !isqrs(annot.anntyp)) - 27 ; - 28 t = annot.time; - 29 while (getann(0, &annot) == 0) - 30 if (isqrs(annot.anntyp)) { - 31 if ((rr = annot.time - t) > rrmax) rr = rrmax; - 32 rrhist[rr]++; - 33 t = annot.time; - 34 } - 35 for (rr = 1; rr < rrmax; rr++) - 36 printf("%4d %s\n", rrhist[rr], mstimstr((long)rr)); - 37 printf("%4d %s (or longer)\n", rrhist[rr], mstimstr((long)rr)); - 38 exit(0); - 39 } - -*Notes:* -_Lines 21-25:_ - Here we allocate storage for the histogram. The value returned by - `sampfreq', if positive, specifies the number of sample intervals - per second; we will allocate 3 seconds' worth of bins, initialized - to zero. See `K&R', page 167, for a description of `calloc'. - -_Lines 26-28:_ - This code sets `t' to the time of the first annotated beat in the - record. - -_Lines 29-34:_ - Here we read the remainder of the annotations, skipping any - non-beat annotations. The difference between the values of - `annot.time' for consecutive beat annotations defines an R-R - interval (`rr'). Each possible value of `rr' up to `rrmax' is - assigned a bin in `rrhist'. Intervals longer than 3 seconds - (`rrmax') are counted in the bin corresponding to `rr' = `rrmax'. - -_Lines 35-37:_ - The histogram is printed as a two-column table, with the number of - intervals in the first column and the length of the interval (with - millisecond resolution) in the second column. (What happens if - `rr' starts at 0 rather than 1 in line 35?) - - -File: wpg, Node: Example 5, Next: Example 6, Prev: Example 4, Up: Examples - -Example 5: Reading Signal Specifications -======================================== - - This program reads the signal specifications of the record named as -its argument: - - 1 #include - 2 #include - 3 - 4 main(argc, argv) - 5 int argc; - 6 char *argv[]; - 7 { - 8 WFDB_Siginfo *s; - 9 int i, nsig; - 10 - 11 if (argc < 2) { - 12 fprintf(stderr, "usage: %s record\n", argv[0]); - 13 exit(1); - 14 } - 15 nsig = isigopen(argv[1], NULL, 0); - 16 if (nsig < 1) exit(2); - 17 s = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo)); - 18 if (s == NULL) { - 19 fprintf(stderr, "insufficient memory\n"); - 20 exit(3); - 21 } - 22 if (isigopen(argv[1], s, nsig) != nsig) exit(2); - 23 printf("Record %s\n", argv[1]); - 24 printf("Starting time: %s\n", timstr(0L)); - 25 printf("Sampling frequency: %g Hz\n", sampfreq(argv[1])); - 26 printf("%d signals\n", nsig); - 27 for (i = 0; i < nsig; i++) { - 28 printf("Group %d, Signal %d:\n", s[i].group, i); - 29 printf(" File: %s\n", s[i].fname); - 30 printf(" Description: %s\n", s[i].desc); - 31 printf(" Gain: "); - 32 if (s[i].gain == 0.) - 33 printf("uncalibrated; assume %g", WFDB_DEFGAIN); - 34 else printf("%g", s[i].gain); - 35 printf(" adu/%s\n", s[i].units ? s[i].units : "mV"); - 36 printf(" Initial value: %d\n", s[i].initval); - 37 printf(" Storage format: %d\n", s[i].fmt); - 38 printf(" I/O: "); - 39 if (s[i].bsize == 0) printf("can be unbuffered\n"); - 40 else printf("%d-byte blocks\n", s[i].bsize); - 41 printf(" ADC resolution: %d bits\n", s[i].adcres); - 42 printf(" ADC zero: %d\n", s[i].adczero); - 43 if (s[i].nsamp > 0L) { - 44 printf(" Length: %s (%ld sample intervals)\n", - 45 timstr(s[i].nsamp), s[i].nsamp); - 46 printf(" Checksum: %d\n", s[i].cksum); - 47 } - 48 else printf(" Length undefined\n"); - 49 } - 50 exit(0); - 51 } - -*Notes:* - -_Line 15:_ - The command-line argument, `argv[1]', is the record name. The - number of signals listed in the header file for the record is - returned by `isigopen' as `nsig'. If `nsig' < 1, `isigopen' will - print an error message; in this case the program can't do anything - useful, so it exits. - -_Line 17:_ - We allocate `nsig' signal information (`WFDB_Siginfo') objects. - -_Line 22:_ - On the second invocation of `isigopen', we pass the pointer to the - signal information objects and the number of signals we expect to - open. `isigopen' returns the number of signals it is able to - open; if any of those named in the header file are unreadable, - the return value will not match `nsig', and the program exits. - -_Line 24:_ - Invoking `timstr' with an argument of zero (here written `0L' to - emphasize to the compiler that the argument is a `long' integer) - will obtain the starting time of the record. If no starting time - is defined, `timstr' will return "`0:00:00'". - -_Lines 31-34:_ - Notice how a zero value for `gain' is interpreted. - -_Line 35:_ - If the `units' field is NULL, the physical units are assumed to be - millivolts ("mV"). - -_Lines 38-40:_ - If `bsize' is zero, I/O can be performed in blocks of any - reasonable size; otherwise it must be performed in blocks of - exactly the specified `bsize'. - -_Lines 43-48:_ - If the length of the record is defined, it is printed in both - hours, minutes, and seconds, and in sample intervals. Since the - argument of `timstr' in line 39 is positive, it is interpreted as - a time interval. The checksum is defined only if the record - length is defined. - - -File: wpg, Node: Example 6, Next: Example 7, Prev: Example 5, Up: Examples - -Example 6: A Differentiator -=========================== - - The program below inverts and differentiates the signals read by -`getvec' and writes the results with `putvec'. The output is readable -as record `dif'. A wide variety of simple digital filters can be -modelled on this example; *note Example 7::, for a more general -approach. - - 1 #include - 2 #include - 3 - 4 main(argc, argv) - 5 int argc; - 6 char *argv[]; - 7 { - 8 WFDB_Siginfo *s; - 9 int i, nsig, nsamp=1000; - 10 WFDB_Sample *vin, *vout; - 11 - 12 if (argc < 2) { - 13 fprintf(stderr, "usage: %s record\n", argv[0]); exit(1); - 14 } - 15 if ((nsig = isigopen(argv[1], NULL, 0)) <= 0) exit(2); - 16 s = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo)); - 17 vin = (WFDB_Sample *)malloc(nsig * sizeof(WFDB_Sample)); - 18 vout = (WFDB_Sample *)malloc(nsig * sizeof(WFDB_Sample)); - 19 if (s == NULL || vin == NULL || vout == NULL) { - 20 fprintf(stderr, "insufficient memory\n"); - 21 exit(3); - 22 } - 23 if (isigopen(argv[1], s, nsig) != nsig) exit(2); - 24 if (osigopen("8l", s, nsig) <= 0) exit(3); - 25 while (nsamp-- > 0 && getvec(vin) > 0) { - 26 for (i = 0; i < nsig; i++) - 27 vout[i] -= vin[i]; - 28 if (putvec(vout) < 0) break; - 29 for (i = 0; i < nsig; i++) - 30 vout[i] = vin[i]; - 31 } - 32 (void)newheader("dif"); - 33 wfdbquit(); - 34 exit(0); - 35 } - -*Notes:* - -_Line 24:_ - Here we attempt to open as many output signals as there are input - signals; if we cannot do so, the program exits after `osigopen' - prints an error message. - -_Line 25:_ - The main loop of the program begins here. If 1000 samples can be - read from each signal, the loop will end normally; if `getvec' - fails before 1000 samples have been read, the loop ends - prematurely. - -_Lines 26-27:_ - For each signal, we compute the negated first difference by - subtracting the new sample from the previous sample. - -_Line 28:_ - One sample of each output signal is written here. - -_Lines 29-30:_ - The new input samples are copied into the output sample vector in - preparation for the next iteration. - -_Line 32:_ - This step is optional. It creates a header file for a new record - to be called `dif', which we can then open with another program if - we want to read the signals that this program has written. Since - the RECORD argument for `osigopen' was `8l', we can also read - these files using record `8l'; one reason for making a new `hea' - file here is that the `hea' file for `8l' may not necessarily - indicate the proper sampling frequency for these signals. - -_Line 33:_ - Since the program writes output signals, it must invoke `wfdbquit' - to close the files properly. diff -Naur wfdb-10.2.5/doc/wpg/info/wpg-5 wfdb-10.2.6/doc/wpg/info/wpg-5 --- wfdb-10.2.5/doc/wpg/info/wpg-5 Sun Mar 10 11:37:36 2002 +++ wfdb-10.2.6/doc/wpg/info/wpg-5 Mon Jun 24 22:20:24 2002 @@ -1,6 +1,271 @@ This is wpg, produced by makeinfo version 4.0b from wpg.tex.  +File: wpg, Node: Example 4, Next: Example 5, Prev: Example 3, Up: Examples + +Example 4: Generating an R-R Interval Histogram +=============================================== + + This program reads an annotation file, determines the intervals +between beat annotations (assumed to be the R-R intervals), and +accumulates a histogram of them. + + 1 #include + 2 #include + 3 #include + 4 + 5 main(argc, argv) + 6 int argc; + 7 char *argv[]; + 8 { + 9 int rr, *rrhist, rrmax; + 10 long t; + 11 WFDB_Anninfo a; + 12 WFDB_Annotation annot; + 13 void *calloc(); + 14 + 15 if (argc < 3) { + 16 fprintf(stderr, "usage: %s annotator record\n", argv[0]); + 17 exit(1); + 18 } + 19 a.name = argv[1]; a.stat = WFDB_READ; + 20 if (annopen(argv[2], &a, 1) < 0) exit(2); + 21 if ((rrmax = (int)(3*sampfreq(argv[2]))) <= 0) exit(3); + 22 if ((rrhist = (int *)calloc(rrmax+1, sizeof(int))) == NULL) { + 23 fprintf(stderr, "%s: insufficient memory\n", argv[0]); + 24 exit(4); + 25 } + 26 while (getann(0, &annot) == 0 && !isqrs(annot.anntyp)) + 27 ; + 28 t = annot.time; + 29 while (getann(0, &annot) == 0) + 30 if (isqrs(annot.anntyp)) { + 31 if ((rr = annot.time - t) > rrmax) rr = rrmax; + 32 rrhist[rr]++; + 33 t = annot.time; + 34 } + 35 for (rr = 1; rr < rrmax; rr++) + 36 printf("%4d %s\n", rrhist[rr], mstimstr((long)rr)); + 37 printf("%4d %s (or longer)\n", rrhist[rr], mstimstr((long)rr)); + 38 exit(0); + 39 } + +*Notes:* +_Lines 21-25:_ + Here we allocate storage for the histogram. The value returned by + `sampfreq', if positive, specifies the number of sample intervals + per second; we will allocate 3 seconds' worth of bins, initialized + to zero. See `K&R', page 167, for a description of `calloc'. + +_Lines 26-28:_ + This code sets `t' to the time of the first annotated beat in the + record. + +_Lines 29-34:_ + Here we read the remainder of the annotations, skipping any + non-beat annotations. The difference between the values of + `annot.time' for consecutive beat annotations defines an R-R + interval (`rr'). Each possible value of `rr' up to `rrmax' is + assigned a bin in `rrhist'. Intervals longer than 3 seconds + (`rrmax') are counted in the bin corresponding to `rr' = `rrmax'. + +_Lines 35-37:_ + The histogram is printed as a two-column table, with the number of + intervals in the first column and the length of the interval (with + millisecond resolution) in the second column. (What happens if + `rr' starts at 0 rather than 1 in line 35?) + + +File: wpg, Node: Example 5, Next: Example 6, Prev: Example 4, Up: Examples + +Example 5: Reading Signal Specifications +======================================== + + This program reads the signal specifications of the record named as +its argument: + + 1 #include + 2 #include + 3 + 4 main(argc, argv) + 5 int argc; + 6 char *argv[]; + 7 { + 8 WFDB_Siginfo *s; + 9 int i, nsig; + 10 + 11 if (argc < 2) { + 12 fprintf(stderr, "usage: %s record\n", argv[0]); + 13 exit(1); + 14 } + 15 nsig = isigopen(argv[1], NULL, 0); + 16 if (nsig < 1) exit(2); + 17 s = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo)); + 18 if (s == NULL) { + 19 fprintf(stderr, "insufficient memory\n"); + 20 exit(3); + 21 } + 22 if (isigopen(argv[1], s, nsig) != nsig) exit(2); + 23 printf("Record %s\n", argv[1]); + 24 printf("Starting time: %s\n", timstr(0L)); + 25 printf("Sampling frequency: %g Hz\n", sampfreq(argv[1])); + 26 printf("%d signals\n", nsig); + 27 for (i = 0; i < nsig; i++) { + 28 printf("Group %d, Signal %d:\n", s[i].group, i); + 29 printf(" File: %s\n", s[i].fname); + 30 printf(" Description: %s\n", s[i].desc); + 31 printf(" Gain: "); + 32 if (s[i].gain == 0.) + 33 printf("uncalibrated; assume %g", WFDB_DEFGAIN); + 34 else printf("%g", s[i].gain); + 35 printf(" adu/%s\n", s[i].units ? s[i].units : "mV"); + 36 printf(" Initial value: %d\n", s[i].initval); + 37 printf(" Storage format: %d\n", s[i].fmt); + 38 printf(" I/O: "); + 39 if (s[i].bsize == 0) printf("can be unbuffered\n"); + 40 else printf("%d-byte blocks\n", s[i].bsize); + 41 printf(" ADC resolution: %d bits\n", s[i].adcres); + 42 printf(" ADC zero: %d\n", s[i].adczero); + 43 if (s[i].nsamp > 0L) { + 44 printf(" Length: %s (%ld sample intervals)\n", + 45 timstr(s[i].nsamp), s[i].nsamp); + 46 printf(" Checksum: %d\n", s[i].cksum); + 47 } + 48 else printf(" Length undefined\n"); + 49 } + 50 exit(0); + 51 } + +*Notes:* + +_Line 15:_ + The command-line argument, `argv[1]', is the record name. The + number of signals listed in the header file for the record is + returned by `isigopen' as `nsig'. If `nsig' < 1, `isigopen' will + print an error message; in this case the program can't do anything + useful, so it exits. + +_Line 17:_ + We allocate `nsig' signal information (`WFDB_Siginfo') objects. + +_Line 22:_ + On the second invocation of `isigopen', we pass the pointer to the + signal information objects and the number of signals we expect to + open. `isigopen' returns the number of signals it is able to + open; if any of those named in the header file are unreadable, + the return value will not match `nsig', and the program exits. + +_Line 24:_ + Invoking `timstr' with an argument of zero (here written `0L' to + emphasize to the compiler that the argument is a `long' integer) + will obtain the starting time of the record. If no starting time + is defined, `timstr' will return "`0:00:00'". + +_Lines 31-34:_ + Notice how a zero value for `gain' is interpreted. + +_Line 35:_ + If the `units' field is NULL, the physical units are assumed to be + millivolts ("mV"). + +_Lines 38-40:_ + If `bsize' is zero, I/O can be performed in blocks of any + reasonable size; otherwise it must be performed in blocks of + exactly the specified `bsize'. + +_Lines 43-48:_ + If the length of the record is defined, it is printed in both + hours, minutes, and seconds, and in sample intervals. Since the + argument of `timstr' in line 39 is positive, it is interpreted as + a time interval. The checksum is defined only if the record + length is defined. + + +File: wpg, Node: Example 6, Next: Example 7, Prev: Example 5, Up: Examples + +Example 6: A Differentiator +=========================== + + The program below inverts and differentiates the signals read by +`getvec' and writes the results with `putvec'. The output is readable +as record `dif'. A wide variety of simple digital filters can be +modelled on this example; *note Example 7::, for a more general +approach. + + 1 #include + 2 #include + 3 + 4 main(argc, argv) + 5 int argc; + 6 char *argv[]; + 7 { + 8 WFDB_Siginfo *s; + 9 int i, nsig, nsamp=1000; + 10 WFDB_Sample *vin, *vout; + 11 + 12 if (argc < 2) { + 13 fprintf(stderr, "usage: %s record\n", argv[0]); exit(1); + 14 } + 15 if ((nsig = isigopen(argv[1], NULL, 0)) <= 0) exit(2); + 16 s = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo)); + 17 vin = (WFDB_Sample *)malloc(nsig * sizeof(WFDB_Sample)); + 18 vout = (WFDB_Sample *)malloc(nsig * sizeof(WFDB_Sample)); + 19 if (s == NULL || vin == NULL || vout == NULL) { + 20 fprintf(stderr, "insufficient memory\n"); + 21 exit(3); + 22 } + 23 if (isigopen(argv[1], s, nsig) != nsig) exit(2); + 24 if (osigopen("8l", s, nsig) <= 0) exit(3); + 25 while (nsamp-- > 0 && getvec(vin) > 0) { + 26 for (i = 0; i < nsig; i++) + 27 vout[i] -= vin[i]; + 28 if (putvec(vout) < 0) break; + 29 for (i = 0; i < nsig; i++) + 30 vout[i] = vin[i]; + 31 } + 32 (void)newheader("dif"); + 33 wfdbquit(); + 34 exit(0); + 35 } + +*Notes:* + +_Line 24:_ + Here we attempt to open as many output signals as there are input + signals; if we cannot do so, the program exits after `osigopen' + prints an error message. + +_Line 25:_ + The main loop of the program begins here. If 1000 samples can be + read from each signal, the loop will end normally; if `getvec' + fails before 1000 samples have been read, the loop ends + prematurely. + +_Lines 26-27:_ + For each signal, we compute the negated first difference by + subtracting the new sample from the previous sample. + +_Line 28:_ + One sample of each output signal is written here. + +_Lines 29-30:_ + The new input samples are copied into the output sample vector in + preparation for the next iteration. + +_Line 32:_ + This step is optional. It creates a header file for a new record + to be called `dif', which we can then open with another program if + we want to read the signals that this program has written. Since + the RECORD argument for `osigopen' was `8l', we can also read + these files using record `8l'; one reason for making a new `hea' + file here is that the `hea' file for `8l' may not necessarily + indicate the proper sampling frequency for these signals. + +_Line 33:_ + Since the program writes output signals, it must invoke `wfdbquit' + to close the files properly. + + File: wpg, Node: Example 7, Next: Example 8, Prev: Example 6, Up: Examples Example 7: A General-Purpose FIR Filter @@ -549,9 +814,9 @@ 30 exit(2); 31 } 32 if (wfdbinit(argv[1], &a, 1, s, nsig) != nsig) exit(2); - 33 if (sampfreq(NULL) != 250.) - 34 fprintf(stderr,"warning: %s is designed for 250 Hz input\n", - 35 argv[0]); + 33 if (sampfreq((char *)NULL) < 240. || + 34 sampfreq((char *)NULL) > 260.) + 35 setifreq(250.); 36 if (argc > 2) scmin = muvadu(0, atoi(argv[2])); 37 if (scmin < 1) scmin = muvadu(0, 1000); 38 slopecrit = scmax = 10 * scmin; @@ -623,9 +888,9 @@ Most of this program is independent of sampling frequency, but the filter (lines 45-46) and the threshold are as specified by the authors of the original program for human ECGs sampled at 250 Hz - (e.g., the AHA DB). The program will work for MIT DB records - sampled at 360 Hz, but better results can be obtained if the - filter is optimized for the correct sampling frequency. + (e.g., the AHA DB). If the sampling frequency of the input record + is significantly different, we use `setifreq' to specify that we + want `getvec' to give us data resampled at 250 Hz. _Lines 36-38:_ The threshold is actually a slope criterion (with units of @@ -686,15 +951,16 @@ through them first. 1. Type in the first program from the previous chapter, compile it, - and run it. Remember to set and export the environment variable - `WFDB' (*note WFDB path::). It is a good idea to include this - step in your `.profile', `.cshrc', or `autoexec.bat'. As input, - try record `100s', input annotator `atr', and output annotator - `normal'. The program should finish in five seconds or less. The - annotations will have been written into a file called `100s.nor' - in the current directory. Now type "`rdann -r 100s -a atr'" and - observe the output for a few seconds, then try "`rdann -r 100s -a - nor'" and notice the difference. + and run it. If you know that you will need to read WFDB files + from non-standard locations, remember to set and export the + environment variable `WFDB' (*note WFDB path::). It is a good + idea to include this step in your `.profile', `.cshrc', or + `autoexec.bat'. As input, try record `100s', input annotator + `atr', and output annotator `normal'. The program should finish + in five seconds or less. The annotations will have been written + into a file called `100s.nor' in the current directory. Now type + "`rdann -r 100s -a atr'" and observe the output for a few seconds, + then try "`rdann -r 100s -a nor'" and notice the difference. 2. Modify the program from the previous exercise so that the non-QRS annotations are put into a second output annotation file. diff -Naur wfdb-10.2.5/doc/wpg/info/wpg-6 wfdb-10.2.6/doc/wpg/info/wpg-6 --- wfdb-10.2.5/doc/wpg/info/wpg-6 Sun Mar 10 11:37:36 2002 +++ wfdb-10.2.6/doc/wpg/info/wpg-6 Mon Jun 24 22:20:24 2002 @@ -54,14 +54,10 @@ A set of annotations in time order. _Annotator name_ - A name associated with an annotation file. On writable Unix and - Macintosh file systems, the annotation file name is constructed - from the annotator name by appending a `.' and the record name. - On CD-ROMs and MS-DOS file systems, the annotator name is - restricted to three characters, and the annotation file name is - constructed from the record name by appending a `.' and the - annotator name. Unix and Macintosh versions of the WFDB library - can locate and read annotation files named using either convention. + A name associated with an annotation file. The annotation file + name is constructed from the record name by appending a `.' and + the annotator name. On CD-ROMs and MS-DOS file systems, the + annotator name is restricted to three characters. _Annotator [number]_ An integer by which an annotation file, once opened, is known. @@ -341,7 +337,7 @@ file. If you need to create such a header file, refer to the description of the byte offset field in `header(5)' (the specification of the header file format in the `WFDB Applications - Guide', or *note wfdbsetstart::. + Guide') or *note wfdbsetstart::. _Record_ An extensible set of files that may include signal files, @@ -395,7 +391,8 @@ _Signal file_ A set of samples in time order, which represent a signal or signal - group. + group. Signal files usually have names of the form RECORD`.dat', + but this is only a convention and is not required. _Signal group_ A set of signals that are multiplexed together and stored in the @@ -534,7 +531,7 @@ This will create a directory with a name of the form `wfdb-'M.N.R, where M.N.R is the version number of the included WFDB library (e.g., -`10.2.5'). Enter this directory. +`10.2.6'). Enter this directory. You should now be ready to configure, compile, and install the software, using the commands: @@ -577,17 +574,11 @@ `http://www.physionet.org/physiotools/libwww/'. You may omit this step if you do not wish to have NETFILES support. - Download -`http://www.physionet.org/physiotools/binaries/windows/bin/which.exe' -and put it into a directory in your PATH. (This utility is needed by -`configure' in a later step. The sources for `which.exe' are available -within `http://www.physionet.org/physiotools/utilities/'.) - Open a Cygwin terminal window (the Cygwin installer will have added this to your MS-Windows start menu). Perform the remaining steps by typing the commands given below into the terminal window. - Check that `which' and `gcc' are accessible by typing the command: + Check that `gcc' is accessible by typing the command: which gcc @@ -610,7 +601,7 @@ This will create a directory with a name of the form `wfdb-'_m.n.r_, where _m.n.r_ is the version number of the included WFDB library (e.g., -`10.2.5'). Enter this directory. +`10.2.6'). Enter this directory. You should now be ready to configure, compile, and install the software, using the commands: diff -Naur wfdb-10.2.5/doc/wpg/info/wpg-7 wfdb-10.2.6/doc/wpg/info/wpg-7 --- wfdb-10.2.5/doc/wpg/info/wpg-7 Sun Mar 10 11:37:36 2002 +++ wfdb-10.2.6/doc/wpg/info/wpg-7 Mon Jun 24 22:20:24 2002 @@ -115,9 +115,9 @@ unneeded functionality in order to conserve memory for special applications. The `calib.c' package is not referenced by any other WFDB library modules. For signal processing applications that do not -involve ECGs, the entire `annot.c' package may be removed (with trivial -modifications to the functions in `wfdbinit.c'). If you wish to add -functions to the library, you will find that it will be easier to +involve annotations, the entire `annot.c' package may be removed (with +trivial modifications to the functions in `wfdbinit.c'). If you wish +to add functions to the library, you will find that it will be easier to maintain your modified version and to merge updates if you preserve the existing arrangement of functions, which requires no global variables. Rather than defining global variables, consider implementing query @@ -170,6 +170,7 @@ _MIMIC Database_ _Other reference databases of physiologic signals_ _WFDB Software Package_ + WWW: `http://www.physionet.org/' PhysioNet offers free access via the web to large collections of @@ -181,10 +182,10 @@ about ten public mirrors are located elsewhere in the US and around the world (see `http://www.physionet.org/mirrors/' for a list). - _MIT-BIH Arrhythmia Database CD-ROM_ _MIT-BIH Polysomnographic Database CD-ROM_ _Software for Physiologic Databases with Samples CD-ROM_ + MIT-BIH Database Distribution MIT Room E25-505A 77 Massachusetts Ave. @@ -194,10 +195,10 @@ WWW: http://ecg.mit.edu/ telephone: +1 617 253 7424 - _European ST-T Database CD-ROM_ _European ST-T Database Directory_ _VALE Database Directory_ + National Research Council (CNR) Institute of Clinical Physiology Dept. of Bioengineering and Medical Informatics via Trieste, 41 @@ -207,8 +208,8 @@ telephone: +39 050 501145 telefax: +39 050 503596 - _AHA Database for Evaluation of Ventricular Arrhythmia Detectors_ + ECRI 5200 Butler Pike Plymouth Meeting, PA 19462 USA @@ -217,8 +218,8 @@ WWW: `http://www.healthcare.ecri.org/' telephone: +1 610 825 6000 - _MGH/Marquette Foundation Waveform Database CD-ROMs_ + Anaesthesia/Bioengineering Unit Massachusetts General Hospital Fruit St. @@ -231,10 +232,10 @@ radial arterial, pulmonary arterial, and central venous pressure, respiration, and CO2), which has been issued on 10 CD-ROMs. - _American National Standard ANSI/AAMI EC38:1998, Ambulatory Electrocardiographs_ _American National Standard ANSI/AAMI EC57:1998 Testing and Reporting Performance_ _ Results of Cardiac Rhythm and ST Segment Measurement Algorithms_ + Association for the Advancement of Medical Instrumentation 1110 N Glebe Road, Suite 220 Arlington, VA 22201 USA @@ -243,8 +244,8 @@ telephone: +1 703 525 4890 telefax: +1 703 276 0793 - _Computers in Cardiology_ + WWW: `http://www.cinc.org/' CinC is the major scientific meeting at which current research in @@ -259,8 +260,8 @@ date of the conference. CinC will be in Memphis, Tennessee in 2002, and in Thessaloniki in 2003. - _Proceedings of Computers in Cardiology (ISSN 0276-6574)_ + IEEE Customer Service 445 Hoes Lane P.O. Box 1331 @@ -279,6 +280,7 @@ _Larry Wall's `patch' program, with GNU revisions_ _GNU groff, gtbl, and related text formatting utilities_ _GNU info and makeinfo (standalone hypertext browser and formatter)_ + Free Software Foundation 59 Temple Place - Suite 330 Boston, MA 02111-1307 USA @@ -296,8 +298,8 @@ archive sites. Please support the FSF with a donation if you use GNU software. - _TeX for Unix systems_ + This software is available by anonymous FTP from CTAN (Comprehensive TeX Archive Network) mirrors, including `ftp.tex.ac.uk', `ftp.dante.de', and `ctan.tug.org'. Many of the @@ -314,8 +316,8 @@ and MacOS are widely available; visit the web site of the TeX Users Group (below) for pointers. - _General information on TeX_ + TeX Users Group PO Box 2311 Portland, OR 97208-2311 USA @@ -325,9 +327,9 @@ telephone: +1 503 223 3960 telefax: +1 503 223 9994 - _X11R6 (the X Window System, Version 11, Release 6)_ _XView_ + The Open Group 29B Montvale Ave. Woburn, MA 01801 USA @@ -344,7 +346,6 @@ Sources for XView are also available from PhysioNet. - _GNU/Linux_ GNU/Linux is a POSIX-compliant reimplementation of the Unix operating system, written by Linus Torvalds and a cast of @@ -403,7 +404,6 @@ telephone: +49 911 74053 31 telefax: +49 911 7417755 - _Compilers and software development systems_ Any ANSI/ISO C compiler (or any K&R C compiler, if you still have one) can be used to compile the WFDB library and applications that @@ -448,8 +448,8 @@ including `gcc', a free 32-bit DOS extender, and many of the same utilties as Cygwin and MinGW. - _Microstar DAP analog interface boards for PCs_ + Microstar Laboratories 2265 116th Avenue N.E. Bellevue, WA 98004 USA @@ -459,8 +459,8 @@ telephone: +1 425 453 2345 telefax: +1 425 453 3199 - _Web browsers_ + The most popular Web browsers may be downloaded by anonymous FTP. Netscape diff -Naur wfdb-10.2.5/doc/wpg/info/wpg-8 wfdb-10.2.6/doc/wpg/info/wpg-8 --- wfdb-10.2.5/doc/wpg/info/wpg-8 Sun Mar 10 11:37:36 2002 +++ wfdb-10.2.6/doc/wpg/info/wpg-8 Mon Jun 24 22:20:24 2002 @@ -161,8 +161,10 @@ * date (conversion to and from string): datstr and strdat. * DC-coupled signal (defined): Glossary. * DC-coupled signals: WFDB_Calinfo structures. -* decimation <1>: getspf. -* decimation: setgvmode. +* decimation <1>: getvec. +* decimation <2>: getspf. +* decimation <3>: setgvmode. +* decimation: setifreq. * deleting an annotation: Annotation Order. * detector (QRS) <1>: Signal processing. * detector (QRS) <2>: Evaluation. @@ -248,8 +250,11 @@ * initial value of signal: WFDB_Siginfo structures. * initialization: selecting. * input buffer size: setibsize. -* interpolation <1>: getspf. -* interpolation: setgvmode. +* interpolation <1>: getvec. +* interpolation <2>: getspf. +* interpolation <3>: setgvmode. +* interpolation <4>: setifreq. +* interpolation: Recent changes. * intersignal skew <1>: Glossary. * intersignal skew <2>: wfdbsetskew. * intersignal skew: wfdbgetskew. @@ -362,8 +367,11 @@ * reference annotation file (defined): Glossary. * reference annotations: Concepts 3. * reference point (on QRS): WFDB_Annotation structures. -* resampling <1>: getspf. -* resampling: setgvmode. +* resampling <1>: getvec. +* resampling <2>: getspf. +* resampling <3>: setgvmode. +* resampling <4>: setifreq. +* resampling: Recent changes. * resolution <1>: Glossary. * resolution: WFDB_Siginfo structures. * restrictions on function and variable names: name restrictions. @@ -476,7 +484,17 @@ * WFDB library: Overview. * WFDB library (compiling with): compiling. * WFDB library functions: Functions. -* WFDB path: Glossary. +* WFDB path <1>: Extensions. +* WFDB path <2>: Using. +* WFDB path <3>: Glossary. +* WFDB path <4>: NETFILES. +* WFDB path <5>: Database Files. +* WFDB path <6>: wfdbfile. +* WFDB path <7>: getwfdb. +* WFDB path <8>: setwfdb. +* WFDB path <9>: WFDB path syntax. +* WFDB path <10>: WFDB path. +* WFDB path: Recent changes. * WFDB_AHA_READ: WFDB_Anninfo structures. * WFDB_AHA_WRITE: WFDB_Anninfo structures. * WFDB_Anninfo structure (defined): WFDB_Anninfo structures. @@ -537,6 +555,8 @@ * getcal (6.0): getcal. * getcfreq (5.2): counter conversion. * getframe (9.0): getframe. +* getifreq (10.2.6) <1>: getifreq. +* getifreq (10.2.6): Recent changes. * getinfo (4.0): getinfo. * getspf (9.6): getspf. * getvec: getvec. @@ -574,6 +594,9 @@ * setgvmode (9.0): setgvmode. * setheader (5.0): setheader. * setibsize (5.0): setibsize. +* setifreq (10.2.6) <1>: getvec. +* setifreq (10.2.6) <2>: setifreq. +* setifreq (10.2.6): Recent changes. * setisqrs (6.0): Mapping macros. * setmap1 (6.0): Mapping macros. * setmap2 (6.0): Mapping macros. @@ -605,7 +628,7 @@ WFDB Programmer's Guide Tenth Edition (revised and with additions for WFDB library version -10.2.5) +10.2.6) George B. Moody diff -Naur wfdb-10.2.5/doc/wpg-src/Makefile wfdb-10.2.6/doc/wpg-src/Makefile --- wfdb-10.2.5/doc/wpg-src/Makefile Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/doc/wpg-src/Makefile Mon Jun 24 22:43:07 2002 @@ -65,12 +65,12 @@ # wpg.info' again. # _____________________________________________________________________________ # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables @@ -78,7 +78,7 @@ VDEFS = -DWFDB_MAJOR=$(MAJOR) -DWFDB_MINOR=$(MINOR) -DWFDB_RELEASE=$(RELEASE) # _____________________________________________________________________________ -PACKAGE=wfdb-10.2.5 +PACKAGE=wfdb-10.2.6 # file: linux.def G. Moody 31 May 2000 # Last revised: 17 December 2001 # 'make' definitions for compiling the WFDB Software Package under Linux @@ -201,7 +201,7 @@ echo "Nothing to be done for lib-post-uninstall" # _____________________________________________________________________________ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 20 December 2001 +# Last revised: 24 June 2002 # Change the settings below as appropriate for your setup. # D2PARGS is a list of options for dvips. Uncomment one of these to set the @@ -256,6 +256,8 @@ .IGNORE: all: wpg.html wpg.ps wpg.pdf + $(MAKE) INFODIR=../wpg/info wpg.info + rm -f ../wpg/info/dir cp -p wpg.ps wpg.pdf ../wpg install: @@ -324,4 +326,4 @@ clean: rm -f info.tar.gz info/wpg* wpg.aux wpg.cp wpg.cps wpg.dvi wpg.fn \ wpg.fns wpg.ky wpg.log wpg.pdf wpg.ps wpg.pg wpg.toc wpg.tp wpg.vr \ - wpgcover.ps *~ + wpgcover.ps *~ ../wpg/info/dir diff -Naur wfdb-10.2.5/doc/wpg-src/Makefile.tpl wfdb-10.2.6/doc/wpg-src/Makefile.tpl --- wfdb-10.2.5/doc/wpg-src/Makefile.tpl Thu Dec 20 18:08:53 2001 +++ wfdb-10.2.6/doc/wpg-src/Makefile.tpl Mon Jun 24 20:32:02 2002 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 20 December 2001 +# Last revised: 24 June 2002 # Change the settings below as appropriate for your setup. # D2PARGS is a list of options for dvips. Uncomment one of these to set the @@ -54,6 +54,8 @@ .IGNORE: all: wpg.html wpg.ps wpg.pdf + $(MAKE) INFODIR=../wpg/info wpg.info + rm -f ../wpg/info/dir cp -p wpg.ps wpg.pdf ../wpg install: @@ -122,4 +124,4 @@ clean: rm -f info.tar.gz info/wpg* wpg.aux wpg.cp wpg.cps wpg.dvi wpg.fn \ wpg.fns wpg.ky wpg.log wpg.pdf wpg.ps wpg.pg wpg.toc wpg.tp wpg.vr \ - wpgcover.ps *~ + wpgcover.ps *~ ../wpg/info/dir diff -Naur wfdb-10.2.5/doc/wpg-src/fixpg.sh wfdb-10.2.6/doc/wpg-src/fixpg.sh --- wfdb-10.2.5/doc/wpg-src/fixpg.sh Thu Dec 20 14:59:09 2001 +++ wfdb-10.2.6/doc/wpg-src/fixpg.sh Mon Jun 24 14:45:32 2002 @@ -1,6 +1,6 @@ #! /bin/sh -# file: fixpg.sh G. Moody 12 April 1997 -# Last revised: 20 December 2001 +# file: fixpg.sh G. Moody 12 April 1997 +# Last revised: 24 June 2002 # # Post-process WFDB Programmer's Guide HTML files @@ -14,3 +14,21 @@ cp $1/wpg_toc.htm /tmp/.fix.$$ sed "s+WFDB Database Programmer's Guide<+WFDB Programmer's Guide<+" $1/wpg_toc.htm rm /tmp/.fix.$$ + +cd $1 + +R=`grep -l "WFDB Programmer's Guide: WFDB path" *.htm` +if [ "x$R" != "x" ]; then ln -s $R database-path.htm +else echo "Can't find database-path.htm" +fi + +R=`grep -l "

      Records" *.htm` +if [ "x$R" != "x" ]; then ln -s $R records.htm +else echo "Can't find records.htm" +fi + +R=`grep -l "WFDB Programmer's Guide: strtim" *.htm` +if [ "x$R" != "x" ]; then ln -s $R strtim.htm +else echo "Can't find strtim.htm" +fi + diff -Naur wfdb-10.2.5/doc/wpg-src/wpg.cover wfdb-10.2.6/doc/wpg-src/wpg.cover --- wfdb-10.2.5/doc/wpg-src/wpg.cover Sun Mar 10 11:07:39 2002 +++ wfdb-10.2.6/doc/wpg-src/wpg.cover Mon Jun 17 18:53:15 2002 @@ -45,7 +45,7 @@ -MARCH 2002 +JUNE 2002 .bp diff -Naur wfdb-10.2.5/doc/wpg-src/wpg.ht0 wfdb-10.2.6/doc/wpg-src/wpg.ht0 --- wfdb-10.2.5/doc/wpg-src/wpg.ht0 Sun Mar 10 11:08:19 2002 +++ wfdb-10.2.6/doc/wpg-src/wpg.ht0 Mon Jun 24 10:43:58 2002 @@ -11,8 +11,8 @@ <B>Up:</B> <A HREF="../manuals.shtml">Books about PhysioToolkit</A> <H1 ALIGN=CENTER>WFDB Programmer's Guide</H1> <P ALIGN=CENTER><STRONG>Tenth Edition<BR> -(Revised and with corrections for WFDB library version 10.2.5)<BR> -10 March 2002<BR> +(Revised and with corrections for WFDB library version 10.2.6)<BR> +24 June 2002<BR> <BR> <BR> <BR> diff -Naur wfdb-10.2.5/doc/wpg-src/wpg.tex wfdb-10.2.6/doc/wpg-src/wpg.tex --- wfdb-10.2.5/doc/wpg-src/wpg.tex Sun Mar 10 12:41:02 2002 +++ wfdb-10.2.6/doc/wpg-src/wpg.tex Mon Jun 24 21:13:57 2002 @@ -9,7 +9,7 @@ @sp 5 @center @titlefont{WFDB Programmer's Guide} @sp 4 -@center Tenth Edition (revised and with additions for WFDB library version 10.2.5) +@center Tenth Edition (revised and with additions for WFDB library version 10.2.6) @center @today @sp 5 @center George B. Moody @@ -62,8 +62,8 @@ @ifinfo This guide documents the Waveform Database interface library (the WFDB library). This file contains the text of the Tenth Edition of -the @cite{WFDB Programmer's Guide} (March, 2002), with -revisions for release 10.2.5 of the WFDB library. +the @cite{WFDB Programmer's Guide} (June, 2002), with +revisions for release 10.2.6 of the WFDB library. @end ifinfo @menu @@ -74,7 +74,8 @@ the WFDB library. * Functions:: Call and return syntax of each function, with descriptions and program examples. -* Data Types:: Annotator and signal information structures, +* Data Types:: Simple and compound types, including annotator, + calibration, and signal information structures, and annotation structures. * Annotation Codes:: Table of codes, descriptions of mapping macros. * Database Files:: A description of the standard file types, and @@ -401,7 +402,7 @@ a wide variety of machines and operating systems, including Unix (BSD 4.x, System V, SunOS, Solaris, HP-UX, OSF/1, Version 7, XENIX, VENIX, ULTRIX, GNU/Linux, OpenBSD, IRIX, AIX, AUX, Darwin, MacOS/X, SCO, -Coherent, and more), MS-DOS, MS-Windows, VMS, and the Macintosh OS. +Coherent, and more), MS-DOS, MS-Windows, VMS, and classic MacOS. This guide was written for Unix users (with notes for MS-Windows and MS-DOS users where differences exist), but others should find only minor differences. @@ -413,8 +414,8 @@ to Paul Albrecht, Ted Baker, Phil Devlin, Scott Greenwald, David Israel, Roger Mark, Joe Mietus, Warren Muldrow, and especially to Paul Schluter, whose elegant 8080 assembly language functions inspired these (long live -@code{getann}!). Pat Hamilton and Bob Farrell contributed ports, to the -Macintosh and the MS 32-bit Windows environments, respectively. Jose Garcia +@code{getann}!). Pat Hamilton and Bob Farrell contributed ports, to classic +MacOS and the MS 32-bit Windows environments, respectively. Jose Garcia Moros and Salvador Olmos contributed Matlab/Octave reimplementations of a useful subset of the WFDB library. Thanks also to the many readers of earlier versions of this guide; if this edition answers your questions, it is because @@ -481,6 +482,42 @@ WFDB Software Package distribution, for information on any more recent changes that may not be described here. +@unnumberedsubsec Changes in version 10.2.6 +@findex setifreq (10.2.6) +@findex getifreq (10.2.6) +@cindex interpolation +@cindex resampling + +The new functions @code{setifreq} and @code{getifreq} allow an +application to choose any convenient sampling frequency for reading +input signals. Samples read from signal files using @code{getvec} are +buffered, resampled, and delivered to the calling application as if the +original signals had been sampled at the desired frequency. Times +expressed in sample intervals passed to or from other WFDB library +functions (@code{getann}, @code{putann}, @code{mstimstr}, @code{timstr}, +and @code{strtim}) are rescaled as needed to match intervals +corresponding to the chosen frequency. Thanks to Pat Hamilton for the +inspiration! + +The WFDB library now records the base time with millisecond precision +(previous versions did so with one-second precision), and @file{xform} +provides starting times to the library function @code{setbasetime} with +millisecond precision. Thanks to Allavatam Venugopal for providing +examples that illustrated the need for these features. + +Fixed deskewing buffer initialization in @code{getframe}, broken by the +10.2.0 update, which introduced an infinite loop when reading a record +that requires skew correction starting at sample 0. Thanks to Andrew +Walsh for finding an example that triggered this bug. + +Fixed rounding errors in @code{adumuv}, @code{muvadu}, and @code{physadu}. +Previous versions rounded negative values toward zero; to obtain consistent +conversions, however, it is necessary to round all values down (e.g., from +-1.5 to -2 rather than up to -1). + +Fixed a memory leak in wfdb_fclose() (in lib/wfdbio.h). Thanks to +Ion Gazta@~naga. + @unnumberedsubsec Changes in version 10.2.5 Additions and fixes in @file{wfdbf.c} (the Fortran wrappers for the WFDB @@ -499,6 +536,7 @@ @unnumberedsubsec Changes in version 10.2.1 +@cindex WFDB path Most users will no longer need to set the WFDB path explicitly, as a result of several minor changes in the default path and in the installer for the WFDB Software Package. @@ -518,6 +556,7 @@ for compatibility with older applications that use them (typically to determine the size of static arrays). +@cindex WFDB path Since version 10.1.1, record names may include path information (see the notes for version 10.1.1 below), but if such names are used to generate names of WFDB output files, the user has been required to ensure that the target directory @@ -584,6 +623,7 @@ @unnumberedsubsec Changes in version 10.1.1 +@cindex WFDB path Record names may contain (absolute or relative) path information as a prefix, and if (as a result) an input file is found in a location that does not appear explicitly in the WFDB path, that location is appended to the end of the WFDB @@ -619,6 +659,7 @@ compiling the WFDB library. For further details, see @file{wfdbio.c} in the WFDB library sources. +@cindex WFDB path The WFDB environment variable may now contain whitespace (space, tab, or newline characters) as path component separators under any OS. Multiple consecutive whitespace characters are treated as a single path component @@ -760,6 +801,34 @@ additional libraries, and the corresponding @samp{-l} options can usually be given before or after the @samp{-lwfdb} option. +If the WFDB library was installed with NETFILES support, it will make +use of functions contained in the @file{libwww} libraries. If you have +dynamically linkable versions of the @file{libwww} libraries, as under +GNU/Linux, these will be loaded automatically when you run +@code{psamples}. If you have only static versions of these libraries, +as under Solaris or MS-Windows, however, it is necessary to provide +additional arguments in the @code{cc} command line in order to compile +successfully. One way to do this is to follow the model used to compile +the standard WFDB applications supplied with the WFDB library; see +@file{Makefile} in the @file{app} directory of the WFDB software package +source tree. + +If you are using WFDB version 10.2.6 or a later version and @file{gcc} +or a compatible compiler, the @file{wfdb-config} utility is available +to help construct commands for compiling programs that use the WFDB +library (and the @file{libwww} libraries, if available). Use it like +this: + +@example +gcc `wfdb-config --cflags` -o psamples `wfdb-config --libs` +@end example + +@noindent +Note that this command contains backticks (`), not apostrophes ('). +@file{wfdb-config} is particularly useful if the WFDB library or +its @file{*.h} files are installed in non-standard locations, or if +you have only static @code{libwww} libraries. + Under MS-Windows, it will be easiest to use @file{gcc}, the GNU C/C++ compiler, which is included in the freely available Cygwin software development system (@code{http://@-source@-.redhat@-.com/@-cygwin/}), @@ -768,27 +837,46 @@ is available in the free djgpp package (@code{http://@-www@-.delorie@-.com/@-djgpp/}). These are used within a Cygwin terminal emulator window or an MS-DOS box in exactly the same way -as described above for Unix C compilers. - -Each proprietary C or C++ compiler has its own idiosyncratic syntax, so no -general rule can be given for these. With Microsoft C/C++, use: +as described above for Unix C compilers. -@example -cl psamples.c -link wfdb +The WFDB library is developed and tested using @code{gcc}, but careful +attention has been given to making it usable with any K&R or ANSI/ISO C +compiler. Note, however, that binary versions of the WFDB library that +have been compiled using @code{gcc} are @emph{not} compatible with most +proprietary C/C++ compilers (except under Unix). Since @code{gcc} is +free, high quality, and supported, it is highly recommended that you +use it for compiling your WFDB applications. + +If you choose to use an incompatible proprietary compiler, you are on +your own! You may be able to create a linkable version of the WFDB +library from the sources in the @file{lib} directory of the WFDB source +tree using a proprietary compiler, but doing so is unsupported (see your +compiler's documentation, and if you are using MS-DOS or MS-Windows, see +@file{Makefile.dos} for hints). If you are not able to build the WFDB +library using your compiler, you can compile the library sources +together with the source file(s) for your application. It may be +easiest to copy the library sources (both the @file{*.c} and the +@file{*.h} files) into the same directory as the application sources. +If you follow this approach, find the directory that contains @file{stdio.h} +on your system and make a @file{wfdb} subdirectory within that directory, +then copy the WFDB library's @file{*.h} files into the @file{wfdb} +subdirectory (this is necessary so that statements of the form +@samp{#include <wfdb/wfdb.h>} will be handled properly by your compiler). +For example, to compile @file{psamples.c} with Microsoft C/C++, set up +the WFDB library source files as just described, then use this command: + +@example +cl psamples.c wfdbio.c signal.c annot.c calib.c wfdbinit.c @end example @noindent -With Borland C/C++, use: +With Borland C/C++ or Turbo C or C++, substitute @samp{bcc} or +@samp{tcc}, respectively, for @samp{cl} in the command above. You will +find that some WFDB applications do not need to be compiled with all of +the WFDB library sources (for example, @file{psamples} needs only +@file{wfdbio.c} and @file{signal.c}); in such cases, you may omit the +unneeded sources for faster compilation and smaller executable binaries. -@example -bcc -L@var{LIBDIR} psamples.c wfdb.lib -@end example - -@noindent -where @var{LIBDIR} is the directory in which @samp{wfdb.lib} (the WFDB -library) has been installed. (Substitute @samp{tcc} for @samp{bcc} if -you are using Turbo C or C++.) See your compiler manual for further -information. @node other languages, WFDB path, compiling, Usage @comment node-name, next, previous, up @@ -879,6 +967,7 @@ @cindex @code{WFDBCAL} (environment variable) @cindex @code{WFDBGVMODE} (environment variable) @cindex @code{WFDBANNSORT} (environment variable) +@cindex WFDB path WFDB applications make use of several @dfn{environment variables}, which are named @code{WFDB}, @code{WFDBCAL}, @code{WFDBGVMODE}, and @code{WFDBANNSORT}. @@ -904,7 +993,7 @@ software package includes easily customizable shell scripts (batch files) that illustrate how to do this for popular shells and command interpreters; see @emph{setwfdb}(1), in the @cite{WFDB Applications -Guide}. (On the Macintosh, for which the concept of environment +Guide}. (Under classic MacOS, for which the concept of environment variables is foreign, the WFDB path may be set only by using @code{DEFWFDB}.) For further information, @pxref{WFDB path syntax}. @@ -940,7 +1029,8 @@ @end example @noindent -and its output will appear as: +(Try @samp{./psamples} if @samp{psamples} doesn't work.) Its output +will appear as: @example 995 1011 @@ -984,6 +1074,7 @@ @node WFDB path syntax, exercises 1, name restrictions, Usage @section More About the WFDB Path +@cindex WFDB path When a WFDB file must be opened for input, the WFDB library attempts to locate it by attaching each of the components of the WFDB path (one at a time) as a prefix to the file name. If two or more matching files exist @@ -993,6 +1084,7 @@ path is rearranged. @cindex database path (default) +@cindex WFDB path The default WFDB path is specified at the time the WFDB library is compiled, by defining a value for the symbol @code{DEFWFDB} in @@ -1062,7 +1154,7 @@ library version 8.0.) Indirect WFDB path files may be nested up to ten levels (this arbitrary limit is imposed to avoid infinite recursion if the contents of the indirect file are incorrect). This method of -indirect assignment is useful on the Macintosh, where recompilation of +indirect assignment is useful under classic MacOS, where recompilation of the WFDB library would otherwise be necessary in order to change the WFDB path. It may also be useful under MS-DOS to reduce the need for environment space, or if the length of the command needed to set the @@ -1154,7 +1246,7 @@ @cindex functions in the WFDB library This chapter describes the functions that are available to programs -compiled with the @samp{-lwfdb} option. The functions are introduced in +compiled with the WFDB library. The functions are introduced in several groups, with examples to illustrate their usage. @menu @@ -1166,6 +1258,7 @@ The remainder of the nodes in this section describe functions for: * selecting:: Selecting database records (opening files). +* special input modes:: Setting the input sampling frequency and more. * signal and annotation I/O:: Reading and writing signals and annotations. * non-sequential:: Non-sequential access to WFDB files. * conversion:: Time and other conversion functions. @@ -1232,15 +1325,16 @@ opening signal files find them by reading the header file (which contains their names) first. -The first part of this chapter describes functions that extract +The first two sections of this chapter describes functions that extract information from header files in order to gain access to signal -and annotation files. The following two sections describe functions -that deal with signal and annotation files. Many readers will not need +and annotation files, and functions that control how these files +are read and written. The following two sections describe functions +that read and write signal and annotation files. Many readers will not need to go any further; the remaining sections deal with special-purpose functions that exist to serve unusual applications. @page -@node selecting,signal and annotation I/O,introduction to functions,Functions +@node selecting,special input modes,introduction to functions,Functions @section Selecting Database Records @cindex selecting database records @cindex opening database files @@ -1664,7 +1758,177 @@ for methods of opening output signal files. @page -@node signal and annotation I/O, non-sequential, selecting, Functions +@node special input modes, signal and annotation I/O, selecting, Functions +@section Special Input Modes + +@menu +* setifreq:: Setting the input sampling frequency. +* getifreq:: Determining the input sampling frequency. +* setgvmode:: Setting the resolution for a multifrequency + record. +* getspf:: Determining the number of samples per frame. +@end menu + +@c @group +@node setifreq, getifreq, special input modes, special input modes +@unnumberedsubsec setifreq +@findex setifreq (10.2.6) +@cindex interpolation +@cindex decimation +@cindex resampling + +@example +void setifreq(WFDB_Frequency @var{frequency}) +@end example +@noindent +@c @end group + +@noindent +This function sets the current input sampling frequency (in samples per +second per signal). It should be invoked after opening the input +signals (using @code{isigopen} or @code{wfdbinit}), and before using any +of @code{getvec}, @code{getann}, @code{putann}, @code{isigsettime}, +@code{isgsettime}, @code{timstr}, @code{mstimstr}, or @code{strtim}. +@emph{Note that the operation of @code{getframe} is unaffected by +@code{setifreq}.} + +Use @code{setifreq} when your application requires input samples at a +specific frequency. After invoking @code{setifreq}, @code{getvec} +resamples the digitized signals from the input signals at the desired +frequency (@pxref{getvec}), and all of the WFDB library functions that +accept or return times in sample intervals automatically convert between +the actual sampling intervals and those corresponding to the desired +frequency. This slightly elaborated version of the example program from +the previous chapter invokes @code{setifreq}, passing it the desired sampling +frequency from the command line, then prints the samples in record 100s, +beginning 1 second (@code{t0}) and ending 2 seconds (@code{t1}) from the +beginning of the record: + +@example +#include <wfdb/wfdb.h> + +main(int argc, char **argv) +@{ + WFDB_Frequency f = (WFDB_Frequency)0; + WFDB_Sample v[2]; + WFDB_Siginfo s[2]; + WFDB_Time t, t0, t1; + + if (argc > 1) sscanf(argv[1], "%lf", &f); + if (f <= (WFDB_Frequency)0) f = sampfreq("100s"); + + if (isigopen("100s", s, 2) < 1) + exit(1); + setifreq(f); + t0 = strtim("1"); + isigsettime(t0); + t1 = strtim("2"); + for (t = t0; t <= t1; t++) @{ + if (getvec(v) < 0) + break; + printf("%d\t%d\n", v[0], v[1]); + @} + exit(0); +@} +@end example + +@noindent +(The source for this program, @file{psamplex.c}, can be found in the +@file{examples} directory of the WFDB source tree. Compile it as shown +in the previous chapter, then run it using a command such as +@samp{psamplex 100}.) The QRS detector in chapter 6 also illustrates +the use of @code{setifreq} (@pxref{Example 10}). + +@c @group +@node getifreq, setgvmode, setifreq, special input modes +@unnumberedsubsec getifreq +@findex getifreq (10.2.6) + +@example +WFDB_Frequency getifreq(void) +@end example +@noindent +@strong{Return:} +@table @asis +@item @t{(WFDB_Frequency)} +the input sampling frequency +@end table +@c @end group + +@noindent +This function returns the current input sampling frequency (in samples +per second per signal), which is either the raw sampling frequency for +the record (as would be returned by @code{sampfreq}, @pxref{sampfreq}), +or the frequency chosen using a previous invocation of @code{setifreq}. + +@c @group +@node setgvmode, getspf, getifreq, special input modes +@unnumberedsubsec setgvmode +@findex setgvmode (9.0) +@cindex interpolation +@cindex decimation +@cindex resampling +@cindex multi-frequency records (reading) + +@example +void setgvmode(int *@var{mode}) +@end example +@noindent +@c @end group + +@noindent +This function sets the mode used by @code{getvec} when reading a +multi-frequency record (@pxref{Multi-Frequency Records}). If @var{mode} is +@code{WFDB_LOWRES}, @code{getvec} decimates any signals sampled at multiples of +the frame rate, so that one sample is returned per signal per frame (i.e., the +oversampled signals are resampled by simple averaging of the samples for each +signal within each frame). If @var{mode} is @code{WFDB_HIGHRES}, each sample +of any oversampled signal is returned by successive invocations of +@code{getvec}, and each sample of any signal sampled at a lower frequency is +returned by two or more successive invocations of @code{getvec} (i.e., the less +frequently sampled signals are resampled using zero-order interpolation). +@code{getvec} operates in @code{WFDB_LOWRES} mode by default. +@code{WFDB_LOWRES} and @code{WFDB_HIGHRES} are defined in @file{<wfdb/wfdb.h>}. + +In WFDB library version 9.6 and later versions, @code{setgvmode} also affects +how annotations are read and written. If @code{setgvmode(WFDB_HIGHRES)} is +invoked @emph{before} using @code{annopen}, @code{wfdbinit}, @code{getvec}, +@code{sampfreq}, @code{strtim}, or @code{timstr}, then all @code{WFDB_Time} +data (including the @code{time} attributes of annotations read by @code{getann} +or written by @code{putann}) visible to the application are in units of the +high-resolution sampling intervals. (Otherwise, @code{WFDB_Time} data are in +units of frame intervals.) + +@c @group +@node getspf, , setgvmode, special input modes +@unnumberedsubsec getspf +@findex getspf (9.6) +@cindex interpolation +@cindex decimation +@cindex resampling +@cindex multi-frequency records (reading) + +@example +int getspf(void) +@end example +@noindent +@strong{Return:} +@table @asis +@item @t{(int)} +the number of samples per signal per frame +@end table +@c @end group + +@noindent +Unless the application is operating in @code{WFDB_HIGHRES} mode +(@pxref{setgvmode}) and has then opened a multi-frequency record, this +function returns 1. For the case of a multi-frequency record being read +in high resolution mode, however, @code{getspf} returns the number of +samples per signal per frame (hence @code{sampfreq(NULL)/getspf()} is +the number of frames per second). + +@page +@node signal and annotation I/O, non-sequential, special input modes, Functions @section Reading and Writing Signals and Annotations @cindex signal I/O @@ -1746,6 +2010,24 @@ example programs in chapter 6 illustrate the use of @code{getvec}; for example, @pxref{Example 6}. +@findex setifreq (10.2.6) +@cindex interpolation +@cindex decimation +@cindex resampling +If @code{setifreq} has been used to modify the input sampling rate, +@code{getvec} resamples the input signals at the desired rate, using +linear interpolation between the pair of samples nearest in time to that +of the sample to be returned. The results will generally be +satisfactory, provided that the original signals do not contain +frequencies near or above the Nyquist limit (half of the desired +sampling frequency). If this is a concern, you may wish to low-pass +filter the input signals using, for example, @samp{fir} (see the +@cite{WFDB Applications Guide}) before resampling them. If you use +@code{setifreq} to @emph{increase} the sampling frequency by a large +factor, you may wish to filter the resampled signals within your +application to remove harmonics of the original sampling frequency +introduced by resampling. + @c @group @node getframe, putvec, getvec, signal and annotation I/O @unnumberedsubsec getframe @@ -2858,9 +3140,6 @@ * sampfreq:: Reading the sampling frequency of a WFDB record. * setsampfreq:: Setting the sampling frequency. * setbasetime:: Setting the base time. -* setgvmode:: Setting the resolution for a multifrequency - record. -* getspf:: Determining the number of samples per frame. * counter conversion:: Functions for reading and setting counter conversion parameters. * setwfdb:: Dynamically changing the database path. @@ -3270,7 +3549,7 @@ @xref{Example 8}, for an illustration of the use of @code{setsampfreq}. @c @group -@node setbasetime, setgvmode, setsampfreq, miscellaneous functions +@node setbasetime, counter conversion, setsampfreq, miscellaneous functions @unnumberedsubsec setbasetime @findex setbasetime @cindex current time @@ -3307,76 +3586,10 @@ @end ifinfo @xref{Example 8}, for an illustration of the use of @code{setbasetime}. -@c @group -@node setgvmode, getspf, setbasetime, miscellaneous functions -@unnumberedsubsec setgvmode -@findex setgvmode (9.0) -@cindex interpolation -@cindex decimation -@cindex resampling -@cindex multi-frequency records (reading) - -@example -void setgvmode(int *@var{mode}) -@end example -@noindent -@c @end group - -@noindent -This function sets the mode used by @code{getvec} when reading a -multi-frequency record (@pxref{Multi-Frequency Records}). If @var{mode} is -@code{WFDB_LOWRES}, @code{getvec} decimates any signals sampled at multiples of -the frame rate, so that one sample is returned per signal per frame (i.e., the -oversampled signals are resampled by simple averaging of the samples for each -signal within each frame). If @var{mode} is @code{WFDB_HIGHRES}, each sample -of any oversampled signal is returned by successive invocations of -@code{getvec}, and each sample of any signal sampled at a lower frequency is -returned by two or more successive invocations of @code{getvec} (i.e., the less -frequently sampled signals are resampled using zero-order interpolation). -@code{getvec} operates in @code{WFDB_LOWRES} mode by default. -@code{WFDB_LOWRES} and @code{WFDB_HIGHRES} are defined in @file{<wfdb/wfdb.h>}. - -In WFDB library version 9.6 and later versions, @code{setgvmode} also affects -how annotations are read and written. If @code{setgvmode(WFDB_HIGHRES)} is -invoked @emph{before} using @code{annopen}, @code{wfdbinit}, @code{getvec}, -@code{sampfreq}, @code{strtim}, or @code{timstr}, then all @code{WFDB_Time} -data (including the @code{time} attributes of annotations read by @code{getann} -or written by @code{putann}) visible to the application are in units of the -high-resolution sampling intervals. (Otherwise, @code{WFDB_Time} data are in -units of frame intervals.) - -@c @group -@node getspf, counter conversion, setgvmode, miscellaneous functions -@unnumberedsubsec getspf -@findex getspf (9.6) -@cindex interpolation -@cindex decimation -@cindex resampling -@cindex multi-frequency records (reading) - -@example -int getspf(void) -@end example -@noindent -@strong{Return:} -@table @asis -@item @t{(int)} -the number of samples per signal per frame -@end table -@c @end group - -@noindent -Unless the application has used @code{setgvmode(WFDB_HIGHRES)} and has -then opened a multi-frequency record, this function returns 1. For the -case of a multi-frequency record being read in high resolution mode, -however, @code{getspf} returns the number of samples per signal per -frame (hence @code{sampfreq(NULL)/getspf()} is the number of frames -per second). - @sp 2 @c @group -@node counter conversion, setwfdb, getspf, miscellaneous functions +@node counter conversion, setwfdb, setbasetime, miscellaneous functions @cindex base counter value @cindex counter (base) @cindex counter frequency @@ -3489,6 +3702,7 @@ @findex setwfdb @cindex database path (changing) @cindex changing the WFDB path +@cindex WFDB path @example void setwfdb(char *@var{string}) @@ -3515,6 +3729,7 @@ by a component consisting of a single @samp{.}). If the string is empty or @code{NULL}, the database path is limited to the current directory. +@cindex WFDB path @cindex indirect WFDB path @cindex file containing WFDB path @cindex database path file (indirect) @@ -3553,6 +3768,7 @@ @findex getwfdb @cindex database path (reading) @cindex reading the WFDB path +@cindex WFDB path @example char *getwfdb(void) @@ -3594,6 +3810,7 @@ @cindex filenames of WFDB files (obtaining) @cindex pathnames of WFDB files (obtaining) @cindex NETFILES +@cindex WFDB path @example char *wfdbfile(char *@var{type}, char *@var{record}) @@ -4272,10 +4489,10 @@ and found in any of the directories in the database path (@pxref{WFDB path}). @item int stat -@cindex WFDB_AHA_READ -@cindex WFDB_AHA_WRITE -@cindex WFDB_READ -@cindex WFDB_WRITE +@cindex @code{WFDB_AHA_READ} +@cindex @code{WFDB_AHA_WRITE} +@cindex @code{WFDB_READ} +@cindex @code{WFDB_WRITE} the file type/access code. Usually, @code{stat} is either @code{WFDB_READ} or @code{WFDB_WRITE}, to specify standard (``MIT format'') annotation files to be read by @code{getann} or to be written by @code{putann}. Both MIT @@ -4602,6 +4819,7 @@ @node Database Files, Examples, Annotation Codes, Top @chapter Database Files +@cindex WFDB path The WFDB library has been constructed to provide a standard interface between the database files and application programs. Alternate means of access to database files is strongly discouraged, since file formats may @@ -5029,6 +5247,7 @@ @cindex URL @cindex http @cindex ftp +@cindex WFDB path If the symbol @code{WFDB_NETFILES} is defined at the time the WFDB library is compiled, then input files located on remote web (HTTP) and FTP servers can be @@ -5040,12 +5259,13 @@ loaded automatically), and incorporate one or more URL prefixes in the WFDB path. +@cindex WFDB path @cindex PhysioBank In current versions of the WFDB library, the default WFDB path (defined in the WFDB library source file @code{wfdblib.h}, and used as the WFDB path if the WFDB environment variable is undefined) is @samp{. /usr/database -http://www.physio@-net.org/physio@-bank/data@-base}. (The second component,, -after the @samp{.} that specifies the current directory,may vary, depending on +http://www.physio@-net.org/physio@-bank/data@-base}. (The second component, +after the @samp{.} that specifies the current directory, may vary, depending on your platform and the choices made during installation.) The URL prefix (the third component) points to PhysioBank, an on-line archive for a wide variety of standard databases of physiologic signals. The databases are kept in @@ -5156,6 +5376,12 @@ cc @var{file.c} -lwfdb @end example @noindent +or, if the WFDB library or its @code{*.h} files are not in the standard +locations: +@example +cc `wfdb-config --cflags` @var{file.c} `wfdb-config --libs` +@end example +@noindent where @var{file.c} is the name of the file containing the source; @pxref{Usage, , Using the WFDB Library}, for further information. The sources for these examples are included in the WFDB Software Package, @@ -5209,6 +5435,7 @@ @i{26} @} @end example +@page @c @group @noindent @strong{Notes:} @@ -6244,9 +6471,9 @@ @i{30} exit(2); @i{31} @} @i{32} if (wfdbinit(argv[1], &a, 1, s, nsig) != nsig) exit(2); -@i{33} if (sampfreq(NULL) != 250.) -@i{34} fprintf(stderr,"warning: %s is designed for 250 Hz input\n", -@i{35} argv[0]); +@i{33} if (sampfreq((char *)NULL) < 240. || +@i{34} sampfreq((char *)NULL) > 260.) +@i{35} setifreq(250.); @i{36} if (argc > 2) scmin = muvadu(0, atoi(argv[2])); @i{37} if (scmin < 1) scmin = muvadu(0, 1000); @i{38} slopecrit = scmax = 10 * scmin; @@ -6320,9 +6547,9 @@ Most of this program is independent of sampling frequency, but the filter (lines 45--46) and the threshold are as specified by the authors of the original program for human ECGs sampled at 250 Hz (e.g., the AHA DB). -The program will work for MIT DB records sampled at 360 Hz, but better -results can be obtained if the filter is optimized for the correct sampling -frequency. +If the sampling frequency of the input record is significantly +different, we use @code{setifreq} to specify that we want @code{getvec} +to give us data resampled at 250 Hz. @item Lines 36--38: The threshold is actually a slope criterion (with units of amplitude/time); @@ -6382,7 +6609,8 @@ @enumerate @item Type in the first program from the previous chapter, compile it, and run -it. Remember to set and export the environment variable @code{WFDB} +it. If you know that you will need to read WFDB files from non-standard +locations, remember to set and export the environment variable @code{WFDB} (@pxref{WFDB path}). It is a good idea to include this step in your @file{.profile}, @file{.cshrc}, or @file{autoexec.bat}. As input, try record @file{100s}, input annotator @file{atr}, and output annotator @@ -6622,14 +6850,10 @@ @item Annotator name @cindex annotator name (defined) -A name associated with an annotation file. On writable Unix and -Macintosh file systems, the annotation file name is constructed from the -annotator name by appending a @samp{.} and the record name. On CD-ROMs -and MS-DOS file systems, the annotator name is restricted to three -characters, and the annotation file name is constructed from the record -name by appending a @samp{.} and the annotator name. Unix and Macintosh -versions of the WFDB library can locate and read annotation files named -using either convention. +A name associated with an annotation file. The annotation file name is +constructed from the record name by appending a @samp{.} and the annotator +name. On CD-ROMs and MS-DOS file systems, the annotator name is restricted +to three characters. @item Annotator [number] @cindex annotator number (defined) @@ -6720,6 +6944,7 @@ calibration files) that are accessed via the WFDB library. @item Database path +@cindex WFDB path @cindex database path (defined) The names of the directories in which header, annotation, and calibration files are kept. (Signal files may be located in these directories or elsewhere; @@ -6951,7 +7176,7 @@ header file that names the signal file. If you need to create such a header file, refer to the description of the byte offset field in @cite{header(5)} (the specification of the header file -format in the @cite{WFDB Applications Guide}, or +format in the @cite{WFDB Applications Guide}) or @pxref{wfdbsetstart}. @item Record @@ -7015,7 +7240,8 @@ @item Signal file @cindex signal file (defined) A set of samples in time order, which represent a signal or signal -group. +group. Signal files usually have names of the form @var{record}@code{.dat}, +but this is only a convention and is not required. @item Signal group @cindex signal group (defined) @@ -7167,7 +7393,7 @@ This will create a directory with a name of the form @code{wfdb-}@var{m.n.r}, where @var{m.n.r} is the version number of the included WFDB library (e.g., -@code{10.2.5}). Enter this directory. +@code{10.2.6}). Enter this directory. You should now be ready to configure, compile, and install the software, using the commands: @@ -7207,17 +7433,11 @@ from @code{http://@-www.physio@-net.org/physio@-tools/libwww/}. You may omit this step if you do not wish to have NETFILES support. -Download -@code{http://www.physio@-net.org/physio@-tools/binaries/win@-dows/bin/which@-.exe} -and put it into a directory in your PATH. (This utility is needed by -@code{configure} in a later step. The sources for @code{which.exe} are -available within @code{http://www.physio@-net.org/physio@-tools/util@-ities/}.) - Open a Cygwin terminal window (the Cygwin installer will have added this to your MS-Windows start menu). Perform the remaining steps by typing the commands given below into the terminal window. -Check that @code{which} and @code{gcc} are accessible by typing the command: +Check that @code{gcc} is accessible by typing the command: @example which gcc @@ -7248,7 +7468,7 @@ This will create a directory with a name of the form @code{wfdb-}@emph{m.n.r}, where @emph{m.n.r} is the version number of the included WFDB library (e.g., -@code{10.2.5}). Enter this directory. +@code{10.2.6}). Enter this directory. You should now be ready to configure, compile, and install the software, using the commands: @@ -7326,6 +7546,7 @@ your system). If you use these programs often, you may wish to include the directory in which they are kept in your search path. +@cindex WFDB path To use any of these programs, you will need to set the database path first (@pxref{WFDB path}), unless the default database path (@samp{. http://www.physio@-net.org/physio@-bank/data@-base}) is suitable. @@ -7747,7 +7968,7 @@ unneeded functionality in order to conserve memory for special applications. The @file{calib.c} package is not referenced by any other WFDB library modules. For signal processing applications that do not involve -ECGs, the entire @file{annot.c} package may be removed (with trivial +annotations, the entire @file{annot.c} package may be removed (with trivial modifications to the functions in @file{wfdbinit.c}). If you wish to add functions to the library, you will find that it will be easier to maintain your modified version and to merge updates if you preserve the @@ -7758,6 +7979,7 @@ using the low-level I/O routines in @file{wfdbio.c} for reading and writing them in a machine-independent format. +@cindex WFDB path Porting the WFDB library to another environment is a straightforward operation if an ANSI C compiler is available in the target environment. Since all direct access to database files is performed using the @@ -7802,6 +8024,7 @@ @itemx MIMIC Database @itemx Other reference databases of physiologic signals @itemx WFDB Software Package +@sp 1 @display WWW: @code{http://www.physionet.org/} @end display @@ -7815,13 +8038,13 @@ about ten public mirrors are located elsewhere in the US and around the world (see @code{http://@-www.@-physio@-net.@-org/@-mirrors/} for a list). -@sp 1 @cindex CD-ROM @cindex MIT DB @cindex waveform editor @itemx MIT-BIH Arrhythmia Database CD-ROM @itemx MIT-BIH Polysomnographic Database CD-ROM @itemx Software for Physiologic Databases with Samples CD-ROM +@sp 1 @display MIT-BIH Database Distribution MIT Room E25-505A @@ -7833,12 +8056,12 @@ telephone: +1 617 253 7424 @end display -@sp 1 @cindex CD-ROM @cindex ESC DB @item European ST-T Database CD-ROM @itemx European ST-T Database Directory @itemx VALE Database Directory +@sp 1 @display National Research Council (CNR) Institute of Clinical Physiology Dept. of Bioengineering and Medical Informatics @@ -7850,9 +8073,9 @@ telefax: +39 050 503596 @end display -@sp 1 @cindex AHA DB @item AHA Database for Evaluation of Ventricular Arrhythmia Detectors +@sp 1 @display ECRI 5200 Butler Pike @@ -7863,10 +8086,10 @@ telephone: +1 610 825 6000 @end display -@sp 1 @cindex CD-ROM @cindex MGH DB @item MGH/Marquette Foundation Waveform Database CD-ROMs +@sp 1 @display Anaesthesia/Bioengineering Unit Massachusetts General Hospital @@ -7881,10 +8104,10 @@ arterial, pulmonary arterial, and central venous pressure, respiration, and CO2), which has been issued on 10 CD-ROMs. -@sp 1 @item American National Standard ANSI/AAMI EC38:1998, Ambulatory Electrocardiographs @itemx American National Standard ANSI/AAMI EC57:1998 Testing and Reporting Performance @itemx @ @ @ Results of Cardiac Rhythm and ST Segment Measurement Algorithms +@sp 1 @display Association for the Advancement of Medical Instrumentation 1110 N Glebe Road, Suite 220 @@ -7895,8 +8118,8 @@ telefax: +1 703 276 0793 @end display -@sp 1 @item Computers in Cardiology +@sp 1 @display WWW: @code{http://www.cinc.org/} @end display @@ -7911,8 +8134,8 @@ usually appear about 3 months after the date of the conference. CinC will be in Memphis, Tennessee in 2002, and in Thessaloniki in 2003. -@sp 1 @item Proceedings of Computers in Cardiology (ISSN 0276-6574) +@sp 1 @display IEEE Customer Service @@ -7935,6 +8158,7 @@ @itemx Larry Wall's `patch' program, with GNU revisions @itemx GNU groff, gtbl, and related text formatting utilities @itemx GNU info and makeinfo (standalone hypertext browser and formatter) +@sp 1 @display Free Software Foundation @@ -7954,8 +8178,8 @@ other archive sites. Please support the FSF with a donation if you use GNU software. -@sp 1 @item @TeX{} for Unix systems +@sp 1 This software is available by anonymous FTP from CTAN (Comprehensive TeX Archive Network) mirrors, including @code{ftp.tex.ac.uk}, @code{ftp.dante.de}, @@ -7971,8 +8195,8 @@ are widely available; visit the web site of the @TeX{} Users Group (below) for pointers. -@sp 1 @item General information on @TeX{} +@sp 1 @display TeX Users Group PO Box 2311 @@ -7984,11 +8208,11 @@ telefax: +1 503 223 9994 @end display -@sp 1 @cindex X11 @cindex X Window System @item X11R6 (the X Window System, Version 11, Release 6) @itemx XView +@sp 1 @display The Open Group 29B Montvale Ave. @@ -8006,7 +8230,6 @@ Sources for XView are also available from PhysioNet. -@sp 1 @cindex GNU/Linux @cindex Linux @item GNU/Linux @@ -8072,7 +8295,6 @@ telefax: +49 911 7417755 @end display -@sp 1 @item Compilers and software development systems Any ANSI/ISO C compiler (or any K&R C compiler, if you still have one) @@ -8123,8 +8345,8 @@ @code{gcc}, a free 32-bit DOS extender, and many of the same utilties as Cygwin and MinGW. -@sp 1 @item Microstar DAP analog interface boards for PCs +@sp 1 @display Microstar Laboratories 2265 116th Avenue N.E. @@ -8136,9 +8358,9 @@ telefax: +1 425 453 3199 @end display -@sp 1 @cindex Web browser @item Web browsers +@sp 1 The most popular Web browsers may be downloaded by anonymous FTP. @@ -8271,7 +8493,7 @@ @ifinfo WFDB Programmer's Guide -Tenth Edition (revised and with additions for WFDB library version 10.2.5) +Tenth Edition (revised and with additions for WFDB library version 10.2.6) George B. Moody diff -Naur wfdb-10.2.5/doc/wug-src/Makefile wfdb-10.2.6/doc/wug-src/Makefile --- wfdb-10.2.5/doc/wug-src/Makefile Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/doc/wug-src/Makefile Mon Jun 24 22:43:07 2002 @@ -55,12 +55,12 @@ # PostScript 'make wug.ps' (requires latex and dvips) # _____________________________________________________________________________ # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables @@ -68,7 +68,7 @@ VDEFS = -DWFDB_MAJOR=$(MAJOR) -DWFDB_MINOR=$(MINOR) -DWFDB_RELEASE=$(RELEASE) # _____________________________________________________________________________ -PACKAGE=wfdb-10.2.5 +PACKAGE=wfdb-10.2.6 # file: linux.def G. Moody 31 May 2000 # Last revised: 17 December 2001 # 'make' definitions for compiling the WFDB Software Package under Linux @@ -190,8 +190,8 @@ lib-post-uninstall: echo "Nothing to be done for lib-post-uninstall" # _____________________________________________________________________________ -# file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 20 December 2001 +# file: Makefile.tpl G. Moody 24 May 2000 +# Last revised: 20 June 2002 # Change the settings below as appropriate for your setup. # Set COLORS to 'color' if you have a color printer and would like to print @@ -250,20 +250,26 @@ $(PSPRINT) wugcover.ps wug.ps # 'make wug.html': format the WAVE User's Guide as HTML -wug.html: +# 'wug.aux' is listed as a prerequisite because the figure numbers are +# recorded there. It doesn't matter if it was created by latex or pdflatex. +# Note that the file 'wug.html' created at the end of this process is empty; +# it is created only so that 'make' can easily determine if the real HTML +# files (in ../wug/) are up-to-date. +wug.html: wug.tex wug.aux cp -p ../misc/icons/* wave/png/* ../../examples/stdev.c \ wave/misc/example.xws ../wug wave/scripts/wugfigures -color # get a set of figures latex2html -dir ../wug -local_icons \ -up_url="../manuals.shtml" -up_title="Books about PhysioToolkit" wug - wave/scripts/wugfigures -clean # remove figures from this directory cp wave/scripts/dossify-html wave/scripts/fixlinks ../wug cd ../wug; ./dossify-html *.html cd ../wug; rm -f dossify-html fixlinks *.html *.orig cd ../wug; rm -f .ID_MAP .IMG_PARAMS .ORIG_MAP images.* mv ../wug/*.pl . + wave/scripts/fixwug.sh ../wug cd ../wug; ln -s wug.htm index.html; find `pwd` -print | doschk wave/scripts/fixinfo >../../wave/wave.info + touch wug.html # 'make wug.pdf': format the WAVE User's Guide as PDF wug.pdf: wug.tex @@ -281,10 +287,9 @@ pdflatex wug makeindex wug.idx pdflatex wug - wave/scripts/wugfigures -clean # 'make wug.ps': format the WAVE User's Guide as PostScript -wug.ps: wug.tex +wug.ps: wug.tex wave/scripts/wugfigures -$(COLORS) # get a set of figures rm -f wug.aux wug.idx wug.ind wug.toc latex wug @@ -293,9 +298,16 @@ makeindex wug.idx latex wug dvips $(D2PARGS) -o wug.ps wug.dvi - wave/scripts/wugfigures -clean # remove figures from this directory + +# 'wug.aux' is created by 'latex wug' or 'pdflatex wug' (which make slightly +# different versions of 'wug.aux'). It is a separate target because it is +# needed by 'make wug.html' (to obtain the figure numbers). Either version +# of 'wug.aux' is acceptable for 'make wug.html'. +wug.aux: wug.tex + $(MAKE) wug.ps # 'make clean': remove intermediate and backup files clean: - rm -rf internals.pl labels.pl wug.aux wug.dvi wug.idx wug.ilg wug.ind \ - wug.log wug.out wug.pdf wug.ps wug.toc .xvpics *~ + wave/scripts/wugfigures -clean # remove figures from this directory + rm -rf internals.pl labels.pl wug.aux wug.dvi wug.html wug.idx \ + wug.ilg wug.ind wug.log wug.out wug.pdf wug.ps wug.toc .xvpics *~ diff -Naur wfdb-10.2.5/doc/wug-src/Makefile.tpl wfdb-10.2.6/doc/wug-src/Makefile.tpl --- wfdb-10.2.5/doc/wug-src/Makefile.tpl Thu Dec 20 17:38:41 2001 +++ wfdb-10.2.6/doc/wug-src/Makefile.tpl Mon Jun 24 21:56:37 2002 @@ -1,5 +1,5 @@ -# file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 20 December 2001 +# file: Makefile.tpl G. Moody 24 May 2000 +# Last revised: 20 June 2002 # Change the settings below as appropriate for your setup. # Set COLORS to 'color' if you have a color printer and would like to print @@ -58,20 +58,26 @@ $(PSPRINT) wugcover.ps wug.ps # 'make wug.html': format the WAVE User's Guide as HTML -wug.html: +# 'wug.aux' is listed as a prerequisite because the figure numbers are +# recorded there. It doesn't matter if it was created by latex or pdflatex. +# Note that the file 'wug.html' created at the end of this process is empty; +# it is created only so that 'make' can easily determine if the real HTML +# files (in ../wug/) are up-to-date. +wug.html: wug.tex wug.aux cp -p ../misc/icons/* wave/png/* ../../examples/stdev.c \ wave/misc/example.xws ../wug wave/scripts/wugfigures -color # get a set of figures latex2html -dir ../wug -local_icons \ -up_url="../manuals.shtml" -up_title="Books about PhysioToolkit" wug - wave/scripts/wugfigures -clean # remove figures from this directory cp wave/scripts/dossify-html wave/scripts/fixlinks ../wug cd ../wug; ./dossify-html *.html cd ../wug; rm -f dossify-html fixlinks *.html *.orig cd ../wug; rm -f .ID_MAP .IMG_PARAMS .ORIG_MAP images.* mv ../wug/*.pl . + wave/scripts/fixwug.sh ../wug cd ../wug; ln -s wug.htm index.html; find `pwd` -print | doschk wave/scripts/fixinfo >../../wave/wave.info + touch wug.html # 'make wug.pdf': format the WAVE User's Guide as PDF wug.pdf: wug.tex @@ -89,10 +95,9 @@ pdflatex wug makeindex wug.idx pdflatex wug - wave/scripts/wugfigures -clean # 'make wug.ps': format the WAVE User's Guide as PostScript -wug.ps: wug.tex +wug.ps: wug.tex wave/scripts/wugfigures -$(COLORS) # get a set of figures rm -f wug.aux wug.idx wug.ind wug.toc latex wug @@ -101,9 +106,16 @@ makeindex wug.idx latex wug dvips $(D2PARGS) -o wug.ps wug.dvi - wave/scripts/wugfigures -clean # remove figures from this directory + +# 'wug.aux' is created by 'latex wug' or 'pdflatex wug' (which make slightly +# different versions of 'wug.aux'). It is a separate target because it is +# needed by 'make wug.html' (to obtain the figure numbers). Either version +# of 'wug.aux' is acceptable for 'make wug.html'. +wug.aux: wug.tex + $(MAKE) wug.ps # 'make clean': remove intermediate and backup files clean: - rm -rf internals.pl labels.pl wug.aux wug.dvi wug.idx wug.ilg wug.ind \ - wug.log wug.out wug.pdf wug.ps wug.toc .xvpics *~ + wave/scripts/wugfigures -clean # remove figures from this directory + rm -rf internals.pl labels.pl wug.aux wug.dvi wug.html wug.idx \ + wug.ilg wug.ind wug.log wug.out wug.pdf wug.ps wug.toc .xvpics *~ diff -Naur wfdb-10.2.5/doc/wug-src/wave/misc/pstoimg wfdb-10.2.6/doc/wug-src/wave/misc/pstoimg --- wfdb-10.2.5/doc/wug-src/wave/misc/pstoimg Wed Dec 31 19:00:00 1969 +++ wfdb-10.2.6/doc/wug-src/wave/misc/pstoimg Mon Jun 24 09:38:54 2002 @@ -0,0 +1,1515 @@ +#! /usr/bin/perl -w +############################################################################## +# $Id: pstoimg.pin,v 1.11 1999/10/25 21:18:22 MRO Exp $ +# +# pstoimg +# +# Accompanies LaTeX2HTML +# +# Script to convert an arbitrary PostScript image to a cropped GIF or PNG +# image suitable for incorporation into HTML documents as inlined images +# to be viewed with WWW browsers. +# +# This software is provided as is without any guarantee. +# +############################################################################## +# +# $Log: pstoimg.pin,v $ +# Revision 1.11 1999/10/25 21:18:22 MRO +# +# -- added more configure options (Jens' suggestions) +# -- fixed bug in regexp range reported by Achim Haertel +# -- fixed old references in documentation (related to mail list/archive) +# +# Revision 1.10 1999/10/06 22:04:13 MRO +# +# -- texexpand: latex2html calls texexpand with the -out option instead of +# output redirection: this is safer on non-UNIX platforms +# -- pstoimg: now there's no default cropping (useful for standalone +# conversions). latex2html was changes appropriately +# -- minor cleanups in latex2html script and documentation +# +# Revision 1.9 1999/09/14 22:02:02 MRO +# +# -- numerous cleanups, no new features +# +# Revision 1.8 1999/07/19 09:51:00 RRM +# -- added -aaliastext switch, for easier way to specify anti-aliased +# font characters, without also anti-aliasing other graphics objects. +# +# Revision 1.7 1999/06/24 07:28:59 MRO +# +# +# -- removed L2HMODULE +# -- fixed processing of -info switch +# -- changed option order for dvips on win32 (thanks JCL) +# -- bumped version to 99.2a8 +# +# Revision 1.6 1999/06/06 14:24:50 MRO +# +# +# -- many cleanups wrt. to TeXlive +# -- changed $* to /m as far as possible. $* is deprecated in perl5, all +# occurrences should be removed. +# +# Revision 1.5 1999/06/04 20:14:25 MRO +# +# +# -- Reworked option parsing completely. Should behave much the same as before, +# options with -no_* work just like before. +# -- Changed $NOFORK to $CAN_FORK and inverted the logic. +# -- Small debugging enhancement in pstoimg +# +# Revision 1.4 1999/06/04 15:30:15 MRO +# +# +# -- fixed errors introduced by cleaning up TMP* +# -- made pstoimg -quiet really quiet +# -- pstoimg -debug now saves intermediate result files +# -- several fixes for OS/2 +# +# Revision 1.3 1999/06/01 06:55:35 MRO +# +# +# - fixed small bug in L2hos/* +# - added some test_mode related output to latex2html +# - improved documentation +# - fixed small bug in pstoimg wrt. OS2 +# +# Revision 1.2 1999/05/17 21:30:59 MRO +# +# +# -- make texexpand warning-free and start making it use strict +# compliant +# +# Revision 1.1 1999/05/11 06:10:00 MRO +# +# +# - merged config stuff, did first tries on Linux. Simple document +# passes! More test required, have to ger rid of Warnings in texexpand +# +# Revision 1.18 1999/05/05 19:47:03 MRO +# +# +# - many cosmetic changes +# - final backup before merge +# +# Revision 1.17 1999/03/15 23:00:53 MRO +# +# +# - moved L2hos modules to top level directory, so that no dir- +# delimiter is necessary in the @INC-statement. +# - changed strategy for "shave": Do not rely on STDERR redirection any +# more (caused problems on at least Win32) +# +# Revision 1.16 1999/02/14 23:44:34 MRO +# +# +# -- first attempt to fix Win32 problems +# +# Revision 1.15 1999/02/11 00:18:29 MRO +# +# +# -- cleaned up warppers, TeXlive stuff and Makefile +# +# Revision 1.14 1999/02/10 01:37:12 MRO +# +# +# -- changed os-dependency structure again - now neat OO modules are +# used: portable, extensible, neat! +# -- some minor cleanups and bugfixes +# +# Revision 1.13 1998/12/07 23:19:58 MRO +# +# +# -- added POD documentation to pstoimg and did a general cleanup +# -- some finetuning of config procedure and modules +# +# Revision 1.12 1998/10/31 14:13:05 MRO +# -- changed OS-dependent module loading strategy: Modules are now located in +# different (OS-specific) directories nut have the same name: Easier to +# maintain and cleaner code +# -- Cleaned up config procedure +# -- Extended makefile functionality +# +# Revision 1.11 1998/08/09 20:45:20 MRO +# -- some cleanup +# +# Revision 1.10 1998/06/14 14:10:38 latex2html +# -- Started to implement TeXlive configuration and better OS specific +# handling (Batch files) (Marek) +# +# Revision 1.9 1998/06/07 22:35:24 latex2html +# -- included things I learned from the Win95 port to config procedure: +# GS_LIB, Win32 module calls, directory separator stuff, ... (Marek) +# +# Revision 1.8 1998/06/01 12:57:56 latex2html +# -- Cleanup and cosmetics. +# +# Revision 1.7 1998/05/14 22:27:37 latex2html +# -- more work on config procedure (Makefile, GS_LIB) +# -- tested pstoimg in 98.1 environment successfully on Linux +# +# Revision 1.6 1998/05/06 22:31:09 latex2html +# -- Enhancements to the config procedure: Added a "generic" target +# in the Makefile for the TeXlive CD (not perfect yet) +# -- included test for kpsewhich / Web2C +# -- included latest stuff from Override.pm into os_*.pm +# +# Revision 1.5 1998/04/28 22:18:11 latex2html +# - The platform specific stuff is now kept in a separate perl module. This +# does not introduce significant overhead and enhances maintainability. +# +# Revision 1.4 1998/03/19 23:38:06 latex2html +# -- made pstoimg plug-in compatible with old one (touchwood!) +# -- cleaned up, added some comments +# -- inserted version information output +# -- incorporated patches to make OS/2 run better (thanks Uli) +# -- updated Makefile: make, make test, make install should work now +# +# Revision 1.3 1998/03/11 23:44:00 latex2html +# -- cleaned up config.pl and reworked dvips checks +# -- got pstoimg.pin up to par with the regular pstoimg +# -- cosmetic changes +# -- runs now under Win95 with Fabrice Popineau's Win32 tools (gs, TeX,...) +# +# Revision 1.2 1998/03/02 23:38:40 latex2html +# Reworked configuration procedure substantially. Fixed some killing bugs. +# Should now run on Win32, too. +# The file prefs.pm contains user-configurable stuff for DOS platforms. +# UNIX users can override the settings with the configure utility (preferred). +# +# Revision 1.1 1998/02/14 19:31:55 latex2html +# Preliminary checkin of configuration procedure +# +# (end CVS log) +############################################################################### + +# This file has been automatically generated by build.pl from pstoimg.pin +# Do not edit this file as your changes will be lost when reconfiguring. +# If you want to supply patches, please apply them to pstoimg.pin and send +# the diff relative to the original pstoimg.pin. Thank you. + +=head1 NAME + +pstoimg - Convert a PostScript file to a bitmap image using +Ghostscript and the Netpbm utilities + +=cut + +use 5.003; +use strict; +#use diagnostics; +use vars qw(*SAVEERR $LATEX2HTMLDIR $SCRIPT); + +# This variable points to the DIRECTORY where the latex2html files +# can be found. + +use Getopt::Long; + + +# see below for a description of the environment + +BEGIN { + # print "scanning for l2hdir\n"; + if($ENV{LATEX2HTMLDIR}) { + $LATEX2HTMLDIR = $ENV{LATEX2HTMLDIR}; + } else { + $ENV{LATEX2HTMLDIR} = $LATEX2HTMLDIR = '/usr/share/latex2html'; + } + + if(-d $LATEX2HTMLDIR) { + push(@INC,$LATEX2HTMLDIR); + } else { + die qq{Fatal: Directory "$LATEX2HTMLDIR" does not exist.\n}; + } +} + +use L2hos; # load OS-specific stuff + +my $RELEASE = '2K.1beta'; +my ($VERSION) = q$Revision: 1.11 $ =~ /:\s*(\S+)/; + +$| = 1; # unbuffer STDOUT + +my $dd = L2hos->dd; # Directory delimiter +my $prompt; +($prompt = $0) =~ s|^.*[/\\]||; + +# Configuration as determined by "configure" +# +# Ghostscript +my $GS = '/usr/bin/gs'; +my $GSDEVICE = 'pnmraw'; +my $GSALIASDEVICE = 'ppmraw'; +# Supported format(s) +my @IMAGE_TYPES = qw(png); +# Netpbm +my $PNMCROP = '/usr/bin/pnmcrop'; +my $PPMQUANT = '/usr/bin/ppmquant'; +my $PNMFLIP = '/usr/bin/pnmflip'; +my $PNMCAT = '/usr/bin/pnmcat'; +my $PNMFILE = '/usr/bin/pnmfile'; +my $PBMMAKE = '/usr/bin/pbmmake'; +# PNG support +my $PNMTOPNG = '/usr/bin/pnmtopng'; +# Temporary diskspace +my $def_tmp = '/tmp'; # Space for temporary files + +# Some lengths used by dvips +# MRO: Is this true for all runs of dvips? + +my $PAGE_HEIGHT = 841.889; # dvips page height, in pts. +my $PAGE_WIDTH = 595.275; # dvips page width, in pts. +my $PAGE_HMARGIN = 72; # dvips margin: 1 inch = 72pt +my $PAGE_VMARGIN = 72; # dvips margin: 1 inch = 72pt + +# The color to be made transparent +my $trans_color = '#ffffff'; + +############################################################################### +# Default settings +# Environment overrides defaults, command line options override everything + +unless(@ARGV) { + print_help(); + exit 0; + } + +=head1 SYNOPSIS + +B<pstoimg> B<-help> | B<-version> + +B<pstoimg> +S<[ B<-antialias> ]> +S<[ B<-aaliastext> ]> +S<[ B<-center> I<num> ]> +S<[ B<-color> I<num> ]> +S<[ B<-crop> I<code> ]> +S<[ B<-debug> ]> +S<[ B<-density> I<num>]> +S<[ B<-depth> I<num> ]> +S<[ B<-discard> ]> +S<[ B<-flip> I<code> ]> +S<[ B<-geometry> I<X>xI<Y> ]> +S<[ B<-interlaced> ]> +S<[ B<-margins> I<X>,I<Y> ]> +S<[ B<-multipage> ]> +S<[ B<-out> I<file> ]> +S<[ B<-quiet> ]> +S<[ B<-rightjustify> I<num> ]> +S<[ B<-scale> I<num> ]> +S<[ B<-tmp> I<path> ]> +S<[ B<-topjustify> [B<x>]I<num> ]> +S<[ B<-transparent> ]> +S<[ B<-type> I<type> ]> +S<[ B<-shoreup> I<num>[B<d>] ]> +S<[ B<-white> ]> +I<file> +S<[ I<file2> ... ]> + +=cut + +my %opt = (); +unless(&GetOptions(\%opt, qw(-help -version -debug -discard -antialias -aaliastext + -multipage -type=s -gif -png -out=s -depth=i -color=i -flip=s -density=i + -scale=f -geometry=s -margins=s -crop=s -transparent -interlaced + -rightjustify=i -center=i -topjustify=s -shoreup=s -tmp=s -white -quiet))) { + print_usage("$prompt: Error: Invalid option(s) specified."); + exit 1; +} + +=head1 OPTIONS + +The command line options may be abbreviated to the shortest unique +prefix. + +=over 4 + +=item B<-help> + +Show this help page and exit. + +=cut + +if($opt{help}) { + print_help(); + exit 0; + } + +=item B<-version> + +Show the release and version of pstoimg and exit. + +=cut + +if($opt{version}) { + print_version(); + exit 0; + } + +banner() unless($opt{quiet}); + +=item B<-antialias> + +Use Ghostscript's anti-aliasing feature for rendering "softer" images. +This applies to lines and edges of polygonal and oval or circular shapes. +Only valid if Ghostscipt 4.03 or higher is installed. + +=item B<-aaliastext> + +Use Ghostscript's anti-aliasing feature for "smoother" font characters, +without the jagged edges. Similar to B<-antialias> for graphic components. +Only valid if Ghostscipt 4.03 or higher is installed. + +=item B<-center> I<num> + +Add the appropriate amount of whitespace to the left of the image so +that the image appears to be centered in a total width of I<num> pixels. + +=cut + +my $CENTER = 0; # No centering by default +if($opt{center}) { + $CENTER = $opt{center}; + die <<"EOF" unless ($CENTER =~ /^\d+$/ && $CENTER > 0); +$prompt: Error: Illegal width for -center specified: "$CENTER" + Value must be a positive integer. +EOF + } + +=item B<-crop> I<code> + +Crop the bitmap from the given directions. I<code> may be a string of +several cropping instructions, which are executed strictly in the given +order. Possible values are: B<h> (horizontal, i.e. crop top and +bottom), B<v> (vertical), B<tblr> (top, bottom, left, right) and B<a> (all +directions). A special case is B<s>: "shave" the image at the bottom, but only +if a single line of whitespace exists. + +=cut + +my $EXTRA_CROP = ''; +if($opt{crop}) { + $EXTRA_CROP = lc($opt{crop}); + die <<"EOF" unless ( $EXTRA_CROP =~ /^([vhtblras]+)$/i ); +$prompt: Error: Illegal crop specified: "$EXTRA_CROP" + Crop must be h, v, t, b, l, r, a, s or combination +EOF + } + +=item B<-debug> + +Turn on debugging output. This can get rather verbose. Any intermediate +files generated are not removed to help debugging. + +=cut + +if($ENV{DEBUG}) { + $opt{debug} = 1; + } + +=item B<-density> I<num> + +The density (resolution) in DPI in which to render the bitmap. The default +is 72. + +=cut + +my $DENSITY = 72; +if($opt{density}) { + $DENSITY = $opt{density}; + } +elsif($ENV{DENSITY}) { + $DENSITY = $ENV{DENSITY}; + } +die <<"EOF" unless $DENSITY =~ /^\d+$/; +$prompt: Error: Illegal density specified: "$DENSITY" + Density must be an integer value. Default is 72. +EOF + +=item B<-depth> I<num> or B<-color> I<num> + +Specify the color depth of the bitmap. Legal values are 1 (black & white), +8 (256 colors) and 24 (true color). + +=cut + +unless($opt{depth}) { + if($opt{color}) { + $opt{depth} = $opt{color}; + } + elsif($ENV{DEPTH}) { + $opt{depth} = $ENV{DEPTH}; + } + else { + $opt{depth} = 8; + } + } +die <<"EOF" unless $opt{depth} =~ /^(1|8|24)$/; +$prompt: Error: Illegal color depth specified: "$opt{depth}" + Depth must be either 1, 8 or 24. +EOF + +=item B<-discard> + +Delete the input postscript file if the conversion was successful. Setting +the environment DISCARD to a true value (as perl sees it) has the same +effect. + +=cut + +if($ENV{DISCARD}) { + $opt{discard} = 1; + } + +=item B<-flip> I<code> + +Flip all generated output bitmaps. The following codes are recognized: +lr (flip left-right), tb (flip top-bottom), xy (flip bottom/left-top/right), +r90 and ccw (rotate by 90 degrees counterclockwise), r270 and cw (rotate +90 degrees clockwise) and r180 (rotate 180 degrees). + +=cut + +if($opt{flip}) { + $opt{flip} = lc($opt{flip}); + die <<"EOF" unless $opt{flip} =~ /^(lr|tb|xy|r90|ccw|r270|cw|r180)$/; +$prompt: Error: Illegal flip option specified: "$opt{flip}" + Flip must be one of: lr tb xy r90 ccw r270 cw r180 +EOF + } + +=item B<-geometry> I<X>xI<Y> + +Render only this "window" of the PostScript file. If given, this option +can dramatically reduce memory requirements and speed up conversion. The +geometry is automatically detected in case of EPS files (Encapsulated +PostScript). + +=cut + +my $GEOMETRY = ''; +if($opt{geometry}) { + $GEOMETRY = $opt{geometry}; + if($GEOMETRY =~ s/-//o ) { + $EXTRA_CROP .= 'bl'; + } + die <<"EOF" unless ($GEOMETRY =~ /^\d+x\d+$/i); +$prompt: Error: Illegal geometry specified: "$GEOMETRY" + Geometry must be <width>x<height> +EOF + } + +=item B<-interlaced> + +Generate an interlaced bitmap. Interlaced images build up from coarse to +fine as they are loaded. This option may not work on every installation +and/or bitmap type, depending of the capabilities of external programs. + +=cut + +my $INTERLACE = 0; # Do not make interlaced images by default +if($opt{interlaced}) { + if($opt{type} eq 'gif') { + print "$prompt: Warning: Interlaced GIFs not supported.\n"; + } + $INTERLACE=1; + } + +=item B<-margins> I<X>,I<Y> + +The offset of the rectangle in the postscript file that is going to be +rendered from top/left. Can be used together with B<-geometry> to further +reduce the size of the intermediate bitmap file generated by Ghostscript. + +=cut + +if($opt{margins}) { + die <<"EOF" unless (($opt{margins} =~ /^(\d+),(\d+)$/)); +$prompt: Error: Illegal margins specified: "$opt{margins}" + Margins must be <hmargin>,<vmargin> +EOF + $PAGE_HMARGIN = $1; + $PAGE_VMARGIN = $2; + } + +=item B<-multipage> + +Process a multi-page PostScript file, i.e. create an individual bitmap +for every page. The resulting files are numbered: The decimal number +(starting with 1) is appended to the basename of the PostScript input +file (or the basename of the filename specified with B<-out>), while +keeping the extension. + +=item B<-out> I<file> + +The file where to write the bitmap. If multiple PostScript files are +supplied on the command line, this option is ignored. The bitmap type +extension is appended automatically if I<file> does not contain a dot. +In connection with B<-multipage> I<file> is extended by the page number +as shown in this example: + +-outfile foo.gif --------E<gt> foo1.gif, foo2.gif, ... + +=cut + +if(!$opt{out} && $ENV{OUTFILE}) { + $opt{out} = $ENV{OUTFILE}; + } + +=item B<-quiet> + +Do not print anything except error messages. + +=item B<-rightjustify> I<num> + +Add the appropriate amount of whitespace to the left of the image so that +it appears to be aligned to the right in a total width of I<num> pixels. + +=cut + +my $RIGHT_JUSTIFY = 0; # No right justifying by default +if($opt{rightjustify}) { + $RIGHT_JUSTIFY = $opt{rightjustify}; + die <<"EOF" unless ($RIGHT_JUSTIFY =~ /^\d+$/ && $RIGHT_JUSTIFY > 0); +$prompt: Error: Illegal width for -rightjustify specified: "$RIGHT_JUSTIFY" + Value must be a positive integer. +EOF + } + +=item B<-scale> I<factor> + +Scale the image by I<factor>. Valid choices are any numbers greater than +zero. Useful choices are numbers between 0.1 - 5. +Large numbers may generate very large intermediate files and will take +longer to process. If this option is omitted, the environment SCALE is +considered. + +=cut + +unless($opt{scale}) { + if($ENV{SCALE}) { + $opt{scale} = $ENV{SCALE}; + } + else { + $opt{scale} = 1; + } + } +die <<"EOF" unless ($opt{scale} =~ /^[\d.e]+$/i && $opt{scale} > 0); +$prompt: Error: Illegal scale specified: "$opt{scale}" + Scale must be nonnegative float value. +EOF + +=item B<-shoreup> I<num>[B<d>] + +Make height and width of the bitmap(s) an exact multiple of I<num>. If +I<num> is followed by a "d", then half the extra vertical space is placed +underneath. This option is useful, if you want to have "blown-up" images +of high quality for print, but downscale them in HTML using +C<E<lt>IMG WIDTH=x HEIGHT=yE<gt>>. If the actual image is is not an +integer multiple of x,y then browsers tend to display distorted images. + +=cut + +my $SHORE_UP = 0; # No pixel alignment by default +if($opt{shoreup}) { + $SHORE_UP = $opt{shoreup}; + die <<"EOF" unless $SHORE_UP =~ /^\d+d?$/i; +$prompt: Error: Illegal shore-up specified: "$SHORE_UP" + Value must be a positive integer, optionally followed by d +EOF + } + +=item B<-tmp> I<path> + +Use I<path> to store temporary files. Defaults to /tmp on this +installation. This parameter can be set by the environment B<TMP> or +B<TEMP>, too. + +=cut + +my $TMP = ''; +if($opt{tmp}) { + $opt{tmp} =~ s|\Q$dd\E+$||; # remove trailing directory separator(s) + if(-d $opt{tmp} && -r _ && -w _) { + $TMP = $opt{tmp}; + } else { + print "$prompt: Warning: Cannot use $opt{tmp} as temporary directory.\n"; + } +} +if(!$TMP && ($ENV{TMP} || $ENV{TEMP})) { + ($opt{tmp} = $ENV{TMP} || $ENV{TEMP}) =~ s|\Q$dd\E+$||; + if(-d $opt{tmp} && -r _ && -w _) { + $TMP = $opt{tmp}; + } else { + print "$prompt: Warning: Cannot use $opt{tmp} as temporary directory.\n"; + } +} +if(!$TMP && -d $def_tmp && -r _ && -w _) { + $TMP = $def_tmp; +} +print "$prompt: Temporary directory is $TMP\n" if($opt{debug}); + +=item B<-topjustify> [B<x>]I<num> + +Add padding whitespace to the image so that it gets a defined height. +If an integer value is given, it defines the total height. The whitespace +is added at the bottom. If the number is preceded by "x", then this +multiple of the image height is added as whitespace at the bottom. + +=cut + +my $TOP_JUSTIFY = 0; # No top justifying by default +if($opt{topjustify}) { + $TOP_JUSTIFY = $opt{topjustify}; + die <<"EOF" unless $TOP_JUSTIFY =~ /^x?\d+[.]?\d*$/i; +$prompt: Error: Illegal align specified: "$TOP_JUSTIFY" + Value must be positive numeric, optionally preceded by x +EOF + } + +=item B<-transparent> + +Generate transparent bitmaps, i.e. the background color (white) is +transparent if viewed with certain viewers (e.g. browsers). This option +may not be available due to missing capabilities of external +programs. + +=cut + +my $TRANSPARENT = 0; # Do not make make images transparent by default +if($opt{transparent}) { + $TRANSPARENT = 1; + } + +=item B<-type> I<type> + +Instruct pstoimg to render the bitmap in I<type> format. Depending on +the local installation, pstoimg is capable of generating either GIF or +PNG bitmaps. This site features the following types: png + +If omitted, the first type in this list is taken. + +=cut + +if($opt{type}) { + $opt{type} = lc($opt{type}); + die <<"EOF" unless grep($_ eq $opt{type},@IMAGE_TYPES); +$prompt: Error: This version of pstoimg does not support + "$opt{type}" image format. +EOF + } +else { + ($opt{type}) = @IMAGE_TYPES; # default image type + } +# Support -gif and -png for a transition period +if($opt{gif}) { + print qq{$prompt: Warning: The -gif switch is deprecated. Use "-type gif" instead.\n}; + if(grep($_ eq 'gif',@IMAGE_TYPES)) { + $opt{type} = 'gif'; + } + else { + die <<"EOF"; +$prompt: Error: This version of pstoimg does not support "gif" format. +EOF + } + } +if($opt{png}) { + print qq{$prompt: Warning: The -png switch is deprecated. Use "-type png" instead.\n}; + if(grep($_ eq 'png',@IMAGE_TYPES)) { + $opt{type} = 'png'; + } + else { + die <<"EOF"; +$prompt: Error: This version of pstoimg does not support "png" format. +EOF + } + } + +=item B<-white> + +Remove TeX's page color information from the PostScript file before +converting so that a white background is used. + +=back + +=cut + +# do some consistency checks on the options + +if($TRANSPARENT && $opt{type} eq 'gif') { + print "$prompt: Warning: Transparent GIFs not supported.\n"; + } + +die <<"EOF" if($RIGHT_JUSTIFY && $CENTER); +$prompt: Error: Conflicting options -center and -rightjustify. +EOF + +# now setup some parameters + +# calculate dpi resolution from density and scale +$DENSITY = int($opt{scale} * $DENSITY + .5) if($opt{scale} != 1); + +my $reduce_color = ''; +if($opt{depth} == 1) { + $reduce_color = "$PPMQUANT 2"; + } +elsif ($opt{depth} == 8) { + $reduce_color = "$PPMQUANT 256"; + } + +my $gs_aalias = ''; +if($opt{antialias}) { + $GSDEVICE = $GSALIASDEVICE; + if($opt{depth} == 1) { + $gs_aalias = '-dTextAlphaBits=4 '; + $reduce_color = "$PPMQUANT -floyd 256"; + } + else { + $gs_aalias = '-dTextAlphaBits=4 -dGraphicsAlphaBits=4 '; + } + } +elsif ($opt{aaliastext}) { + $GSDEVICE = $GSALIASDEVICE; + $gs_aalias = '-dTextAlphaBits=4 '; + $reduce_color = "$PPMQUANT -floyd 256"; + } +my $PAPERSIZE = $ENV{PAPERSIZE} || ''; +# This rx matches float values in Bounding Box expressions +my $Brx = '-?\d+(?:\.\d*|)'; + +############################################################################## +# Main program + +=head1 DESCRIPTION + +B<pstoimg> iterates over the given input files and runs them through +Ghostscipt. The resulting pnm (portable anymap files) are processed +with different Netpbm tools (cropping, color mapping, aligning, ...) +and finally converted into (currently) either GIF or PNG format. The +bitmaps can now be included e.g. in WWW pages. + +The PostScript file is converted as is. If a valid bounding box is +found (EPS format), then only this area is converted. The image is +I<not> cropped by default. + +=cut + +die "$prompt: Error: No input file(s) specified\n" + unless(@ARGV); + +# suppress diagnostics messages if possible +my $NULLFILE = '/dev/null'; +open(STDERR, ">$NULLFILE") unless($opt{debug}); + +my $exit = 0; + +$opt{out} = '' if(@ARGV > 1); # disable -out if multiple ps files given + +my $psfile; +foreach $psfile (@ARGV) { + unless (-f $psfile) { + print qq{$prompt: Error: Cannot find file "$psfile": $!\n}; + exit 1; + } + $exit += (&pstoimg($psfile) ? 0 : 1); +} + +=head1 RETURN VALUE + +=over 4 + +=item 0 + +if everything went all right + +=item x + +(x != 0) something went wrong. See the message output. + +=back + +=cut + +exit $exit ? 1 : 0; + +############################################################################## +# Subroutines + +sub pstoimg { + my ($psfile) = @_; + + print "$prompt: Processing $psfile\n" unless($opt{quiet}); + # remove a trailing suffix the same way a shell would do it + my $base = $psfile; + $base =~ s|[.][^.$dd$dd]*$||; + + my $outfile; + if($opt{out}) { + $outfile = $opt{out}; + # append the type unless -outfile has a "." in it + $outfile .= ".$opt{type}" unless($outfile =~ /[.]/); + } + else { + $outfile = "$base.$opt{type}"; + } + + # Invoke Ghostscript + my $pnmdir = $TMP ? "$TMP$dd" : ".$dd"; + my $pnmbase = "p$$"; # keep it short for dos + my $pnmfile = $pnmdir . + ($opt{multipage} ? "%d_${pnmbase}.pnm" : "$pnmbase.pnm"); + + ps2pnm($psfile,$pnmfile) || return 0; + + my $ok = 1; + if (-f $pnmfile) { + if(crop_scale_etc($pnmfile, $outfile)) { + L2hos->Unlink($pnmfile) unless($opt{debug}); + } + else { + return 0; + } + } + elsif($opt{multipage}) { + unless(opendir(DIR,$pnmdir)) { + print qq{$prompt: Error: Could not open directory "$pnmdir": $!\n}; + return 0; + } + my @list = grep(/^\d+_\w*\./,readdir(DIR)); + closedir(DIR); + if(@list) { + my $i; + foreach $i (@list) { + my ($n) = $i =~ /^(\d+)_/; + my $j = $outfile; + $j =~ s|(\.[^/.]*)$|$n$1|; + if(crop_scale_etc("$pnmdir$i", $j)) { + L2hos->Unlink("$pnmdir$i") unless($opt{debug}); + } + else { + $ok = 0; + } + } + } + else { + goto not_found; + } + } + else { + not_found: + print "$prompt: Error: Couldn't find pnm output of $psfile\n"; + } + L2hos->Unlink($psfile) if($opt{discard} && !$opt{debug}); + $ok; + } + +sub ps2pnm { + my ($psfile,$pnmfile) = @_; + my $gs_size = $PAPERSIZE ? "-sPAPERSIZE=$PAPERSIZE" : ''; + my $gs_density = ($DENSITY != 72) ? "-r$DENSITY" : ''; + + my ($bbx, $bby, $bbw, $bbh) = (0,0,0,0); + my $max_lines = 100; + my ($epsf,$have_geometry) = (0,0); + + # Parse postscript file for information + unless(open(PS, "<$psfile")) { + print qq{$prompt: Error: Cannot read "$psfile": $!}; + return 0; + } + $_ = <PS>; # read one line + if( /^%!.*EPSF/ ) { + # we're in a EPSF file + $epsf = 1; + } + if($GEOMETRY || $epsf) { + while (defined ($_ = <PS>)) { + # Look for bounding box comment + # MRO: add support of precise bounding boxes + if ($epsf && ( + /^%+(?:HiRes|Exact)BoundingBox:\s+($Brx)\s+($Brx)\s+($Brx)\s+($Brx)/o || + /^\%\%BoundingBox:\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)/)) { + $bbx = 0 - $1; $bby = 0 - $2; + $bbw = $3 + $bbx; $bbh = $4 + $bby; + if(($bbw > 0) && ($bbh > 0)) { # we have a valid bounding box + print "$prompt: EPSF dimensions are ${bbw}x$bbh\n" if($opt{debug}); + # this overrides the -geometry switch + if($DENSITY) { # scale the output + my $scale = $DENSITY / 72.0; + $bbw *= $scale; + $bbh *= $scale; + } + $bbw = int($bbw + 0.99); + $bbh = int($bbh + 0.99); + $GEOMETRY = "${bbw}x${bbh}"; + $have_geometry = 1; + last; + } + } + # Look for page size information + elsif($GEOMETRY && /TeXDict\s+begin\s+(\d+)\s+(\d+)\s+/) { + $PAGE_WIDTH = int($1 / 65536 * 72 /72.27 +.5); + $PAGE_HEIGHT = int($2 / 65536 * 72 /72.27 +.5); + print "$prompt: Page dimensions are ${PAGE_WIDTH}x$PAGE_HEIGHT\n" + if($opt{debug}); + # we don't have to look further for EPSF stuff at this point + last; + } + elsif(!$GEOMETRY && (/^\%\%EndComments/ || --$max_lines == 0)) { + # abort at a certain point to avoid scanning huge ps files + last; + } + } + } + close PS; + if($GEOMETRY && !$have_geometry) { # RRM: overrides $PAPERSIZE + # no geometry info found in the Postscript file + $bbx = $PAGE_HMARGIN; + $bby = $PAGE_HEIGHT - $PAGE_VMARGIN; + unless($GEOMETRY =~ /\s*(\d+)x(\d+)/i) { + print qq{$prompt: Illegal geometry "$GEOMETRY" specified.\n}; + return 0; + } + $bbw = $1 + 10; # allow for the side-bars + $bbh = $2; + $bby = int(-$bby + $bbh + 8); # allow small margin for error + $bbx = int(-$bbx + 5); # allow small margin for error + if($DENSITY) { + my $scale = $DENSITY / 72.0; + $bbw = int($scale * $bbw + .99); + $bbh = int($scale * $bbh + .99); + } + $bbw += 10; # add a 5pt margin for safety + $bbh += 40; # add a 20pt margin for safety + $GEOMETRY = "${bbw}x$bbh"; + $have_geometry = 1; + } + if($have_geometry) { + $gs_size = "-g$GEOMETRY "; + } + + my $ps_changed = 0; + if($have_geometry || $opt{white}) { + # Remove any Postscript commands concerning Papersize if -g switch is used + # thanks to Axel Ramge for identifying the problem and for this code + local($/) = undef; + open(PS,"<$psfile"); + my $ps = <PS>; + close(PS); + my $had_papersize; + if($have_geometry) { + $had_papersize = ($ps =~ s/\n%%BeginPaperSize.*?%%EndPaperSize[^\n]*\n/\n/sg); + } + my $had_nonwhite; + if($opt{white}) { + $had_nonwhite = ($ps =~ s/(\n\d+ \d+ bop gsave) \d*\.\d+ (TeXcolorgray clippath fill grestore)/$1 1 $2/s); + } + $ps_changed = $had_papersize || $had_nonwhite; + if($ps_changed) { + my $tmppsfile = $pnmfile; # was "tmpps$$.ps" + $tmppsfile =~ s/\.[^.]*$/.ps/; + unless(open(PS,">$tmppsfile") && (print PS $ps) && (close PS)) { + if($had_papersize) { + print <<"EOF"; +$prompt: Warning: Could not write "$tmppsfile": $! + "$psfile" contains %%Papersize comments. + Any of these should be removed else GS will fail. +EOF + } + if($had_nonwhite) { + print <<"EOF"; +$prompt: Warning: Could not write "$tmppsfile": $! + "$psfile" has a non-white background. + This may cause ugly images. +EOF + } + } + $psfile = $tmppsfile; + print qq{Debug: Papersize comment in "$psfile" deleted.\n} + if($had_papersize && $opt{debug}); + print qq{Debug: Background switched to white in "$psfile".\n} + if($had_nonwhite && $opt{debug}); + } + } + + my $gs_quiet = $opt{debug} ? '' : '-q -dNOPAUSE -dNO_PAUSE'; + my $out_redirect = $opt{debug} ? '' : "> $NULLFILE"; + my $gs_out = "-sOutputFile=$pnmfile"; + my $gsfile = $psfile; + # Ghostscript understands only '/' as path delimiter! + if($opt{debug}) { + print "$prompt: Running $GS $gs_quiet -sDEVICE=$GSDEVICE $gs_size $gs_density $gs_aalias $gs_out $out_redirect\n"; + print "GS>$bbx $bby translate\n" if($have_geometry); + print "GS>($gsfile) run\n"; + print "GS>showpage\n" if ($epsf); + print "GS>quit\n"; + } + open (GS, "|$GS $gs_quiet -sDEVICE=$GSDEVICE $gs_size $gs_density $gs_aalias $gs_out $out_redirect"); + print GS "$bbx $bby translate\n" if ($have_geometry); + print GS "($gsfile) run\n"; + print GS "showpage\n" if ($epsf); + print GS "quit\n"; + print "\n" if($opt{debug}); + unless(close(GS)) { + print "$prompt: Error: Ghostscript returned error status ",$?>>8,"\n"; + } + L2hos->Unlink($psfile) if($ps_changed && !$opt{debug}); + 1; + } + + +# This sub post-processes the PNM images that come out of Ghostscript. +# The image is cropped, flipped and finally converted to PNG or GIF. + +sub crop_scale_etc { + my ($in, $out) = @_; + + # create temp filename; should be auto-incrementable + my $tmp = $in; + $tmp =~ s/(\.[^.]*)?$/.t00/; + # save the original Ghostscript result + if($opt{debug}) { + L2hos->Copy($in,$tmp); + &increment_name($tmp); + } + my ($cmd,$type,$width,$height,$just); + + my $must_align = 0; + #$EXTRA_CROP = "a$EXTRA_CROP" # hack to ensure first all-over cropping + # unless($EXTRA_CROP =~ /^a/i); + + # RRM: Remove justification bars + $EXTRA_CROP =~ s/h/bt/gi; # crop horizontally + $EXTRA_CROP =~ s/v/rl/gi; # crop vertically + while ($EXTRA_CROP =~ /([atblrs])/gi) { + my $edge = $1; + my $croparg = ''; + if($edge =~ /b/i) { + $croparg = '-bot -sides '; + } elsif($edge =~ /[tlr]/i) { + $croparg = "-$edge -sides "; + } elsif($edge =~ /s/i) { + #RRM: shave at most 1-2 rows of white from the bottom + if($cmd) { + # Terminate command pipe + &do_cmd($in,$tmp,$cmd) || return 0; # failure + $cmd = ''; + } + my ($type,$width,$height) = get_image_geometry($in); + next unless($type); # skip if no geometry + if(&do_cmd_norename("$PNMCROP -bot -sides < $in",$tmp)) { + my ($type,$width,$height2) = get_image_geometry($tmp); + if($type && ($height - $height2) < 3 ) { + # command succeeded and shaved less than 3 rows + if($opt{debug}) { + L2hos->Copy($tmp,$in); + &increment_name($tmp); + } else { + L2hos->Rename($tmp,$in); + } + next; + } + } + # MRO: this shouldn't be necessary: L2hos->Unlink($tmp); + next; # go to next crop argument + } # end switch on crop codes + if($cmd) { + # Continue command pipe + $cmd .= "| $PNMCROP $croparg"; + } else { + # start new pipe + $cmd = "$PNMCROP $croparg< $in "; + } + } # end cropping + + + if($opt{flip}) { + unless($cmd) { + $cmd = "$PNMFLIP -$opt{flip} < $in"; + } else { + $cmd .= "| $PNMFLIP -$opt{flip} "; + } + } + + if($RIGHT_JUSTIFY || $TOP_JUSTIFY || $CENTER || $SHORE_UP) { + if($cmd) { + # empty command pipe, we need the image's geometry + &do_cmd($in,$tmp,$cmd); + $cmd=''; + } + + # Get bitmap type and dimensions + ($type,$width,$height) = &get_image_geometry($in); + return 0 unless($type); + + my ($white_left,$white_right,$white_top,$white_bottom) = (0,0,0,0); + + if($RIGHT_JUSTIFY || $CENTER) { + if($RIGHT_JUSTIFY) { + $white_left = int($RIGHT_JUSTIFY-$width); + } else { # CENTER + $white_left = int(($CENTER-$width) / 2); + } + $white_left = 0 unless($white_left > 0); + + $width += $white_left; + } + + if($TOP_JUSTIFY) { + if($TOP_JUSTIFY =~ /^x([0-9.]+)/io) { + $white_bottom = $1 * $height; + } else { + $white_bottom = $TOP_JUSTIFY - $height; + } + if($white_bottom > 0) { + $white_bottom = int($white_bottom + 0.99); # round up + $height += $white_bottom; + } else { + $white_bottom = 0; + } + } + + if($SHORE_UP =~ /(\d+)(d?)/ && $1) { + # RRM: make height and width an exact multiple of $SHORE_UP + my ($shoreup,$depth) = ($1,$2); + my $extra = $height % $shoreup; + if($depth) { # image needs depth, place half the extra space underneath + my $bextra = int($extra/2); + $white_bottom += $bextra; + $white_top += $extra - $bextra; + } else { + $white_top += $extra; + } + + $extra = $width % $shoreup; + my $rextra = int($extra/2); + $white_right += $rextra; + $white_left += $extra - $rextra; + $cmd = ''; + } + + + if($white_left) { + if($cmd) { + &do_cmd($in,$tmp,$cmd) || return 0; + } + # Start new command pipe + $cmd = "$PBMMAKE -white $white_left 1 | $PNMCAT -white -lr - $in "; + } + + if($white_right) { + if($cmd) { + &do_cmd($in,$tmp,$cmd) || return 0; + } + # Start new command pipe + $cmd = "$PBMMAKE -white $white_right 1 | $PNMCAT -white -lr $in - "; + } + + if($white_top) { + if($cmd) { + &do_cmd($in,$tmp,$cmd) || return 0; + } + # Start new command pipe + $cmd = "$PBMMAKE -white 1 $white_top | $PNMCAT -white -tb - $in "; + } + + if($white_bottom) { + if($cmd) { + &do_cmd($in,$tmp,$cmd) || return 0; + } + # Start new command pipe + $cmd = "$PBMMAKE -white 1 $white_bottom | $PNMCAT -white -tb $in - "; + } + } # endif must_align + + my $pnmtoimg; + if($opt{type} eq 'png') { + $pnmtoimg = $PNMTOPNG; + if($INTERLACE) { + $pnmtoimg .= ' -interlace'; + } + if($TRANSPARENT) { + $pnmtoimg .= ' -trans ' . L2hos->quote($trans_color); + } + } + unless($pnmtoimg) { + print qq($prompt: Error: unknown image type "$opt{type}".\n); + exit 2; + } + + unless($type) { + ($type,$width,$height) = &get_image_geometry($in); + return 0 unless($type); + } + # run ppmquant only on color/gray images + if(!$type || $type =~ /(ppm|pgm)/i) { + if($cmd) { + $cmd .= "| $reduce_color " + } else { + $cmd = "$reduce_color < $in "; + } + } + + if($cmd) { + $cmd .= "| $pnmtoimg " + } else { + $cmd = "$pnmtoimg < $in "; + } + &do_cmd_norename($cmd,$out) || return 0; + print qq{$prompt: Written $out\n} unless($opt{quiet}); + + 1; +} + +sub banner { + print "$prompt V$RELEASE (Revision $VERSION, Perl $])\n"; +} + +sub print_version { + my $formats = join(',',@IMAGE_TYPES); + print <<"EOM"; +$prompt (Revision $VERSION, perl $]), +part of LaTeX2HTML Release V$RELEASE. + +Supported output image format(s): $formats +EOM + 1; +} + +sub print_help { + L2hos->perldoc($SCRIPT); + 1; +} + +sub print_usage { + my $start = 0; + my $usage = 'Usage: '; + my $indent = ''; + + print (@_, "\n") if @_; + + my $perldoc = '/usr/bin'.$dd."perldoc"; + my $script = $SCRIPT || $0; + open(PIPE, "$perldoc -t $script |") + || die "Fatal: can't open pipe: $!"; + while (<PIPE>) + { + if (/^\s*$/) { + next; + } elsif (/^SYNOPSIS/) { + $start = 1; + } elsif (/^\w/) { + $start = 0; + } elsif ($start == 1) { + ($indent) = /^(\s*)/; + s/^$indent/$usage/; + $usage =~ s/./ /g; + $start = 2; + print $_; + } elsif ($start == 2) { + s/^$indent/$usage/; + print $_; + } + } + close PIPE; + 1; +} + +sub do_cmd { + my ($in,$tmp,$cmd) = @_; + + print qq{Running "$cmd > $tmp"\n} if($opt{debug}); + my $stat = system("$cmd > $tmp"); + if($stat) { # error + print qq{$prompt: Error: "$cmd > $tmp" failed: $!\n}; + return 0; # failure + } + elsif(!-s $tmp) { # does not exist or zero size + print qq{$prompt: Error: "$cmd > $tmp" produced empty file\n}; + L2hos->Unlink($tmp) if(-e $tmp); + return 0; # failure + } + if($opt{debug}) { + # increase the temporary filename by 1 + # this uses perl's magic autoincrement + &increment_name($_[1]); + return L2hos->Copy($tmp,$in); + } elsif(!L2hos->Rename($tmp,$in)) { + print qq{$prompt: Error: rename of "$tmp" to "$in" failed: $!\n}; + return 0; # failure + } + 1; +} + +sub do_cmd_norename { + my ($cmd,$out) = @_; + + print qq{Running "$cmd > $out"\n} if($opt{debug}); + my $stat = system("$cmd > $out"); + if($stat) { # error + print qq{$prompt: Error: "$cmd > $out" failed: $!\n}; + return 0; # failure + } + elsif(!-s $out) { # does not exist or zero size + print qq{$prompt: Error: "$cmd > $out" produced empty file\n}; + L2hos->Unlink($out) if(-e $out); + return 0; # failure + } + 1; +} + +sub do_cmd_plain { + my ($cmd) = @_; + + print qq{Running "$cmd"\n} if($opt{debug}); + my $stat = system($cmd); + if($stat) { # error + print qq{$prompt: Error: "$cmd" failed: $!\n}; + return 0; # failure + } + 1; +} + +sub get_image_geometry { + my ($pnmfile) = @_; + + my ($type,$width,$height); + my $out = `$PNMFILE $pnmfile`; + if($? || $out =~ /(P[BGP]M)[^0-9]*(\d+)\s*by\s*(\d+)/i) { + $type = $1; + $width = $2; + $height = $3; + print qq{Image "$pnmfile" is $type, ${width}x$height\n} if($opt{debug}); + } else { + print "$prompt: Error: Could not determine image size: $out\n"; + return undef; + } + ($type,$width,$height); +} + +# push the number in the suffix up one notch +sub increment_name { + $_[0] =~ s/(\d+)$/$a=$1;++$a/e; +} + +__DATA__ + +=head1 EXAMPLES + +=over 4 + +=item C<pstoimg foo.ps> + +Convert the first page of foo.ps to the default bitmap type. + +=item C<pstoimg -type png -crop a -trans -interlace foo.ps> + +Same as above, but force png output and crop all the whitespace +around the image and make the color white transparent and +generate an interlaced bitmap. + +=item C<pstoimg -multi -out bar -type gif -crop a foo.ps> + +Consider foo.ps a multiple page PostScript file and create output +files bar1.gif, bar2.gif, etc. + +=back + +=head1 ENVIRONMENT + +=over 4 + +=item DENSITY, DEPTH, DEBUG, DISCARD + +See B<-density>, B<-depth>, B<-debug>, B<-discard>, respectively. + +=item GS_LIB + +This variable is set to the path(s) where Ghostscript libraries have +been found on this system during configuration, but only if the built-in +paths are not correct. This fixes the problem of relocation that is quite +common on Win32 installations. This behavior can be overridden by +setting GS_LIB manually before starting pstoimg. + +=item LATEX2HTMLDIR + +The directory where the LaTeX2HTML library and perl modules are found. +Defaults to "/usr/share/latex2html" on this installation. + +=item OUTFILE + +Setting this has the same effect as specifying B<-out>. Please do not rely +on this feature any more, it will disappear from the next releases! + +=item PAPERSIZE + +The papersize to use by Ghostscript to render the image. pstoimg tries +hard to optimize for rendering on the smallest possible bitmap size. +Still this option is there to enable tuning by hand, although it is +deprecated. If pstoimg finds a better setting, this parameter is ignored. + +=item SCALE + +See the discussion of B<-scale>. + +=item TMP and TEMP + +Unless overridden by B<-tmp>, these variables denote a directory where +to store temporary files. TMP is considered first, then TEMP. + +=back + +=head1 SEE ALSO + +gs, pnmcrop, pnmquant, pbmmake, pnmcat, pnmfile, pnmflip, ppmtogif, +pnmtopng, giftool, giftrans. + +=head1 NOTES + +Several people have suggested to use ImageMagick's convert instead of +pstoimg. A few comments on this: convert uses (of course) Ghostscript +for conversion of PostScript to bitmap, so one still needs gs. And +for the special requirements of LaTeX2HTML convert's features are not +sufficient. The ImageMagick toolset has everything in place, but it +has some overhead that can prove killing when processing some 100 +images. pstoimg only does what it really has to, so it should be +quite efficient. Don't get me wrong - I like ImageMagick, but not in +the context of LaTeX2HTML. + +=head1 CAVEATS + +This utility is automatically configured and built to work on the +local setup. If this setup changes (e.g. some of the external commands +are moved), the script has be be reconfigured. + +Despite the portability of perl, a pstoimg configured on UNIX will +probably not work on Win32 and vice versa. + +=head1 BUGS + +This is a major enhancement release, so there may be a few bugs. As +the user inteface changed a bit, some of your tools that were using +pstoimg may not work any more. + +Please report bugs to latex2html@tug.org, stating the (debug) output +of pstoimg, your perl version and the versions of the external tools. +Best is to include the cfgcache.pm file from the configuration procedure. + +=head1 AUTHOR + +Marek Rouchal E<lt>marek@saftsack.fs.uni-bayreuth.deE<gt> + +=head1 HISTORY + +This script went through a long evolution, beginning with a modification +of Doug Crabill's E<lt>dgc@cs.purdue.eduE<gt> ps2epsi script. +The first perl version was done by Nikos Drakos <nikos@cbl.leeds.ac.uk>. +It was gradually improved by numerous LaTeX2HTML developers: +Ross Moore <ross@mpce.mq.edu.au>, Jens Lippmann +<lippmann@rbg.informatik.tu-darmstadt.de> and others (sorry for not +mentioning everyone and thanks for your contributions). + +=cut + diff -Naur wfdb-10.2.5/doc/wug-src/wave/ppm/GTKWave.ppm.gz wfdb-10.2.6/doc/wug-src/wave/ppm/GTKWave.ppm.gz --- wfdb-10.2.5/doc/wug-src/wave/ppm/GTKWave.ppm.gz Wed Dec 31 19:00:00 1969 +++ wfdb-10.2.6/doc/wug-src/wave/ppm/GTKWave.ppm.gz Tue Jun 18 08:57:38 2002 @@ -0,0 +1,112 @@ +‹B.=�GTKwave.ppm�íýiŨ-[V˜ūÖm˒%#DŌƒ„p�ĻE}Cæ―ŲgÚ.ÛReVÉv•ĪēģJČĻïEŸ@™IßHB]ŠĸŌÍæ6Đoû‹ŋĸ#jįsãÆŦ‰đšđÖ\+ž9žqÆ~ãsƊîŲņîØį;ūņ3ūø ŋïMßþ{žĸ“oú–7<ĸž?õ†?ø‡ĸøw|ųŸ{Ãwü‰?þ†?ðÞ?óįĸԟ}Ã[þԟýsïýßþŨ7|íWÍg|íŨ|ÝŨŋákŋæ›ŋņ3ūîūá3ūáú^����������������������������������������������������������������������������€éy ‚ ‚ bØČðĸOýō§ōxá/üĨŋô‰"þō99‰ŋâåÅ"þę‹Ĩ.-‡ŋįŊŨæoxøk…üÍ +üõ=Ŧ6[ÄßHâïxy)Ÿŋûiþf]þ^2+ÎßŊÍw{øۅ|OþΞïUāûÎųŧI|ŋ——óųOóũęōƒ9üýïWā‡<|w ?\ï9ð#ĩųĀ9ߛďzyĨˆ{åûęōã9|œÖæC~ „ŨáũüDm~RÄû“øĐGü‘7ūgą/ūôbķĸßM>ƒũ}įûîĘýŸü§øO~…‡ĸôWüĻ‡ĸLÆþi~…„ĸ"ÆķįWĘø/ņŸGøŒsþ‹•ĸJĖŊ:ō+ՏyøŊÅüęû/…üš Ÿąįŋók_įŋŠóëÎųUwþ[1ŸéáŋþĖũðëÅ|֏ĸj ŸãŨėų b>įuþ›Ÿ+âŨÞųb>ÏÃŊûžzø|ŋéÓü·ū ÆgîyƒŒ/|_į‹ÎųŽ•/–ņ%>ûK>äáKÅ|Ų‡~ƒ/ō9{ūBĖWūÎįÆųÍįüÆ;ŋEĖWyøžŊú°‡ß*æŦ?üų~[ŒßīįkÄ|íë|A„Ŋņ†;OÄ|―‡/üúŸ8ō būņÓ|‘„ßä‹|“Œo~/‰ó-į|éĘïņ;=|ŲïüIß*æÛ~ō˅üŪ _ąįw‹ų=Ŋó•q~ï9ŋųÎïóû=ü–ßĸSū]Æø4_%áÆø­ð§>ë‹ßļ:ķYþÂ_ü …þũyɟöþĸWþę‹”ûWŠ•[nÝĘ]jÝŋZlÝaåÎīî_+ķnĄr—Yw#åŽZ·ŪrËŽûŨ&Ywuåþü~Ę-·nrĸú$åÖ°î/[wXđ3­ŧšr—Yw#åŽZ·ŪrËŽ[Eđ­ŧPđÖ-Tnđu ”ûK’”[ÚŋMlÝaåÎīîęĘ-·îęĘýíbåŽZũoÝó‡ÄüáŨųę8äœßvį>ãģŋô™ĸWJ|âŸh–RîĸwäŸüYýĸŊþõsntWWnųîęĘ=ŲîÏęwĢûslÝčnĪÜQëÖUîÉntWWnđu ”ŧĸîŊîwĢûkkÞč~Cąu7RnųîęĘ-ŋŅÝQđå7šŦ+·ÜšĘ=ӍîdëŪŪÜ;ë>áyøš?öÓþļ˜?ņÓ_ëã7|ųëþ/ü@Î]Ë[ĶtđĸĸŨþ招ZŊýėeûõ)Ŋ öģ)ŋæ8eoÝÏĶ8š―MũŽƒ+ÛÏĶWŋŅVnoc―>[ēVÏŧŅ―æJŽûŲœŧŨ!ÁöüvĶϖ qĢûšŸ-‘[ũ5?[2čîŸ-ÉīîoķuĢ›Ï– vĢŧšrË­[ Ü_ĪÜÖý'‚Ö}äOÆøš=ß!㍏xæsūō‘ĸBëœÍRšÜĸĸëëÅĢoïîrŧūŸē*ũ:e/Øî”ÕšŸMß―ˆßå>Ņoߍî5%óģ%Ÿ}Tîí-@—Ï–øm\ĶÜkî*ÕûŨ.ëoWĐÞŋvyöÛ/øāáýŅ^đ·‰ĩM?Uî5+áFũ5?[2č-ÉšŅ]GđåÖ}Íϖ qĢŧãgKŒÝčæģ%ÆotŦ+ũwH•ûÓžéœŊŋóœ˜į=|Ãó?ãá͏øÜßüĶéý?ãþĸßø;/mÖíúvhĘÁ·]ë~6egÚû)ÏĪúėģ%GũXũš’ýŲWđŸMéqĢ{oŨ%7šâýXđ_ėĮŊ]åþôŊūču“ß&Þc5ęíõ~ĒgzŠrŊ)WđŅÍC”<DÉC”SÞčūægK†ļŅ]]đĢÖýuÅ7šë(·Üšs•;Æ[~æ%ž5Æoßóķ~ãWÕņĸT‡Rî/ķßnqŸē~ėŋŪĸgÜĸĸ›ïĨrïÝþŨ>Uēýx°nŨ߉ôį†ïl;7š—ĮqPîýŊö·ē#3”;4e á]îŨ§ïntŊSŽÖýEĮĩpïrŊÓ]Ŋ^ÂĘýú ŊYũaújÝĮ‰M{ōėWŊIõúãþÅĢé_þú‹•ýëޗ^ûÐÏ6åîÛë Ēäģ%ÃÜčæ!J>[2čîŽŸ-âF·@đĩnt§(wđuĸöDë~ÆÛ_į›âžãœo^y§Œw=ãóūšĸo){ųßĸØũþĸßúû/…nw/Ŋ)ũýÅĢO•|ÞÝ–ė_ï­ûŨížz‰ÎÄđđ―em,Ųîr?û1úú3_SkũFwčÝÏæyüã:e}ˆrýņāØû·8˜ööbŧÅ}˜ĸpŧû0}Ģ{û•ũĩŦŲûŨŦlŊSö‚}ðíŨMûĩÝÏ~|ėØÛüÛëM­·―Ó]ĩÞOũž~Í·ƒÆC”<D9ügKxˆr‚ÝŨül‰üFũԟ-1uĢ;ŲšĘýMIĘ―ģî=ßōŪŸ=ōn1ĸݧųþ{?ŸĸÛšųĸÞųōßýþĸßþž—B·ŧ—Õ·ŨūO’ė|ýõkŸ-Y§x?Xēø"rĢÛõmĸëlŧ/Yĸ8··ąýgHöS<Ŋwwđũîý9Žx۝PîÏ}|ëûŲëĮĘí}―Ýč~öcDžËöþõáFũģ‰ŊzõþõþĮg/^“ęõĮļr?›Įyý›^ûņš7šyˆ’Ï– zĢûšŸ-™ë!ĘúŸ-ņYw#å–ßčŪŪÜōÝՕ;ŅšK”{åwîųÄüß^į[#ü"ūíüŲ/øÚjþïÎyęĸû7Ą*]îĸĸï{)þŲ’ÐįšŸ―ޙö6åčÛÛkɇšŋėxĢ;âÞû8Üë>(ũņOt?›gũ‰îuŠ{Į{ Ũ·ũ/Y§ŸÞå^?[ōlĘcýv?[ōlšcÝîkŊrûtdûóũē――~MŠ·Õ?LŲ”ûŲŊ―Øûðã^­ŧŸļYũģųlɈ7šyˆ’Ï– zĢ›‡(õ?[’iÝo·uĢŧ‘rG­[WđeÖým+ĸ“ŒĸŲÃïúŸÎßó§îwïxÓį–Ųý?ãþĸßýþ—Q.ÎĮđ·Ũ‹óAn7öQ>šūŅzˆríøcطݏ—ė<üĘûqîužÐ-nũ.·gúãÚëtϏŽlï§x•ÛkڞŨ_ûáƒuï_ŋþãcëv_ŋasïŨÄ{sėm›î­ûŲ”Ũ”{ýņŪŲۋUđŸýč8ö~úģŨŊJõúzsėÏ<Dy­ÝŨülÉ7šyˆ’Ï– zĢŧøģ%ĶntK•ÛgÝu•;Æĸ=ČïŲó1ï}ßëã ŋū§ĸ·ųüOÆýĸŋĸƒ/{­{YÅûąW/ūxoQŪSÜu§;7šCQŪģyÝûŅŊ$ūýøFwčãÜë<!ŲvÜ>XēNß;öŅ―Ģēýč^ũ““{ÝÏĶýŅšŨŨŦi{^ûLÛ+Þ^ŲÞŋx6ýąloWŲ^žëôöbåðãqúŦÖ―ū^{ĸúõđŅÍgK†ŧŅÍC”<D9øC”ÜčŪŪÜĨÖý§ÅÖVn=ë~ÆĸCÄïŧóĸóg<üþ?óóGþ—g|Ņ7zü?dČuýĸāü‡ûÞĸĸîzŲ}ˆrĩ,ĸýmįã%‘ÛÝ!ëÞ&ÆĒÜTó‘xï|{yU­·ûŨËŦj―8ˆrĮ#Ûî­ïĮū―iöŪ`û§?þ É:ņ‘f;7šŸMß―>(ũAģ·ŨĮ)ßüz•―]Ŋ?šÓWĩÞŋ>(ũúŦŧQo/V<Óß^œX•ûŲëoýÉíßõQNxĢûšŸ-á!Ę nt_ã!ĘĢrË­{ęϖ˜šŅdÝ*Ę―ģîþŨOóíþ·`ÏĸËÏS5ĸOJiųýŸũĸŋįG^ŽÂÄýl‰įS܁ϖxïr{ĩ|‰ÞčÞ^ė?Ņ―ÏÝĒûŲ”Įš―ė <üå:ÃAđŸM|Žßk>[ōútßÍíåĩûÛî]î=ÏĶ‡M{?}}}Ðė ;ūýš`;ē―ė4{ĸãâ‹ÍŪÝ)ĮéaåÞæđõö"øúš7šŊųŲĒä!ĘA?[2ŨC”―Ņ]]đåÖ]]đĸąrG­[ĒÜþßŊóãüŲsþН?'åKūĨÎįôRšÜĸĸÞžĖC”<D9ân>[2؍nĒä!JĒœōFũ5?[bōFwDđOŽ[ĻÜ)Öý‡þü‘?üįÁÃĸGĖĸþ DČĸņˆ/ýÏOïĸũĸŋïĮ^á!JĒœĸģ%CÜčæ!J>[2čnĒäģ%ƒÞčŪŪÜ]otŧĘ]jÝĸŧØšĸtÏûdüņĮ"üĸNøēo}ÝĸWë–D˔.ũĸŋĸƒŊpĢ›‡(‡đŅÍC”<DÉC”SÞčūægK†ļŅÝņģ%Y7šë(·ÜšŦ+·üFwuå~ŸXđÖ}įßų būÓßøÎ_ôðeüŸŸæOþŸŋøåŋë™ĸßĩÜûæP4KĐâĸIÜýĸ>ô +QNuĢûšŸ-á!Ę ntó%Ÿ-ôFũ5?["·nrkÝčNQîrëþĢÅ7šë(·ÜšŦ+ũ_|ĶÜį|WŒïØó—ÄüåŨyãŽŊøÝÏüß,UüĸŪôIü‘ïxÏgūá;ÎųÂs~}_äåE|ņ?Ŧ._’ÃgGøRūĖÃo(áËëð9{ūĒ6_yÎįĶō›]ÞTÄoyÓoŽËWåðyq~kmūÚÃįōÛ*ð›ö|MmūVÄ$ņu^žËįɧyC]ū>™/Œó ĩųF_TČoŊĀïų&ūųœ/Iâ[ž<_ÄïxþKëō;søēߊĀ·yøō~WūâĀïŪÍï9į+“ø―^ÞėeulkÔõÉįĸ ‚ ‚ ‚čåþŋĸŧÆýĮÛíĸ�����ƒāĸ�����Ũĸ����ļø?����ĀuĀĸ����Ūþ����pð����€ë`Áĸžx_+ŊxĢBŠŧ’ĩH…ýĮæ8ģ]æ€íâøPũNaóÁžÆþßý6ö―ŊkŽÝ“Џ6„ýø„:TšÓšzŦų&C{7cĸŅŌøI[ļî+r8ūjqðųS―ŋÏpĄ–flkû +-iïĸgý4ō›H:”ž/(,Ýr ėoH%tIj°­ŧėN‘õmųMËĘŨņ0o°,ė�mYrŸã”~ðųS―oėĸån3Įf‚,øä†váÉDxĸ_~wŦÁu$ōŦHŸå·}B‹―9§t·ŠwķČĀnÝķOw€.Ī�!ņM9Ž2vïlĄ]ąņúÎaþ‘­vš][§û{…wvŽ/ [žˆĸß_Ŋ„æ_åÎS‹Tr_Û90Ą#fý_bã‚ĩ;ũĸĪę―ü?éÐ./}8Kxg ―#8ØČFIÚ.`Ó­RDũuÞÎs ėŠŨ·å^Ú –äĪÝýĖi|ļš•6u|Ųčy„üUúåÕØë―ûaMã-@đĸūu  +f?ĸ_kG ŽäŽ–ōzWÞŅĸC󜎡Pāņĸ9nááï]ōМH–Ķ―ū“Éĸ-åĪ-|ݗ+ž°s|ŲŲîĐl7ų76ĸß{~äĩ;-ðĻ‚åûĸ!N\Ásĸ\āÜ•7Įų…CÏĸãŨŽø +6ÉĸC-qâē‰|ŧv‰Č†Žė<}ý?ēüÉÞĖ$FÎá z°p|ŲčylŋÝęß|Þ}Sp“―/Ļļ}å›Æø! ąėĸ•VðÜĸ#‰—ōĸӉĐþ/Вš]ŠŽ,(!w&ßOĖúd}[ūKÕŪ5‡l4Ø"vwĀŧ_ÜĨ‰|þgyîüø? Áþ_nķ팒Ÿë"ËLmõīDGĸ—Œ[ꛂĪũĩVT‘\ýåû‰|į %öZß9Þ”Ëƃï&sųŲēûȜ–čĻÁ―ŽŊ Ė%îĸÛDïüÚþï~ä2ŠĸCģþ{mŨ-ßKãþ)ÔÅĸ|ŦÝŊEü KÝ·Â3|žįĪKF|ŧÔÚ%  ōýä0ŅÝóCđ\āŠ“íĸ7ßYŦ―ĸ_ŽŊŠŋĸ'äüÞyęÚÜûßÆ7Ӌcáĸĸ…Ņá��3qðöý‡ĸf8|FĻAŦ˜<d€ĸC9œy���n=þ/āo ü��� íý ü����ā:āĸ�����Ũĸ����ļø?����ĀuĀĸ����Ūþ����pôüĸýïĸ0�����Ąĸ?AAa ķĸœâAŲĸ—ŽøŅŋîéÓ§yđũ(Ï―7ÐūhƒÜýz™m84øfNM”ė]íî{ÐeqŲEŨZėŠ‰û\˧Ó!N‰Đ‰Ķv§6#_eíýß[ÝÔ.ą†Ō(•äķ,ZeWÔhXõ€=$Þvĸ9þïÍĩ|Á*Éâb‡ĸ—ÍÎÅĸĩëFmîĩŠZ>qJLM4ĩ;áĸzuSņĸōšø?þŊQīAî;üŋĪhv.þŊ]7’hs—ĻUÔōétˆSbjĒĐÝ ĸŨŦ›šˆĸ—ŨÅĸņĒ r‡ļØáĸ%Eģsņíš‘D›ŧD­Ē–O§CœSMíNøŋ^ÝÔDüŋž.þŊíĸ%+Û+—†ĩsiX;—†ĩsiØr. kįŌ°v. kįŽÞ0þŊ‘KÃÚđ4ŽKÃÚđ4l9—†ĩsiX;—†ĩsGoĸŨČĨaí\ÖÎĨaí\ķœKÃÚđ4ŽKÃÚđĢ7ŒĸkäŌ°v. kįŌ°v. [ÎĨaí\ÖÎĨaíÜŅķïĸ<ĸŦ”;ÄÃn<ĸ[R4;—įĩëFmîĩŠZ>qJLM4ĩ;ņüŊ^ÝÔDžĸ-ŊŦŅ0ÏĸîĸWĘâb‡ĸ—ÍÎÅĸĩëFmîĩŠZ>qJLM4ĩ;áĸzuSņĸōšø?þŊQīAî;üŋĪhv.þŊ]7’hs—ĻUÔōétˆSbjĒĐÝ ĸŨŦ›šˆĸ—ŨÅĸņĒ r‡ļØáĸ%Eģsņíš‘D›ŧD­Ē–O§CœSMíNøŋ^ÝÔDüŋž.þÏóŋFŠ–äŌ°v. kįŌ°vîp —äŌ°v. kįŌ°vîč ãĸđ4ŽKÃÚđ4ŽKÖsiX;—†ĩsiX;wô†ņ\ÖÎĨaí\ÖÎĨaËđ4ŽKÃÚđ4Ž;zÃøŋF. kįŌ°v. kįŌ°å\ÖÎĨaí\ÖÎ―aûþÏóŋJđC<ėÆóŋ%EģsyþWŧn$Ņæ.QŦĻåÓé§ÄÔDSŧÏĸęÕMMäųßōš óüï>ðĨÜ!.vøIŅė\ü_ŧn$Ņæ.QŦĻåÓé§ÄÔDSŧþŊW75ĸ/Ŋ‹ĸãĸEäqąÃĸKŠfįâĸÚu#‰6w‰ZE-ŸN‡8%Ķ&šÚð―šĐ‰øy]ü_îĸOģbU‘ŽŅ―Ĩb―†hē$lŪ`ßŪZV78þ[Š–ŨÎroŲajĨÚ4sÓWIŒŌ§R˜]}íÆzųÞũ=‹ý\ÖÎĨaí\ÖÎĨaËđ4ŽKÃÚđ4Ž;zÃøŋF. kįŌ°v. kįŌ°å\ÖÎĨaí\ÖÎ―aü_#—†ĩsiX;—†ĩsiØr. kįŌ°v. kįŽÞ0þŊ‘KÃÚđ4ŽKÃÚđ4l9—†ĩsiX;—†ĩsGoØūĸóý?JđC|ŲßĸSR4;—ïĸŅŪIīđKÔ*jųt:Ä)15ŅÔîÄũĸčÕMMäûĘëj4<ëũĸä5Œĸ+åqąÃĸKŠfįâĸÚu#‰6w‰ZE-ŸN‡8%Ķ&šÚð―šĐ‰øy]üĸŨ(Ú wˆ‹þ_R4;ĸŨŪIīđKÔ*jųt:Ä)15ŅÔî„ĸëÕMMÄĸËëâĸøŋFŅđC\ėðĸ’ĒŲđøŋvÝHĒÍ]ĒVQ˧Ó!N‰Đ‰Ķv'ü_Ŋnj"þ_^ĸįų_#EKriX;—†ĩsiX;wļ†KriX;—†ĩsiX;wô†ņ\ÖÎĨaí\ÖÎĨaËđ4ŽKÃÚđ4Ž;zÃøŋF. kįŌ°v. kįŌ°å\ÖÎĨaí\ÖÎ―áQüŸ―ūö.ï>q%2%ĐnNÚø{…ý\ÖÎĨaí\ķœKÃÚđ4ŽKÃÚđĢ7lßĸŨG…þïN?ä&Å:V–X+Éâa7žĸ-)šËóŋÚu#‰6w‰ZE-ŸN‡8%Ķ&šÚxþWŊnj"Ïĸ–ŨÕh˜įũąųĸĶýø•Ü!.vøIŅė\ü_ŧn$Ņæ.QŦĻåÓé§ÄÔDSŧþŊW75ĸ/Ŋ‹ĸ·žĸïþëþ/Œ!.vøIŅė\ü_ŧn$Ņæ.QŦĻåÓé§ÄÔDSŧþŊW75ĸ/Ŋ‹ĸãĸĄÄ’Ē r‡ļØáĸ%Eģsņíš‘D›ŧD­Ē–O§CœSMíNøŋ^ÝÔDüŋž.þoęų_wzđĸ·Lė•KÃÚđ4ŽKÃÚđÃ5\’KÃÚđ4ŽKÃÚđĢ7ŒĸĮë6Nė•KÃÚđ4ŽKÃÚđÃ5\’KÃÚđ4ŽKÃÚđĢ7ŒĸĮë6Nė•KÃÚđ4ŽKÃÚđÃ5\’KÃÚđ4ŽKÃÚđĢ7ÜŌĸŸÄ}Á‡ŨÛûŊlŋÚĸčBAA—Š^þŸũ†ĨïĢˆ‹íÖJr‡x؍įKŠfįōüŊvÝHĒÍ]ĒVQ˧Ó!N‰Đ‰Ķv'žĸÕŦ›šČóŋåu5æųß}āĸJđC\ėðĸ’ĒŲđøŋvÝHĒÍ]ĒVQ˧Ó!N‰Đ‰Ķv'ü_Ŋnj"þ_^ĸĮĸ5Š6Čâb‡ĸ—ÍÎÅĸĩëFmîĩŠZ>qJLM4ĩ;áĸzuSņĸōšø?þŊQīAî;üŋĪhv.þŊ]7’hs—ĻUÔōétˆSbjĒĐÝ ĸŨŦ›šˆĸ—ŨÅĸÛ|ĸÏXđ4ŽKÃÚđ4ŽKÖsiX;—†ĩsiX;wô†ņ\ÖÎĨaí\ÖÎĨaËđ4ŽKÃÚđ4Ž;zÃøŋF. kįŌ°v. kįŌ°å\ÖÎĨaí\ÖÎ―aü_#—†ĩsiX;—†ĩsiØr. kįŌ°v. kįŽÞ°}ĸįų_ĨÜ!vãųߒĒŲđ<ĸŦ]7’hs—ĻUÔōétˆSbjĒĐ݉įõęĶ&ōüoy]†yþwøŋRî;üŋĪhv.þŊ]7’hs—ĻUÔōétˆSbjĒĐÝ ĸŨŦ›šˆĸ—ŨÅĸņĒ r‡ļØáĸ%Eģsņíš‘D›ŧD­Ē–O§CœSMíNøŋ^ÝÔDüŋž.þĸkm;ÄÅĸ/)š{)ĸŋŸ™Ø%Tũđ–O§CœSMíNøŋ^ÝÔDüŋž.þÏóŋFŠ–äŌ°v. kįf'ZóģđÃ5\’;MÒ ŊІÍæŌ°v. kįâĸ r‡hxŋA†hļ{Ņ’\ÖÎÅĸĩs‡kļ$wš†ņĸZđ4ŽKÃÚđøƒÜ!Æĸ[æŌ°v.þŊ;\Ã%đÓ4ŒĸŨĘĨaí\ÖÎÅĸäŅ0þß27’xzdXkØf.þŊ;\Ã%đÓ4ŒĸŨĘĨaíÜÆE·Cc”†Ës‡óžĸUĘÂĸŊðüŊAĸįų_íš‘DSlV/jųt:åóŋũÝÛΆįõęĶ&ōüŊMĸįųß}āĸJđûë‚Ų†§ũSWį-Ūãĸëø›Ú%ðš’Āĸ+ÖõþŊW75ĸĮĸņĸÓ\ËŽ’\üŋeîWį-ðíš‘Äéý?õR0™*åq†ÁĸõęĶ&âĸÛĄaŠáYýĸiVŽ*Ō1š7 ›ųXŽY ›[Ąï°·ŽnpüįÞį·\Œ)GÞÔÞf„Ŋsú*‰QúTŠÍĸ{7r ííŌËĸóÞ°ļïYėįŅðũĸM-É %šš;Ũ―hIn^ĒÁûĸfsk5{ĸŋ{Ņ’\Î0Úđ4ŽÛļĻÍûĸŠđøƒÜ!žÞĸC{œĐ†đ:ŨĘÅĸĩsŦ•ėðu›%öĘå Ģ+OtÜxÃFrņí\üŋAŪý†Ũ­1ąĸV°JŅ’\ŪÎÚđøŋv.þo9—3Œv.þŊ‹ĸkįâĸ rí7<·ĸoë…ĸOžWIœĖĸUŋėĸ·œëMŒÜĐRī$wŽöþ?DQüßūĸóý?đũ­QåûŊīsóūĸgŋŊ?ÛôūĸGŧn$1ûûīeozĸŸïûįųęESs/ōý?Æ/:k\üûögKS Ïúý?y ãĸđûĸaG3~*ÆĸÝ\ü?#7þ7/I݌ĒđøŋRîÜþXûþŸÔp•šĐ‰øĸ‚ĸãĸgđø­ĒđåþïN1ufÃĸÝ\ü?#7þ7/I݌ĒđøŋRîÄþïþa ĸ/OÄĸüĸ?ËÅĸkÍČÅĸKŠfį^ĘĸÁ=óęu#‰įũo^‘5ÂĸCĸŨŠŠŒöūąÅĸËņĸe:ĸO=ŌíûdeÍæÚoxÖį―{™åSąMĸïUī$wĸÏČ=}Ï[Ĩîôþß―hInČĸ—t+(Ŋ[1ŅûyNË /ūÜxÃFrņĸėÜm—Kúã/þŊ‘kŋáKųĸaš†'ļ:ÛÉ―ŽĸKÞóVЋĸ[Νō zckķá%0æ–.ÉõΖÞb&ĸ?ėrō“?þŊ‘kŋaüŋnÝžÄŅŊÎĶrņĸ}āĸ…đsėĸCŸažŧ +þß Q˜ŧ_Ó*WXü?/Ũû72I"þŊ‘kŋá)ý?ē‹Yöĸåėm§aËđŨôá>_Ĩnņ“| ÝĐcî”þšnģá5.âĸûwg‡wj6>Ä4þŸtĸg8ĸįų_Ü‡ŸĸŅĸŨīæĸ%]ųՙįåđcųŋp‡Ŋ^W<ĸ[Ŧn(’F8Ûĸû>ĸ;Šĸ—Œ’ũ†sđNāĸKúóŋø$ðoĖįĸ§ûWߕ―ˆĸo'ÕlĢnéĸy:Z^7žˆĸWŊ+Œ’o§Ė.Z+w2ĸïØøybEĸ?L4ĨÓĄĀĸü_‹ĸŨ*š‘‹ĸ—ÍÎÍ;čö#Œĸg'ĘÏĸņķņĸÔÜėo§Žõų‡’\üß[Å üėQ:―į`J§C1‡ĸ§ÞĸÁĸSsņĸZE3r…þ/ŲđðydtŪĸäņø?þ_―Ū0Jūĸ—þŊW75ĸ_L6ŒĸĮ{ķŸkŋáZØ땛áĸKņÁ^’š:^Ô-Z’ÛŅĸsŌrýĸðĒMÝÂÄE6Â6ý ›þŸ‘ļ_›wÁhÛix‹ž}ŧžnyâ(þŸ—+ų;ŧІCaÖĸ“rņƒđÆvŊÂÆ>MÄĸŦį–ûĸ’u™Æĸ…đIóŠRĸ?Äa-ðĸZ‰ōsÖ­[%ĸ7Õp(&ðĸŒũČýĸ)a#Ö#tĸbôŪˆĩõfC„ú7ū^CŋĪgkë5ô€ŧáŪ…ĩõZûąÖÕiœ6lysa ―iö1ÁfŠ7úm/ĸ/|ģ3Pî–øðp|4LŊĻ<wēûĸōáåþŋRbčfũĸ5—Ä?xÕŠ[ūÎtĸßŧ +6Ï0ÜĸÖ­’8ņýĸ’ÓNvQĨÜŅïĸįýýw8ĸũų_ïGC…đy‘t‚Ú?ˆgÖĸ%Ïĸíĸ<ĸëūÃÍÛ:[.ÏĸžæĶî󒹧QÅĸįxþ7ÔŋĐ3Ėvž·ãĸ’–ėqĸáų_IbÆ(áĸ…E%đÂį‡óĸŒ›áË°þïŪĶpÅņĸ}ÔõĸĨėӉKíÅ4þ)Šĸ§&âĸÕë +ĢÍ·ÓÄCÃĸ3gü_Ŋnjâ•ýĸp"Âĸ›Ýĸŋ‚ĸĮïIŠæþvŪÎËþú ü?5ņtõ“öaü_>3þ_Ĩn$ð―šĐ‰ĐĢ”ô†ž3*þŋT―ĸƒĸ·ũĸČųĸOÍ=õĸÔÝÉÎÕyđ†ĸ‡æ þ_Ũĸ—z*‚ĸŊoÞÎfDĸOú+yhfü_’ˆĸ/ģûŋ;įpþïöl9ũtwēðQĖ}ý?é]ŌčþxQ·hInGĸO˜ŧ,Q8þÕë–$f°ĶüßےvÝš‰cųŋûšbŅ’\=ĸÏĻ[+1ī‡ÛážÜÔÖūĸï_Xay”üýĸŨËÝV ĸ/É―ˆĸxu>DĻmü_/ĸÏĻ[11ïc·åu3‡;Ã$ÝaNš?^·b"þŋlöþŋ”)þĸo!ņĸÅĀĐØūĸ ß%åĸđ:ŨJÄĸóę–$ŽëĸōūnÝš‰ø­ÜrĸOJ‰Ô­˜s##œ—›:Čøŋj.þo0W~°w?ãĸŲqåŦó!"=Wđē§þšUR·$q™Åĸ…mŲÆ:ÃäíøŋFâ!ĸŊRīJnáýŸáüŋŨóŋÛ^!|1é`Or'y$ųŋÍįŨ~ķņ‰?ĸ›íĸŲčęWgSOįm!9čôüŸįC)Âŋ0F3rË—ĸýüïˆþoę áė]ÂMėøüïvJY*t%đņDá(•h|Þ‡žHUâýf2åĸņí‚ĸ'EĸOý {Gĸ?ĻõýĸiîÓIËėWį-ŪāĸŲ:ZXũ4ĸŊ[W>sÅo§á ã ü_ĐŪ<ņôÚzČÅĸkæâĸû°ïĸîĨþĄ057øŋžhIn•DƒWį-NšŒ†åîtAĸß7 áĸ…đ…‰‹mĸũžm +ßÃâĸÞĀĸ•ę +ũû–ŒRáUĸÏČ­îĸKøäĸ‡ĸŊXTž‹ĸW,š‹ĸëÕu…ûü>KĸũFȈðĸėš‘Ðð7ĸ%6öĸÔ%āĸ‹ō߇óĸŒ•­’+ß+ōüߛ(ÏõFÆûSþŋõvš“”_aøŋûšbŅ’ÜŽþ/šŊ8Q>þu빉ĸEđNėUüßI›šņOÚĐĸw_W,Z’ŦįĸIđuCcna„—ðÞʝØĸũŊMų$ðĸÃID1đÞk‡Iöm|ü?/·ĨĸKŠDrËĮš:ĸÏŪë&âĸŠuã3(ųjJĻnvĒũ<_―hI.þ_ąŪ0ĸ_|‡†ĸ— Tųß'ðĸm–\7ņĸxQ;þŸĪøvÝōÄė7ݒŋšĸËßóVŅ‰Ž;ü_ž[ž8–ĸ§ŽþŸ‘(žÏ°åÖú–|9ø<&ðášî#~ĒPōĸÓ%GfČÞ“róęâĸnQų‰ĸ_ðĸēš‡Dü_ŧn|‰ĸį]°ðĸxõŠþŸī„‹ûĸ">ãĸ‹FrŨSþïýĢˆĄÄČËý_ō8FvŅŽþoęųßÐÛšČóŋuÏN·�Ų’:%šz:oߕ†ĸ s/õüŊ{Q­~-^kÜĻâĸ#>ĸ›m§ĸÂhį Ģ:‡%œ^ē―đŲE―=˜}þũpŠ9ĨZWØEž}[úŋįþŊwþwŨt ĸg•Ŧļŧīþï.d\ĸOúóĒ7ŨíģĸŧESs#oKņĸŒÜëøŋũnĄķĸo§ÓÔv>ĸ?Œ�þ_^ŨÐÅīŪĸï áĸÞÄîþzįá‚þßōþO_ĸúZŽmcUIĘö6JūðČĒķŨ"ģUĐÕ,ķrō•/vûŨÅm 2åiŦÁ-Vļŋm/ž;^doTÚ +%ąï62ėO‹ŧ=MWŊûŽŨø{‹ÐęŨmŌ=`3JČį7ļÃ?uv‘ŊļĶI‹22āû“äÓûvË8ŽĢ‘| áķpįŨĻÞk=5ķ™ÃōTų9žĸ2{ĸĸķ(õ}häūŦ| ‹āmrĻąÔĒ…ïė’VÖ{_(o”ö <ÝFûŲ {sミ}kbIžauØýž>ūģũā{=ēĶnĸÝïÎí[ÚwJ”Œ|žčéĘ6ļĸũÄXXŨ―ŦãMÜĸ6~ĸį°]ÂÝáãE“ÎĖîÚÉsõöĸÃAŠtw:)ýtëĪÕ>Ãė|ؗTïĸoqŊrŪÂ+Ž0ņ°ŽUŠ–ä†FøTlÍSâōxgn?JîfŌÛ%âđōóĸĒģÛôŊVĨF‰ŲJęĘOÅōŠû\áŧĪ}Ŧ”;%ã ËÃîĶ·pÔ"ž›=ø§‘zĒXvûÃÖ°ũÝÁƒï3Þ})þcvÃyđÞķõü?ūÂ3›|W<äVđØyũ ážīÃëųĸö:ūK„Þ#Čg;þïmĶŪzGÉŧØýn|8[†šņžÃ•Î0‘SĒdþPŅšþh ō^ā47ĐhdĖ úĸin]ĸwÃ=[æų^j–ŧ™ęúŋ°“ĸ‡bbĸũÚūŦÄБd§Ą~âóxĢüM‡ä pwc7ë°ä*þXēŌ[ð·bHï―3oŊ·Q:―ˆWlXž;‡ĸ']>4ü?RÝ=Ýƒąŧĸ{ËÎ*‹ģšĄģPh‘) Ÿ.Ĕĸ‡ÎðûŲöwâgþÃl üßŧÎlĄĒÚ#|‘‹`$%Iš"cŪtĀ +7kŌÎ ŸįīŪ0öĶ'?‡ïs―"?ÕŌiïI>ī.ũĸÃđŨ=<ũ{EÞĘšĩķ‰‡BÞ ‘­ ĩÞ°ļCqHũðZ‡[1ĩá6*’=ø%E…đIÕĸĨC.H‡Ēy‘t͒œa$ë.7Ėļ$EüЈ_*úĸi“K`ݓvøÆ·ũĶį6ģgžgÔø™§°áÃ)Î=Äâ['rŠOÚŽ’†Î|~qVgņíšûwĀ#‡@jÑĒÞEčēj ąĸoUöoXÜ=Įm)ū!Üå{ŽrĀ†Z +5šZÉÏTyQn§îy2"E[î遚XrJ<L íü§[!iïÝĸCÛŨ;ĩŽï1~zā‡ĒĨ°úŒ77ēj‡)BKôÖ― ĸ'EčD᝭VQynhũÐöĸÅŲĐ•t‘rÏáîŧŸrXx‰ĸĮ/Á‘ˆß°õV å–Ô­˜ņ“< ‰Ũ=Ճ‡Įw‹\p#§ĩō-*z˜~ÚddigwâËÉáCîvd…(R4uËý Ž—w-â#pXūũĮZ7BÍD| ïÐër… éīwÝ|ïC#gžÐ@đŨŽÓØ›īŧý~{šūÅ4þšÖņŊ"L]ßH9ïdÉzĩËÕ957ōüïáÔ7UĸïōüoÝ\ïo!yē™ĸ/ŧaoāĸûnĸzïÎmsŪŅûŨĄ]x§l/RŸĸu‡+û―Cč ëõüoõDŊþ•<ĸ24oQŊ?,ÎNĩŸŲûtjÆÆÍŧ­?'Ýge?ĸŪøŪÏj0‹āÉÖý§VŋOŒļw|—;n?ņŠDöíÐĐ)~mõVIŠęþïķäķwðw!‡”’į]ĸ—WH}ãįĸ%ww:„)ĸ_ãVŨĸ#áŠî5ý_þÖ,ĢĻ<wĸ'ÖōũÜēâPÖ~JKĸw—ŋ}}ĮâÛC§ŽÔQZ#ÉĸÍx…MÓûĸ>ĘýĸTD#đ‡”Čnï&V·SĨÜ<ĸũîŌî‹ÔģSHo úRŅįÖĨ{‚*ũĸߍIâáߥý?!ĸÍ:ó/aĸ]R―oļĘũá6į#þ/fþŋÞ<âĸ‹Ęs#ƒŸņ†]XT/·ĸŧŨĶýëȅĀ:čÚėmþĸŊ5Bþï=ų{gĀĸ“r“ü?ōî/ĩŪŧXwĘ4þŋSĸßN§y2s)ĸ_Âw˜Ëý?ôæBØ°;āņ7}CûjnžĸŧŠxqúîXÞ0þþŋøŪû’ÍQXīKŪëĸUÞÆÖĘÅĸåE―§Đ}nhüßëĸĄŧ=빉Ũôĸļ—.ŊėŲ6’äN—ōĸýŲ~–ðΜQwVĸEžĸ‡$S^WŌ’wúĨüߍˆĸ{ïĪđQũԄĸ {V͍ۑäWEûæ>8_kß čiîéq§QT/WčðމÞ+ĐPé#ŸˆT 5ÜÆĸ'.Ëqĸž +ë†Îĸnļŋq„SÜ[Ąknƒ•Œ°Sbaâƒóg”øÁ^ŦîūĒ7qš>„Ũĸ―ûyÜ3Ŧ7,ðéý Wã…7B•ü?T+’›]ī‹ĸöÜ,ũ:þßå`į^Óĸ―g!ï­ioŠžnüÖP(qnĸÏ{ Œĸįå†DHŧŪ7Ū`§áŋg1‰!ĸ_Wđ―ĸũšÂöõųUuŸ˜WtÁĸs{n–‹ĸë=Í―ŽĸÎ?ûģSƖĘūfáĸÚuņĸļö+ÕõÆė4ē‡3ÂJ‰ûÓiöuĸWÍõúŋvQ7ĸöÜ,ĸŨ+zš{AĸũęPÝ?2žþߎ.þogw +pã]Ē$Wx‡ĄnQyî•ý?ûÞBvÝx"þŋųˆŠEÝ\üߍŸĸÝĮÚōÜÏĸ.ķýßüuú#,I”l…– oÃÞŅĸ{=ĸÛýęßįŦ-É­RīäûĸKęÆÃųiüŋûĸ0ēŊ>ņóŋÞęÛYÅÔ.›mS kä6S›Ēņ\đpâĸyë›ōËqÅĒ]üß`ÃøyŅŒÜ+û^āĸIđøŋRŪqĸ_ĀĸõęĘãþo°a\üÁĸĢĸW/*Ï― ĸW/š‘ņĸf†ĸ{§W)Z’[ŨĸŨþŸW4)Ũëĸ#ŒĸĮņĸĸ5ðĸHāĸՋĘsņĸōĒđø›šÞDü_Ŋn<ŪāĸE“rŊéĸ…EKrņĸHxĸĨ]4žÛāü?œĸ—ŽlanĻå9ü Ëþšn°aƒE3r#,SØĻ^Ԏĸŧ1“ĸÛĖ ðþo'Ũ{sîķėĸĄļˆĸWÉÕð7ðĸ.đņĸ^EãđÞAî{:-ÉĨáËúû\á{'ixš\üŋA.þߎn<12æ66›‹ĸËýĸéhąÞ—L$Šƒß%"#Ėākû|Ŋ 2ƒ_1Ø―'y›Ņæ,ÔËĸóÞ°ļïYšåĘoĮU,Ú%Ũ`ÃÜĸï’áĪ×ÎKäþŊ\ï6#OZ.š”{Áûĸ}sC‰ÜĸŊ•[·čÜũĸóîøüïz 8<Ž1ĸWyþE/Ũû,Ė|þoįéž5BÏĸķôĸ.Ïĸfä–Ôõ&Æũų*EKrŦčųß9üßÎæ‚Ïĸ–-ɍûü{fL5Ž‘Ëóŋ þ–‹ĸŨ-*ÏÅĸˋfäâĸmęzņ―šņĀĸóŠ&åâĸŠuå‰øĸ2ŽĸŨ=ĸãĸIđøÝĒō\üŋžhF.þßĶŪ7ĸŨŦü?ŊhRŪëĸJ#ŒĸŸ&šbģ<>ÕXkļz.þŋāĸgđøÝĒō\üŋžhF.þßĶŪ7ĸŨŦü?ŊhR.þŊZ7)ĸĮĸ—üŋdeËsÝŪ§ņĸîEãđ<ĸÛ%Ũ;ÂĐĮ.#œ—(?Ûixš\žĸmë>ĸËŦæf_^KŠ–äÎ4Âđ ūĸĸOĘ=t-\‰‹ïÆUrņĸ.đøģ\üßNnÞ}žÂĒusð‚ĸ7ÏÅĸĩsņüŋzŅöđÆĸŧäâĸÍrņ;đøƒ\üŋq.þŊ‹ĸãĸՋķÏ5ØpüŠl°aƒE3rņĸfđøŋ\üŋA.þß8ĸŨÎÅĸ/õüïLþ?ÜóŋÝÏN%đĄD;Oį­á}þ·ąĸóüïaJÅĒ%đUŠŽōüï4þoį ÃóŋŠu“OŋØÄZÃÕs‡xþ·úųĸOĘÅĸë•įâĸåE3rņĸ6u―‰øŋ^ÝxāĸyE“ró.ĶEņĸÓDüĸ_ðĸģÜýa"_ƒ!ėĸo™kĸęžþßĶŪ7ĸŨŦü?ŊhR.þŊZ7)ĸĮĸüĸ,ĸŊ[Tž‹ĸ—ÍČuý?ãĀÅĸóņ―šņĀĸóŠ&åâĸŠu“ņüÁĸKVķ<wßõdþß―h<—įŧäšÏĸķũĸƉ―rCįĸø”ÂĒ%đÍ°<—įäæ}™FaŅŠđöGXžxšÃ[kØfŪ†ĸĮ§ÖÅĸ“r·Ū“Úŋøn\%ĸĸ7Ë==ĸGFÞHÃÓäš#oža#E“rņĸÆđøŋv.þĸW/Ú>ŨfÑë…͆­ÍČÅĸ›åâĸvrņĸđøã\ü_;ĸĮĸŦmŸkģaüŋ}.þß,ĸ7•{øĻ§ý†-MĘÅĸįâĸÚđøĸEžĸÏĸ?ĸŧDŸģŲpFĒ§óÖāųß6u―‰‡įŋĶô›Ïĸ.Ï63ųŋ3 ÏĸŠÖMJäų_žĸ]ÚúĸÓŽXUĪWŽ‡ÉúĒcŅw`%ą þöcĮf”ÂÚVXđï°·Sã|vø–ą?ÛĖ4ōvžŲųžï*ÛðH\áÚƒ›ĐÍÅ·—ĸį―aáþŋRîXũĸ-ܝ(É %Úđ;·ÅviØ~lPtŸËýĸýu‹–äV)ĘýĨ\ûgîĸŦÖMJ<ÝÖŪžËýĸĸ?ËÅĸëMĘÅĸ ‹æåîý?ïĻÅĸóņ―š§ĸŨ­ëþŊZ7)ĸĮĸ—üŋdeËsyþ·cîቾ6E•rjxęŽþß8ąWnčüúąJŅ’ÜáF8)—įĩsyþ·qnÜĸ#?–-ɝi„3rœĸņĸĪ\üŋc.þß%ĸo“‹ĸ›Ę=œęí7lĄhR.ï°įâĸÚđø?þ_―hû\› ãĸ]rņĸ6đøŋĐ\ü_;ĸoœ‹ĸkįâĸWðĸÔÞ/ūŨĘÅĸŧäâĸmrņSđøŋv.þß8ĸŨÎÅĸŊðüï”þÏóŋ-sC‰vžÎۂįÔõ&ōüŊ^ÝÓ8|Õg˜Âšn4{šįOyþŨþóŋøĸ‚ĸŦåâĸ-sí_·ĀĸÔõ&îÏĸņ‘7ŌpF.þŊ”kĸ ƒĸŦÖMJÄĸņĸĸäÞĮĸkMĘÅĸ ‹æåâĸ ęzņ―š§ĸŨ­ëþŊZ7)ĸĮĸü_‹ĸW,š”‹ĸÍËÅĸÔõ&âĸzuOĸŊ[Ũ ü_ĩnRbäÚZXī$ĸ_ðĸz+[%wVĸï^ô4—įŧäōüo›ÜÐųß}]ąhIîp#œ”ËóŋÚđ<ĸÛ87îĸÞŨåEKrgáŒ\žĸ­ŧēUrņĸ^đ‘/_ĩŲ°ĩĒyđø›\üßT.þŊ‹ĸ7ÎÅĸĩsņü_Ģhã\› ãĸ]rņĸ6đøŋĐ\ü_;ĸoœ‹ĸkįâĸøŋFŅÆđ6ÆĸŧäâĸmrņSđøŋv.þß8ĸŨÎÅĸŊðüoûĒ rzþwbĸ·ótÞÛóŋŲoŲ æųße^ĸįų_Ĩ\ûgžĸU­›”Čóŋ<ĸŧāĸ‚\üŋbŅĪ\üŋ°h^.þß Ū7ĸŨŦ{øÝšnāĸŠu“ņüÁĸđøÅĒIđøaŅž\üŋA]o"þŊWũ4ðĸšu―ąĸþ_·nR"þĸ/øŋ ŨėŦ0ĸo™;ÄÕy üŋA]o"þŊWũ4ðĸšu―ĸëÕMJÄĸûŋŌų8ĸ/YŲ^đ4\%—įŧänþÓËĸ*Z’ëMŒėóUŠ–ä7ÂIđ<ĸÛ ·ĸ+åNÖpüTc°aƒđՋjŸĸ;úĸS‚H‰õąA4†―c0ø―bp†]5Ø―íÛÂ`4Ø(―ü?ï ‹ûžÅ~. WÉåþ—\îĸ·Éõ&rĸŋWî:āÛ°ÛoØBŅÔ\îĸ·ĖÍūž–-ɝl„3r'ūĸŸŨpÉĘöĘĨá*đø—\üŋM.þo*ĸo‹ĸ·ĖÅĸĩsņžĸÕ(Ú —į[æ†M=·Ïĸ6ĻJ\ĸtäí4œškötzyÎ0…u―ą“ĨW”į%‰ũƒÏĸ.QįĐRĸOÍ5{Á*ĖÅĸ[æqu^ĸoP7”ˆĸ+Õ= üŋn]oāĸzuSðŠUī$ĸĮĸĸ+åŽâĸvîN”äqu^ĸoP7”ˆĸ+Õ= üŋn]oāĸzuSņĸōšø?þŊQīA.þß2wˆŦóøƒšĄDü_ĐîiāĸuëzĸŨŦ›šˆĸ—ŨÅĸyþŨHŅ’\› GNP6ķV4/—įÛä†ÎĸËŲÉŋĪhIîp#œ”Ëóŋ rÛøŋRîd _ÜĸŦäjøĸáEÝšøƒ\Ū’‹ĸwÉÅĸÛäâĸÖrïÎĸŦæâĸ-sņí\üĸ7Rī$ŨfÃø—\Ą‚Ö-Zž;ÐGņĸŽđøŋv.þß2ĸŨÎÅĸņ#EKrm6ŒĸwÉÅĸÛäâĸÖrņí\üŋe.þŊ‹ĸóüŊFŅđ<ĸÛ27”hęéž5„ Ö-šÏåų߉ýßōétJĸ7u†áų_―šĐ‰ũžĸ]ðAŪå VIŪ}ĸ__‘›ÕČâęžþß n(ĸWŠ+‰ý°s†)Žë ü_Ŋnj"þ_^ĸĮĸ5Š6ČÅĸ[æquÞ"4ėŠE·\üĸŊ^WøÅšÞĀĸõęĶ&âĸåu•ü_ïüĸ§æZū`•äâĸ-s‡ļ:oĸkŨ %âĸJu%1Ä)15ŅÔĸŨŦ›š?Ïlļn.þŋŒāĸ%+Û+—†kåšš;Q’;VÃ}ý Ē%đĄóĸröĮߒĒ%đÍpI. käōüoËÜėËkIŅ’ÜųF85Wûüĸ7ČĨáZđø—\üŋAnčü/y; ϚKÃđøË\ÖÎÅĸņ#EKriX;wŽ†ņĸđøŋå\ÖČÅĸ[æŌ°v.þĸ)Z’KÃÚđc5|?XĮjļWŅ’\üßr. käNų ŦfsiX;ĸįų_Ē r‡xØ-4øfNM4õtÞ}ýĸâÏĸÎíĸ–O§CœSMaÚø?ÏĸJ•FĐ$·eQžĸ]ÚúĸÓŽXýŋcto@)†XŊ!š, ›+Ø·Ŧ–Õ­ĸ*H―ŧP kūË―e‡Đ•jģ{_įôUĢôĐ6Wó――ü?ï ũĸ•r‡ļŲÅýĸ’ĒŲđ}š‹ßĸ·đKÔ*jųt:Ä)15ŅÔîÄý―šĐ‰Üĸ/Ŋ[―á‰ïĸį5Œĸ+åqąÃĸKŠfįâĸÚuC‰øŋR]I qJLM4ĩ;áĸzuSņĸōšø?Ïĸ)Z’KÃÚđ4ŽKÃÚđÃ5\’KÃJđ<ĸÛ,—†ĩs5üáųßJ+Û+—†ĩsiX;—†ĩsiØr. +åâĸÍriX;WÃĸUŋĸĸoKÃÚđ4ŽKÃÚđ4l9—†ĩsiX;—†ĩsņüßHŅ’\ÖÎĨaí\ÖÎŪá’\ÖÎĨaí\ÖÎÕ(Šĸïƒį•r‡x؍įKŠfįōüŊvÝHĒÍ]ĒVQ˧Ó!N‰Đ‰Ķv§6#Ėóŋ’Džĸ-Ŋ‹ĸãĸEäqąÃĸKŠfįâĸÚu#‰6w‰ZE-ŸN‡8%Ķ&šÚð―šĐ‰øy]†UXü?5ŨōŦ$wˆ‹þ_R4;ĸŨŪIīđKÔ*jųt:Ä)15ŅÔî„ĸëÕMMÄĸËëâĸøŋFŅđC\ėðĸ’ĒŲđøŋvÝHĒÍ]ĒVQ˧Ó!N‰Đ‰Ķv'ü_Ŋnj"þ_^ĸįų_#EKriX;—†ĩsiX;wļ†KriX;—†ĩsiX;wô†ņ\ÖÎĨaí\ÖÎĨaËđ4ŽKÃÚđ4Ž;zÃøŋF. kįŌ°v. kįŌ°å\ÖÎĨaí\ÖÎ―aü_#—†ĩsiX;—†ĩsiØr. kįŌ°v. kįŽÞ°}ĸįų_ĨÜ!vãųߒĒŲđ<ĸŦ]7’hs—ĻUÔōétˆSbjĒĐ݉įõęĶ&ōüoy]†yþwøŋRî;üŋĪhv.þŊ]7’hs—ĻUÔōétˆSbjĒĐÝ ĸŨŦ›šˆĸ—ŨÅĸņĒ r‡ļØáĸ%Eģsņíš‘D›ŧD­Ē–O§CœSMíNøŋ^ÝÔDüŋž.þĸkm;ÄÅĸ/)š‹ĸkŨ$ÚÜ%jĩ|:┘šhjwÂĸõęĶ&âĸåuņđĸ?%‚ ‚ Ēyôōĸž7,î{ûđ4ŽKÃÚđ4ŽKÖsiX;—†ĩsiX;wô†ņ\ÖÎĨaí\ÖÎĨaËđ4ŽKÃÚđ4Ž;zÃøŋF. kįŌ°v. kįŌ°å\ÖÎĨaí\ÖÎ―aûþÏóŋJđC<ėÆóŋ%EģsyþWŧn$Ņæ.QŦĻåÓé§ÄÔDSŧÏĸęÕMMäųßōš Ïúüo^ÃøŋRî;üŋĪhv.þŊ]7’hs—ĻUÔōétˆSbjĒĐÝ ĸŨŦ›šˆĸ—ŨÅĸņĒ r‡ļØáĸ%Eģsņíš‘D›ŧD­Ē–O§CœSMíNøŋ^ÝÔDüŋž.þĸkm;ÄÅĸ/)š‹ĸkŨ$ÚÜ%jĩ|:┘šhjwÂĸõęĶ&âĸåuņžĸ5Rī$—†ĩsiX;—†ĩs‡kļ$—†ĩsiX;—†ĩsGoĸŨČĨaí\ÖÎĨaí\ķœKÃÚđ4ŽKÃÚđĢ7ŒĸkäŌ°v. kįŌ°v. wÎýö‡dú6lŊhI. kįŌ°vîč ãĸđ4ŽKÃÚđ4ŽKÝsĢ>ïIÄĸŦæŌ°v. kįŽÞ°}ĸįų_ĨÜ!vãųߒĒŲđÝšf‰<ĸÛ qŸkčtęøüÉ)qLĸ7ĩ; qŅ)Läųß!tšįü_kč‚U5wˆS1þ_R4;·ûAŨ,ĸoļÏ5t:Åĸ‹‹ĶæqŅ)LÄĸMét(ðĸĸäš`UÍâTŒĸ—ÍÎí~Ð5KÄĸ$îs NņĸâĒĐđC\t +ņS: +üÁĸđ†.XUs‡8ãĸ%EģsŧtûNT‹âĸ ũđ†N§øqŅÔ\ūĸ_Ŋnj"þ_^ĸįų_#EKriX;—†3r“\ŅBÃö‹–äŨðI.ÏĸvÍírãĻĪ.#ŽKÃÚđøƒ\ÖÎĨaíÜî §Þ(îÞðEKr‡kø$ĸïšŦ]īúߎaí\ÖÎÅĸäŌ°v. kįömØЧDÔriļs.þß5·AŅšÅa„ĩsiX;ĸoKÃÚđ4ŽÛąá ų//Ú>—†;įâĸ]sÛuO&ÆŪ˜KÃÚđĢ7ÜŌĸŸfÅú(bĮčހR ą^C4Y6W°{WÍčūĶnlĐbØYŧŧÏĶÄ{sį"ė øÓæÍtYwS‰QúT +ģŦŊÝX/ĸÏ{ÃŌýŦHfý(ßĸÓ27”hęÛ9ķč~Ð-­>ĸÏũĸ4H\ +6k­šžāûŠ‹Ķæķžčôúü?ßĸÓũ # ūĸgÁĸđ†.XUsņĸ–đC\·č~ÐmmhÅĸ$îs NņĸâĒĐđÍ.:ŋĸĸ7ĨÓĄĀĸü_kč‚U5ĸo™;ÄÕy‹îÝūÕĒøƒÄ}ŪĄÓ)þ_\45—ïĸŨŦ›šˆĸ—ŨÅĸyþŨHŅ’\ÖÎĨaí\ÖÎŪá“\žĸíšKÃÚđ4Ž;zÃøŋF. kįŌ°v. kįŌpį\üŋk. kįŌ°vîč ãĸđ4ŽKÃÚđ4ŽKÝsņĸŪđ4ŽKÃÚđĢ7ŒĸkäŌ°v. kįŌ°v. wÎÅĸŧæŌ°v. kįŽÞ°}ĸ·ó(ĒņĒ%đ4ŽKÃÚđ4Ž;\Ã'đøŨ\ÖÎĨaíÜŅÆĸ5riX;—†ĩsiX;—†;įâĸ]siX;—†ĩsGoĸŨČĨaí\ÖÎĨaí\ĸwÍĨaí\ÖÎ―aüĸ4wĸuŽÂ/ŊbŊČXŊōĒĐđĄ&‡aIĒd+īoxÐúÂv…ÄýũĸįŲ%j5t:~ĸŋ§·1ýßÔî4ÄE§0ŅŧŽŽo ƒ ŨÍ­ē+j4ŽzĀįĸ%+[%ŨÐŦjî}]ķÕ1{*ū‚ĸŸn…ŦųK_ĮĸWMÜįfœvðĸ’DSg˜6þßýĸĸrÜÔ.ąþ_î?ø?þŊQīA.þß2wˆŦóū+ü_ĩn$ĸŨĻë üŋļhj.þŊW75ĸĮĸņĸÓ܉ýĸðoƒĒĐđWðĸål+āĸzEˏü?)7cĀņĸ’DSg˜‹øĸâ ļĐ]b ü)öüzĸ_Ōw’î Kbĸ_1’DSWįPc͊.øŋÓUÝĒ%đÓûĸēkĖ“ˆĸŨȍpĨĒøŋ01ēWØlļbŪYĸ_4ÏĸÃųŋę‰B˜;ąĸ/ĸĶ]4#ũ +þŋD·ÂÕüŋe⹂ë›ü_)qqÎĨKĘiĸ/Iīv†iāĸJđIþŋ<p› ãĸK™ĸāĸøŋRQí\üŋeî(Wį-ðÕšņDüŋz]OāĸÅE3rņĨš‰øĸ‚ĸãĸ‚ÜĪ=ÄBç!ų˜YõĒyđF>X’{zu^Â[ĄWÃÖΊ‰›ĸ/Íßėtų CIn]ĸ_ÄÞŌĸ—Įŧ„dþīĒjđa‚#ŽYī<7ãjeÜĸ3ŧDûĒUüGŊá6ŸaÃĸ…đø•Ēyđø^Ņ’\ü_ĩîi"þ_·Ū'ðĸâĒyđøŋFÝžD#ŧDûĒøĸŌÖĸŸAœÅú–Ÿ TãîóŠó―‚A„Ē—ĸį―aqßģØÏĨaí\ÖÎíØð@”äŌpįÜčý|Oâ˜ũĸÍæęmsïÔ~. kįŽÞ0þŊ‘KÃÚđ4Ž‹ĸkįŌpį\üŋk.þŊKÃÚđĢ7ŒĸkäŌ°v. kįâĸÚđ4Ü9ĸĸkįŌ°vîč ãĸđ4ŽKÃÚđ4ŽKÝsņĸŪđ4ŽKÃÚđĢ7ŒĸkäŌ°v. kįŌ°v. wÎÅĸŧæŌ°v. kįŽÞð@þ?ЧFß+ėįŌ°v. kįŌpį\üŋk. kįŌ°vîč âĸ‡/kÝH]ßÔš{åŌ°v. kįŌ°vîp Ÿäâĸ]siX;—†ĩsGoxDĸ_ĸßÍIë›ZWRBĢhƒÜýz™mØÔĸNR’JīųķïšŨō/}ĸ+Ēąv‰ZE NŸ?9%ŽéĸĶv§6ūÏĸzŦ›Ú%֘õF•]QĢaÕvDĸwĸ/ÏÅĸ[æquÞĸŨŪIīđKÔ*jčtŠĸMÍÅĸõęĶ&âĸåuņü_Ģhƒ\üŋeîWį-ðíš‘D›ŧD­Ē†N§øqŅÔ\ü_Ŋnj"þ_^ĸïåĸÍ>ĸoč‚U5ĸo™;ÄÕy ü_ŧn$Ņæ.QŦĻĄÓ)þ_\45ĸŨŦ›šˆĸ—ŨÅĸ§ŋĸß2ąW. kįŌ°v. kįŨðI.ÏĸvÍĨaí\ÖÎ―aü_#wô―Â~. kįŌ°v. wÎÅĸŧæŌ°v. kįŽÞðþĸīëũĸīLė•KÃÚđ4ŽKÃÚđÃ5|’‹ĸwÍĨaí\ÖÎ―áýŸïĸŊžKÃÚđ4ŽKÃÚđÃ5|’‹ĸwÍĨaí\ÖÎ―áQüéũĸĸz`­j.ÏĸķĖ %Ú|ËóŋÚu#‰6w‰ZE Nyþ·ļhj.ÏĸęÕMMäųßōš óüo­•­’kč‚U5ĸo™;ÄÕy ü_ŧn$Ņæ.QŦĻĄÓ)þ_\45ĸŨŦ›šˆĸ—ŨÅĸņĒ rņĸ–đC\·ĀĸĩëFmîĩŠ:Þ}>•ū g%šÚð―šĐ‰øy]ü_îĸOĮŒÕ…æ‹!Ökˆ&KÂæ +öíŠeuƒão°ĨŠayí,ũ–ĶVŠM3Ũ9}•Ä(}*…ŲÕŨnŽ—ĸį―aqßģØÏĨaí\ÖÎĨaí\ķœKÃÚđ4ŽKÃÚđĢ7ŒĸkäŌ°v. kįŌ°v. [ÎĨaí\ÖÎĨaíÜŅÆĸ5riX;—†ĩsiX;—†-įŌ°v. kįŌ°vîč ãĸđ4ŽKÃÚđ4ŽKÖsiX;—†ĩsiX;wô†íûßŊ"YL}aEÕ\ūĸ§en(ŅÔ·slÁũĸhŨ$ÚÜ%jĩ|:┘šhjwâûôęĶ&ōý?åu5žõûōÆĸ•r‡ļØáĸ%Eģsņíš‘D›ŧD­Ē–O§CœSMíNøŋ^ÝÔDüŋž.þĸkm;ÄÅĸ/)š‹ĸkŨ$ÚÜ%jĩ|:┘šhjwÂĸõęĶ&âĸåuņü_ĢhƒÜ!.vøIŅė\ü_ŧn$Ņæ.QŦĻåÓé§ÄÔDSŧþŊW75ĸ/Ŋ‹ĸóüŊ‘Ē%đ4ŽKÃÚđ4Ž;\Ã%đ4ŽKÃÚđ4Ž;zÃøŋF. kįŌ°v. kįŌ°å\ÖÎĨaí\ÖÎ―aü_#—†ĩsiX;—†ĩsiØr. kįŌ°v. kįŽÞð(þŋÏ―–ŽojÝƉ―riX;—†ĩsiX;wļ†KriX;—†ĩsiX;wô†íûĸú(ĒŨųï/øŋåÖJr‡x؍įKŠfįōüŊvÝHĒÍ]ĒVQ˧Ó!N‰Đ‰Ķv'žĸÕŦ›šČóŋåu5æųß}„üĸŊ|}“ĸŊ^45ĸ/)š‹ĸkŨ$ÚÜ%jĩ|:┘šhjwÂĸõęĶ&âĸåuņĸŽũĸüŋ wˆ‹þ_R4;ĸŨŪIīđKÔ*jųt:Ä)15ŅÔî„ĸëÕMMÄĸËëâĸÍūĸß{ÃĸÏÎâb‡ĸ—ÍÎÅĸĩëFmîĩŠZ>qJLM4ĩ;áĸzuSņĸōšøģïĸéåĸ-{åŌ°v. kįŌ°vîp —äŌ°v. kįŌ°vîč ãĸđĢïösiX;—†ĩsiØr. kįŌ°v. kįŽÞð@þŋølĸŊ’KÃÚđ4ŽKÃÚđÃ5\’KÃÚđ4ŽKÃÚđĢ7ÜŌĸŸĮ}ņûŨ{ĘNAASF/ĸÏ{ÃŌũQÄÅök%đC<ėÆóŋ%EģsyþWŧn$Ņæ.QŦĻåÓé§ÄÔDSŧÏĸęÕMMäųßōš óüï>ðĨÜ!.vøIŅė\ü_ŧn$Ņæ.QŦĻåÓé§ÄÔDSŧþŊW75ĸ/Ŋ‹ĸãĸEäqąÃĸKŠfįâĸÚu#‰6w‰ZE-ŸN‡8%Ķ&šÚð―šĐ‰øy]üĸŨ(Ú wˆ‹þ_R4;ĸŨŪIīđKÔ*jųt:Ä)15ŅÔî„ĸëÕMMÄĸËëâĸ-ŋĸg”\ÖÎĨaí\ÖÎĨaËđ4ŽKÃÚđ4Ž;zÃøŋF. kįŌ°v. kįŌ°å\ÖÎĨaí\ÖÎ―aü_#—†ĩsiX;—†ĩsiØr. kįŌ°v. kįŽÞ0þŊ‘KÃÚđ4ŽKÃÚđ4l9—†ĩsiX;—†ĩsGoØūĸóüŊRîŧņüoIŅė\žĸÕŪIīđKÔ*jųt:Ä)15ŅÔîÄóŋzuSyþ·žŪFÃ<ĸŧü_)wˆ‹þ_R4;ĸŨŪIīđKÔ*jųt:Ä)15ŅÔî„ĸëÕMMÄĸËëâĸøŋFŅđC\ėðĸ’ĒŲđøŋvÝHĒÍ]ĒVQ˧Ó!N‰Đ‰Ķv'ü_Ŋnj"þ_^ĸĮĸ5Š6Čâb‡ĸ—ÍÎÅĸĩëFmîĩŠZ>qJLM4ĩ;áĸzuSņĸōšø?Ïĸ)Z’KÃÚđ4ŽKÃÚđÃ5\’KÃÚđ4ŽKÃÚđĢ7ŒĸkäŌ°v. kįŌ°v. [ÎĨaí\ÖÎĨaíÜŅÆĸ5riX;—†ĩsiX;—†-įŌ°v. kįŌ°vîč ãĸđ4ŽKÃÚđ4ŽKÖsiX;—†ĩsiX;wô†íû?Ïĸ*åņ°Ïĸ–ÍÎåų_íš‘D›ŧD­Ē–O§CœSMíN<ĸŦW75‘įËëj4ĖóŋûĀĸ•r‡ļØáĸ%Eģsņíš‘D›ŧD­Ē–O§CœSMíNøŋ^ÝÔDüŋž.þĸkm;ÄÅĸ/)š‹ĸkŨ$ÚÜ%jĩ|:┘šhjwÂĸõęĶ&âĸåuņđĸ?͊UE:Fũ”bˆõĒɒ°đ‚}ŧjYÝāølĐbX^;Ë―e‡Đ•jÓĖuN_%1JŸJavõĩëåĸyoXÜũ,ösiX;—†ĩsiX;—†-įŌ°v. kįŌ°vîč ãĸđ4ŽKÃÚđ4ŽKÖsiX;—†ĩsiX;wô†ņ\ÖÎĨaí\ÖÎĨaËđ4ŽKÃÚđ4Ž;zÃøŋF. kįŌ°v. kįŌ°å\ÖÎĨaí\ÖÎ―aûþÏũĸ(åņe|ĸOIŅė\ūĸGŧn$Ņæ.QŦĻåÓé§ÄÔDSŧßĸĢW75‘ïĸ)ŊŦŅðŽßĸ“Ũ0þŊ”;ÄÅĸ/)š‹ĸkŨ$ÚÜ%jĩ|:┘šhjwÂĸõęĶ&âĸåuņü_ĢhƒÜ!.vøIŅė\ü_ŧn$Ņæ.QŦĻåÓé§ÄÔDSŧþŊW75ĸ/Ŋ‹ĸãĸEäqąÃĸKŠfįâĸÚu#‰6w‰ZE-ŸN‡8%Ķ&šÚð―šĐ‰øy]üÄį‚ ‚ ĖD]ĸ™æ=ŽŲÜŅūŽĸę—?•Į ŸxáߧÄ-^->:Z|līøøhņ‰ŅâÅĄâĨŅâåŅâ•Ņâ“ĢÅTˆũūũ―ŲĒēú’Üa$1šÚÏ―á+ûĸÝä3xßwūï.ÉߎïQ‹ïՉïӉïW‹ЉT‹ũëÄĐÅëďĻÅtâGuâĮÔâĮuâƒjņ!ø°Zü„NüĪZü”NüīNüŒZüŽNüÜ.ž{îđ―ĸ$ąW]ĸÝNíįŽÞ0þũyÉæþ?Ū–ë™đ’–ë™đ’–ë™9ZŪŠåzfŪĪåzfŪĪåzfŪĪåzf>––ë™đ’–Ėžbü|86ĸĸŪ”øôŸĸðĸ~EKrGoØūĸk<Šxļĸ/ĸäÏęĸ/žðÂ@ZŪgæJZŪgæciđž™+iđž™+iđž™+iđž™ĢåŠZŪgæJZŪgæJZ7ó’øq<ĸüóËkþ/ô“ŧüŊ)íýŸįËëōüïčþŸqĸĸĢýčĶÖO^ Wđ·éĄôī\ÏĖĮŌr=3WŌr=3WŌr=3WŌr=3KËõĖ\IËõĖ\IËõĖ\IËõĖžŧ–§Æ/æÆÁĸ%þŽsâĸí‹âĸ þŸuĸĸîĸ›iŊzïø6}?ÃXZŪgæJZŪgæJZŪgæhđŠ–ë™đ’–ë™đ’–ë™9ZŪŠåzfž­å§ņ*śßüæĸ7ĶÓĄĀĸü?ëþĸĮ>öą―~Ŋ†ï2––ë™đ’–ë™ųXZŪgæJZŪgæJZŪgæJZŪgæciđž™+iđž™+iđž™ŨŌr7þĄNžå-oYûĸýÅ]Οē~ėĸïXĸ_Fðĸ’• åÞĸŋûĸÞÆWÛߛų:Å}―ýš!ô-WÕr=3WŌr=3WŌr=3WŌr=3KËõĖ\IËõĖ\IËõĖ\IËõĖ\IËĸ‘ZüŌãpýĩýý[€Ãýß`. kįâĸKņýĸüã{-ß|>ōcäĩwâ]ĄŨŨChđž™+iđž™+iđž™ĢåŠZŪgæJZŪgæJZŪgæhđŠ–ë™ų/ĐÅ?ŽÆ[ßúÖÅũųŸÍųōĸ[(Z’;zÃ-ýĸЙ(žĸ?l^―wõƒ·‡~ĩ―^_ŽzmMËõĖ\IËõĖ|,-Ũ3s%-Ũ3s%-Ũ3s%-Ũ3óąī\ÏĖ•ī\ÏĖ•ī\ÏĖãZ^ĸ$%Bþŋ™ŋûY ƒĸũ6#bþčåĸyoXÜũ,åđ…ũĸï‡íAģ#ÞîþjŦKoŊÝhđ)-Ũ3s%-Ũ3s%-Ũ3sī\UËõĖ\IËõĖ\IËõĖ\IËõĖ<IËåņOËâmo{ÛRæĸuý§š8iįŌ°vîpþoðû^|ņEWž]ŦßO_-zĸzÛtũE/3WŌr=3WŌr=3WŌr=3KËõĖ\IËõĖ\IËõĖ\IËõĖ-WÕōr3Å?Ŧ!ĸ·ųųžĸ-ŊŦŅ0ÏĸîÃāũĸÜý?äð›·o"―Nq_B8›ž™+iđž™+i𞙏ĨåzfŪĪåzfŪĪåzfŪĪåzf>––ë™đ’–ë™đ’–W7ó-þđZ|ä#yûÛßūŒóü/þ_^ĸÝĸ3îĸŋôŌK^-_―ýāÕû‰ÛwfwķAo˜ĢåÚfŪĪåzfŪĪåzfŽ–Ŧjđž™+iđž™+iđž™+iđž™D'þ…/ÞņŽw,|ĸ§1þŋāĸYũĸïþïÕōÕÛãũ&ðÎvWčõõ(fŪĪåzfŪĪåzfŪĪåzf>––ë™đ’–ë™đ’–ë™đ’–ë™9ZŪŠå!3/)ŨĸOĸïUĸ_Fðĸ’• åÞĸųå—íkđž™+iđž™ĢåŠZŪgæJZŪgæJZŪgæJZŪgæciđž™+iđž™+iđÐĖ3â_ĨĮ;ßųÎeĸ7˜KÃÚđøĸR|ĸĸ•W^1Ļåzf>––ë™đ’–ë™đ’–ë™đ’–ë™9ZŪŠåzfŪĪåzfŪĪåzfnG˅ņŊ‹cïĸŦÛKbÁĸŧ-É―aü?ãþĸÝĸ'Ör=3WŌr=3WŌr=3WŌr=3KËõĖ\IËõĖ\IËõĖ\IËõĖ|,-Ũ3ór-ÅŋĐïzŨŧVĸđË’Ĩāĸ‹–äŽÞ0þŸĘÝĸ?ųÉOrÞĢ–ë™9ZŪŠåzfŪĪåzfŪĪåzfŪĪåzf>––ë™đ’–ë™yu-ßâßęÄŋ{-Þýîwïý' üŋWŅ’ÜŅķïĸ ūĸįŪôIžį=ïyããxÓhņÜPņühņæŅâ-ĢÅ[G‹·o-Þ1ZžsīxŨPņîąš“œŽþÏóŋåuyþwĸ—|þŸ ‚ ĒVāĸ―Šâĸ˅ýßÛ'���€6øĮĒøĸ‚ĸãĸ���ÐüŋcQüÁĸKV6”‹ĸ��@/úúŋÁ\ÖÎÅĸü���úĸ[(Z’;zÃ7üĸ��€†āĸŠ–äŽÞð ĸĮĸ�� !øŋ…Ē%đĢ7|3ïĸ<ĸ ���3Áóŋ‹ōüï‚ĸãĸ���ÐüŋcQüiëĸOģbõĸšĸ��@/\ãŠŪ:‘Ð0ŦÂėęk7ÖËĸóÞ°pĸ���f‚ûĸ‹rĸÁĸKV6”‹ĸ��@/xþŨBŅ’ÜŅūáĸø?���4ĸ·Pī$wô†oø?þ��� Áĸ--É―áþĸ��@Cð EKrGoøfÞĸyþ���f‚į;åųßĸÜĸģ‡eˆ8Ý.―l V?ūúũsėÜ\|õ Į§ũþ[CþĐ"ĸw,Šĸ/øĸøþß―=$įüîM2Žū…Õ_ÏąģÆéƝ{õOãt|F?:F8üO›tįĮĸ{Åĸüĸ·ĘšÏ\võ V?iõ%óŒËéƝ{õËĮgčĢcˆÃ?cÄĸ;Åĸ—üŋdeCđøŋ}†8į3Žū‘ÕŸ[€O7îÜŦ_>>CCþÃųŋÁ\ÖÎÅĸü†8į3Žū‘ÕŸ[€O7îÜŦ_>>CCþøy. kįâĸ‹Ķĸ?<<iyÎYtNzŨÂKÉ9?ÞųÚE–pĸÕöÛÓBĄÜéyĢĄš[BĄ�T‡ö›^ļú]øɟþ@›B§'šÓÕŊÛjģŊ5>mŽï2˗_îĸ Î�øy. kįâĸK%ĸ_/ũû‹~ÝóŒ„Ĩ­ĸ·\ŧýĸ0ýšþŊ1öý_oÓ WĸĮĸófĀĸģW-ĩIgQøĸĒ%đĢ7|3ïĸ6Ÿĸĩ`ȧ'―ę§8üŋîø\ÁĸŦ,g8ĸŊŧüĸôDŨxõņĸ8u—‰ĸW”Ÿ-xþ·ž.ÏĸâĸîôÃķ_IîŠČ?BpzŌó6ęÁ}íΞ_BRŪ·zœŠŸų<”Nę0ēACUž[0ēðČ*ŽFd­…Ûąã čí ‘AßÃTÝôÂÕOŌU_ïĸnŧ―ŸēŸčÍ:üVžčV,Ųļ‡ÕõpømžÉHŦĄÎ3’šžOĮ'2Cęų0t]p—zzuĻëĸIŨÁÓ#7ĐI§+üŋ[Ņýęg8ĸŋŽĸ{Ï―83ûĪwz֊Ÿũ„}Jrå*•t:•Žū[.ĐÃÐPHj•ŒaõŅČØĶ^óï2;CŌØqÓ W?Õĸ―Î)ûÃr23nžŸnÜýę{—ï0i"Ŧšž­1>‘äįCïđ4õuÆÕĄĒĸˏôĪ#TØĪÓÕxþŋöčít›ļύÏyømÁ‡Äóýĸ^ôž›WĸÏóųhÛôĸíT&đïqęIÎ/?é…;=­UÝËĸ“Ö:iÕ$åŽųõŨÍAã @ä=HöØáüĸôĩ;Ņýív;ū4áÍó§·Šĸ Į!ē +Ų 97Uĸũūv'VņĸøbņĄÃ,UÜûïšr­ƒgf۔xûŨ}qøíūŪ77īœÃoã…ž o++ûęo%"7Õöþŋ5|šõũó‡ŠÞúĸķqÝíž4P‡UóþÚ_›ģÚũĸ<þ’wũ_9Kúįždžõ=’nÛûŋ·ÃZę›īðYý?{4>ĸ“ī“K[}­“Vŋšĸŧ’ņúŋ{o_ž(ėVēq―ŸĸņŪrŠĸG>,”4°ņ…DþnäĪņ‰Ėz> ÍSâĸņŦC]ĸ4œšjĐM:]Åü;="ÛņCō|(”$“qãŠĖvú[ŨÖNßk„Þ/Ä;<üļĶä-ÏþÅĐĸGJ{Õԛ~XTŌÖw}xŋü[ûĸ!ĸģdŧ' HÝïĸÅĸ…Ý +_‡z–Œ€„ÆþŊ­ūŲÛĒÖhXðĸėÆš|þg{-Ų{õ6―põëúŋðÎsü#+Þ’é.§ŨŧúņĩØxÆįō"ŋÕïM9ŸČ IįÃČl§Ë”Ô’o\ų +Ę–œčTýßkž‡Œãþc-éō—ũ–xÄTũ3äÝwíÔŧðÐ;šSõ]ƒā~`é4ũtӄˆü6īū§Šøˆ-mýĸĐ/vïûķ)îtũ·ûÝé‡ŨΒ›úäüsjŨ%'=y·Ų7'ãS„W/ŠŸĸ—wX]}…wʏFj]SƒÐĖĸũuŧŊuŌęwũĸČgLųĸi·§ã \Ģšþ|ÉøDfĻåĸŲŊŦžĸžýäÜÔ`ĸũzKČg2bÓŠÃëÉĒÁzyÍ3d­nâáW!Yu—_Ōę―üĸôJ(ž†ßėœū!õæÖzþŨ―^ĮO/BŸgä'=oÃÞén'§ó‡šŒŒLHoēO§ÂÕ?”ŽœØÝŅĻ"ĄÕí!-ý?ēHrÛ ‚ŌÎāöfpÓ W_ïó?Ûôļ‚šŸZņÎæá”Ӎ{øüäó?åãZZÉB$‰‘ĩ;ŸČ ’3ööŊðĞņ^ ruÐþþwáŠĨ6é,ŋÏóŋĄÛāUŠ–äv)Z’[ąĻû· šÖüĸ4Ė>ĸk%ýþEžgBđáĮâĸ|oÆÅGƒÕŊëĸÃqšqóV?é=ˆeNĮgčĢcˆÃ,ĸŋÃũ–ŨÕðĸõÁdĨšøĸ‚ĸŨ tŧĸŨāâĢÁęãĸW?ãÆ9ŸĄŽ!ĸüĸUÂĸmųĸ"û0La]üÁĸG`ˆs>ĢÁęY}üâÕ/ŸĄŽ!ĸąüáĸĸēįĸ‹ā}Ya]ü™ÎĸïÃ;%Âs~ũ> VŋûęKæ—ĸ/ŸŅŽ!üŋ0ĸĮĸ+Ūl(wĸ˜=.ūú‡ļøh°úîįØė“äqņÕ?éŽ!V0õōÝŅĸ æŌ°v.þŋLäĸ���0øŋ…Ē%đĢ7|Ãĸņ���hþoĄhIîč ßðü���‚ĸ[(Z’;zÃ7óþÏóŋ���0}ýŸįËëj4ĖóŋûĀĸ��`&ðĸŽEņĸĸĮĸ�� -øĮĒøĸ‚ĸãĸ���ÐüŋcQüÁĸKV6”‹ĸ��@/xþŨBŅ’ÜŅūáĸø?���4ĸ·Pī$wô†oø?þ��� Áĸ--É―áþĸ��@Cð EKrGoøfÞĸyþ·1ũÍ؎>`ķŧ+@-xþ·cQžĸ]ðüßa―Ę Ąb(Ø]*‚ĸw,Šĸ/mýĸiVŽþ_7ðĸ\åęŅa`U�ãļÆU]u"ĄaV…ŲÕŨnŽ—ĸį―aáþcļĘ3ÔĢÃĀ2Š�ÆáþĮĒÜĸ_Fðĸ’• åâĸė_åžtïá"C=(övÄ}ØþĻ ÏĸZ(Z’;zÃ7üŋķĸÛđēįuâ―Ęßĩáxø•Áõ2H{Ą:l>û[Ąâ>Y`Ë―7u―svÜųņ€ŠāĸŠ–äŽÞð ĸÏōW}·ëē;­åN!éēĶv†Ũiė$$CíŪlÝõ ųF•áü?ô.ĩýþœTHÉĸ5vW�ƒĸ[(Z’;zÃ7üŋėþŋYÍîM"ĨIË_g;žEōZM|·häOnVƒ{žI6%j=ĸ—LÏXTí!Õ―ĸ/īkÕ}8žĨwĸŋúî +�rð EKrGoøfÞĸ?ĸđxkC\óž3ļt Ih†PÅ$ĸ—|ø'īún{ņyžc+ųmËũhr›:ęø ĪšhdX܍ũOųÛŪø ]öálĸŨ؇%YzþŦšŧ@}ýŸįËëōü/þ™’tq?―Ušxę―§ũĨTþ+‰– Õ=Ãĸ[ĘĸkE6%ęTcŒO/gųÞZZvÅZûpķĸWy]qĻkQkw€$ðĸŽEņĸĸorĸ?ō:ÝâWeOęģ“§ŋUu'ïýáČÝŨ6Hl*>ÔĄÍWq<;úŋ}ĸŋUÚ] üŋcQüÁĸ øŋŦŽî%Šå.$ĐĘFč*šĻíN§Ë—ß|n€d§ŠkjhŦôĸQöáøš†ÓįŒĄŽŊx6…ŧ+�Ī‚ĸw,Šĸ/#øÉʆrMųjĄŒŠIÚúî”Óu7åĸI·‹{‘§Đý_ļū}ũáÓŌ‘}ýĸ极ęþPžĸĩPī$wô†oøŋĸ_ßKl-IĻžßĸđ}zKķŠ/yĮŲ­jFxßļ1öýßÝÜîô!öáx‡§û†Ō>œīEšï―ø?@Eð EKrGoø†ĸwõĸۙš +…vĸcH™B.wĀæUūŧüh ęĸĄũG‘î"ģą§2ú>lsTĸ·Pī$wô†oøíĸĸwtļĘO0ÔĢŦĶŲ―2Œ*@Eð EKrGoøfÞĸ?ĸ;\å'jüŸ}˜Q° Ïĸv,Ęóŋ þĸ;p•gĻG‡eTŒƒĸw,Šĸ/ø?þïĀUžĄ–Q0þßą(þŋāĸøŋÃ}cA3„Š}xØ]jĸw,Šĸ/#øÉʆrņĸŲCMäEũ->―7éĖŅ}ãĖÏĸZ(Z’;z÷†þĸÔLāĸ���Ð Ũļz›1ôōĸž7,î{–ō\ü���zÁý EKrGoø†ĸãĸ���ÐüßBŅ’ÜŅū™ũžĸ��€™āųߎEyþwÁĸņ���h þßą(þŋāĸø?���īĸïXĸ_ðü���ڂĸw,Šĸ/#øÉʆrņ���čÏĸZ(Z’;zÃ7üĸ��€†āĸŠ–äŽÞð ĸĮĸ�� !øŋ…Ē%đĢ7|Ãĸņ���hþoĄhIîč ßĖû?Ïĸ��ĀLðüoĮĒ<ĸŧāĸĢųĸ}$aDķĢŒÝæâôÝ�ĀøĮĒøĸ‚ĸčĸŲCAôŠîÖĮnc$šï �`üŋcQüÁĸĮôĸîm@Ý·ZũāƆ�€øĮĒøĸ2‚ĸ—Žl(ĸ‡–tßjÝ€�vðüŊ…Ē%đĢ7|Ãĸ'õĸ‡‡'ÞŨōŽį·šK—îÖŨ―ļą!�`þoĄhIîč ßðü?Uãü†ĸšZÖÏÓq5pOŒäŪŋÏSeĨ"ëu ĘļuÜ-ņ�XÁĸ--É―áþŸåĸUī$mĸŊ}~›ÐĸÎÂM9ÝjÂ}ĐŪĸoYÞô6ΜÔCy•Ú‹­ŋ'�ĀEĀĸ--É―á›yĸ·ųüoŊ;Š!‘sÕQâĸnâáuhođÓŋWŌ#IųB[-īu2†(ÃĸS‹Ęw!oJÞ[ áPļûddŊÎápéš{�\‡ūþÏóŋåuyþWîĸOģbõĸšQÝĸũSB6"ōø q‘“žNŒŋ)Ï_q‘+ŸwŦÅ·ÂþWÞßo‹Č ‘ŠøŋüŊŲþ/ųËHČü#ãVēéęuö�ļŪqUWHh˜Õ@avõĩëåĸyoX†ļĸ{,I>œ$Ėō;Ézþ/_ėÄþsÄ/2gķĸ ĸĶĢíĸ§oWã‰Âô’ŋA”Q Uö�ļÜĸïX”ûĸ þŊvĸĸ4ëô.Ĩ—øį’Dý5ĖTĸ—ô0ßŧ�‰ō…ķZ|Óx•š}# ČÝûô­AÞ{‡Īâ3tũĸ[=�.þßą(þŋŒāĸ%+Ęmėĸ7vĸSņó?ņ9ëþ9CØɈHvž$ĸïHÂq>m@čÞÂíOŸþþĸkK.Ú�āRôõƒđ4Ž‹ĸ/mý?.$fýĸķ3üŋƒþ*”īØøœÂŋ@EfÎx“)já/Pø?�ŽāĸŠ–äŽÞð ĸŊýý?ÕĩįôûNĨΛu:§äuĪo­ëũý?BĸČzþŨÍ mēČķ‹oVá[‰øNo ^ĸ�ģāĸŠ–äŽÞð ĸŊýýĸ^m“ßK-dÉĨđ?t·ĶŅIúþĄĸßvB›íĸÐ6�ŽāĸŠ–äŽÞðÍžĸÛ|þ·-ýáâ7í+ŌÝúš7�76�ėāųߎEyþwÁĸņЧûVëÞ�ÜØ�°ĸïXĸ_ðüôéūÕš7�76�ėĀĸ;Åĸüĸ}šoĩî Ā �;ðĸŽEņĸeĸ/YŲPîÐþ#ēôö0Bß=�ŒĀóŋŠ–äŽÞð ĸĘĸģĮčė6ÄÝO#�ÐüßBŅ’ÜŅūáĸCų?���ŒþoĄhIîč ßðü���‚ĸ[(Z’;zÃ7óþÏóŋ���0<ĸÛą(Ïĸ.ø?þ���mÁĸ;Åĸüĸ��€ķāĸ‹âĸ þĸ��@[ðĸŽEņĸeĸ/YŲP.þ���―āų_ EKrGoøÖÐĸŸš ü���záWo3"æ^þŸũ†Å}ÏRž‹ĸ��@/ļĸoĄhIîč ßðü���‚ĸ[(Z’;zÃ7óþÏóŋ���0<ĸÛą(Ïĸ.ø?þ���mÁĸ;Åĸüĸ7É}‡ ØÎ-l_;ƒ�Āĸ;Åĸüĸ7Éj/ÄÐũĸÎÍÍø?€qðĸŽEņĸeĸ/YŲP.þoėeNýŋ{‡Ã‡į--É―áþĸÛ{™�üßæā€ð EKrGoø†ĸãĸöÅ^žtïÁ,ý?ī-Úl#k{Â(GĀeÁĸ--É―áþ_Õĸ­i€Ú‰Kw5[úĄĩeNþosðĀøŋ…Ē%đĢ7|3ïĸfŸĸ―_ņ7öŧŸU2V$uüŋÍ8Øáá,Ü#Ÿĸ™Āĸë>�X€į;åųßĸÏõĸū7kŸ…’ý_›―ÞpđïŋķVÝũe§đnĒwųÞĨ]$ĸŒlÄÐŊâïĶÝ­O*ŲFÂrÂ]%2ŋ7ĨŨā€ðĸŽEņĸĸŨņĸˆ4 +—ā.—ŠĪ6$bėÎYfžąČr6B~úŅíötũĩÜO7ÖŽČý3īCŋ +m‘Â"ÛČ]ˆžDäÝGęnŲ~ðĀøĮĒøĸ‚ĸøŋũ"~*ŸIęr:CüĪĪŒŨÂeÆW9ēē·3?,_…Óþó†å +ýóVðųųŪ{:sh…ÞŪæõ ĐRe·Đ2ø�`üŋcQüÁĸKV6”[îĸ·č ųÃëScIš1XÝoOoĘsS­)„Ðĸœ?LČĮÄÍuŨ%iųŨAâŸÞĸUdīSwÅ<ĸ•;ÝU")ō–š >�X ŊĸĖĨaí\üĐúý?’ŦžD6\ņðĘs]IōBĐËtÕčtTSïĸ‡ĶWqBáō/…ä)ĸüÏÍw\īũĸÓôÔ6 +w›ÂÁ� āĸŠ–äŽÞð ĸ/þþÏþŸíüō6äŊK–šr ðóĸuĮ'2ĸeý_BĸwžĨėš‘m$Ųî‘Åf·äMo9ø�`üßBŅ’ÜŅūáĸúþK—Ė’Đm”øę2ãĢąQþý?Ąķ#đÞ>―đMÄĸ#”|ĸäüĐ·ŸnĢÐƍ4™'ū"ū?Ŧu|�°�þoĄhIîč ßúĸÓŽXŸĸ­ĩžĸ͖OÉüĄŠ·ĮRqš(a^1v­FļĖČÍXÉ*c/`äûĸÐø­âG`,\ãŠŪ:‘Ð0ŦÂėęk7ÖËĸóÞ°ØüþP{™�üþ�{øþŸŽEųþŸĸĮĸM‚―L�þosðĀøĮĒøĸbÉĸCŋßûŋ;Ïéŧ +üD°— Āĸm>�X�ĸïXÔļĸĮÍvÍ-ũᛠĸ_šeŋēûyâYÞõ}-ĸ7 ö2øŋÍÁ� ðüŊ…Ē%đJEOÍöé§b=ΐáÃ7þï*ýáõšē‘ÕŒ”Ŋ"þošû°„ýz >�X�ĸ·Pī$WĢčĐ/g,ũá›Uĸ_ßÝŽ?âĸW#ļ9‰Ņ‚íÛ1šČ�ĸ·Pī$·™ĸï}x˝Øĸîĸ��ĀŒāĸŠ–äöšĸĸ_c}þĸ��€9āųߎEÍ>ĸ+1[üĸ��€Áĸ;Åĸþŋø”~ûqûþOūĸ���&�ĸïXÔŽĸß‹øð>wŽïĸqŨnŲ=ïĀũĸ��ĀLāĸ‹Zöĸ%ėÇßšęÃ73þïÆáaįžĀĸ��Ā<ĸkĄhInËĒîýĸōĒ7Ãþ_ūēĄ\ü���zĸ[(Z’;zÃ7üĸ��€†āĸŠ–äŽÞð ĸĮĸ�� !øŋ…Ē%đĢ7|3ïĸûįËŨw ü���zÁóŋ‹þWĐ.þŋāĸ���ÐüŋcQüÁĸņ���h þßą(þŋāĸøũÍ +Ó°��@üŋcQüiëĸÝ·ýqįí’XĨ‘˜ ð�€–ļÆÕ―%ļKĸïj7ĮĀĸŦ€4N›� %ÂûĸĄĄ―ą–ĸ[c”>ƒ4N›� %Üĸ;āĸ„\ž4ëŠe­iĀĸ�Z‚ĸƒ4üŋûS^Tý_Õ?ũ Ï+Tą=üð�€–ļÆÕ]āš,Ŋ~*^Ãĸ[~Iåþ—L—íWšg üßP-›<œ…›"ߔ��PŸĸ',„ķĸw?ÐÜãnĐtĸŋąm–—ÓöĸÃŧ!·hdïôÃDoúíņ;ē–[Ä&Iōڔ�� Ÿĸ āĸ‹ōˆčáõáŊ§Šë­â5áČB"F}šuxęÍÝļI‹r;9­{šüH·WC.ĸ7ü� -ø?X�ĸ/XԉĢzÍĸԇ# t_{CI*œļ'Ãĸ Ũ ĸOB(ĸ7ü� -]ü_Ē’é G‰ š.øÁĒŠUÕĸO_įõģáõųŸ*„ĘÅĸ%Häßŧ)�@šþ/üŽ†ĸŦ^sóáXĩ!ŌÆAxēŧ|ä†ĸwõĸӍ›áÉIY^—–ėiņûĸÞéy7ðOĸĸGėÞ6S�€YĐčĸqÁËXBģ\…Ëoj7_·ÕZcˆĸÛņĸĪBON-­áĸEOŨKø~*{k^›Į)�ĀŽÔōĸøîÛãËĒŦ‚Đ·#”?L %žÞŒ4Y—Ð +捞w-ž™ŊrÚŠPfž[9Rĸ7čĸ’›į üĸôĮōïĸqÏ’ģAäŒt l§��ģŌÆĸãŨâӅļWdųr$ę’tsOēâUü?OŪ„)ōVũ^$ÜĘÞm„ĸ?^}+þŋßÄņ*ŪÜšōÚs"íŗZĮýnSi‹ í=ąyœ�ĖJģûĸĄ)þŸũZø$i!ÂU>5Ŧ’qūđVÉ{ŦRļ-nøĸŒßŧ•mÔōDül§��ģĒįĸÂ{æJþïÞ{ ĩ!điú„p4’ÞđÍĪŪWRüŋ ø$Ŧ‹ĸC_ؔ��-™Õĸåæ-0é–ūü|6ázŪfFŦu·þĸo€Í °)�ZŌāûäŸciųųŸxϑŨ’ņfžŲĐŧĻĪ·W’q+ŲF·ðVÆĸŧ·4"67.dĀĶ�h‰Þũĸ ýĸķsŠnĸ OdâƒïÄÔÅšý„–ã.ÐÛI|b|zaŦ‡n#KHÝF{ðĸî-Č}ãÂ4<N�fĨËĸĸ pāýøï–Fd!æŠî{�ĀEĀĸÁøũ–���ā"āĸ`Uĸ7þ���―pŦŧÁ5Qōĸ.c8 ü���záWo3"Ūþo6ü���zðāAtŒšþo–ü���:áWw5xĸ���Ðĸ›āĸ����āĸ`“lĸ_sƒĸ��@/\ĸïŪF�+yþ?Jāĸ���Ѕžĸ% GŠĸÂþ���x(þÆ�Hĸ��€^āĸ�íÁĸANũĸ›TéūƒĀÁĸڃĸƒœŧ"öøðŅ"îįî;�\ü 9ø?ˆYýŋ{ þ�]Āĸڃĸƒübð�čþÐüäāĸƒĸ@ð€öāĸ ĸŸü�š€ĸī§šĸ/Ä°qšõ]ĸïÝ2‘îĶäčž82Îí―[&ōcŽ5ø?@{4üŋûÉōČóĸîmCyþß―mČ#Ïĸŧ· yāĸ�ĸ‡Ég{ðĸiČ۔lîAÉûä›{P†û &þÐüVðĸKĸ_ +üĸRāĸ�p +þ+øĸĨĀĸ/þ)ð�8ĸ‡üĸRāĸ—ĸŋø?�œ‚ĸà +þ)ðĸKĸ_ +ü�NđĶĸ?<<é˜nüĸĀ”[yĸŊŽd‡đϓ·_îWóĸōƒwčÃĸ€SõĸÃÉ9õ\ĸŧĖęĸŦqexŨ”[yCÏĸģ|tNŨ·d@öđ˙Ïĸũŧ™; ø?þ�qðĸōęs0ąĸ{_'%·’ĸÏ=h…ëŽĸëö•w<ü�N™ÏĸŨŨĄ›BÞûE§ũ*YĄĄ…Įg>4/\luŪæĸ‘;‡§›ÛŧáNŦ›ĒąĸĮGLē]â3ÄģälÆvČÞý*tšˆž.įtsK°|tĮïųŸn‹›ïˆŽ,MrĒķþ�§Léĸsū–_ú―%âWÉĖI]UįRþŸšc$í<ŸėŽžĸ Å,iå‹:í*ŊÉÉ!oïŠø:Âeý?īynáĖÔø?�œ2ĨĸË_G–šYl^]ü_ũ~Đd 7A|~˞ÐāóĸņËóĸÓEelĶÓēw�ááĸúŋü5þß�ü =ødąÞ)ņÅ +U341ī„Wœ‰ý?ūĨō ”ëþkíïĸņîÑ‹oÉāgXzųvĖXēdLäŊOŨ=īđ%X>š…þÏóŽāĸ�p +þYŽwŠdQōšûëHü‚Ē}đ™ÞĸC+uæøÆÅĸãxęĸÂezg.ŲŽÞŪēý?ĐųBĸ— ݕýŋÖ Ëũ·îāĸ�pĘý?tÃMrՎ/6ĩŸƒ]äđM-.ëĸ§;‰pg‹ĸĘü?c�•ü?{;žî0%·&ðÉČK~,Ü(ō)FĀĸā”AýĸöÚõņAü·ÝÛî’š~Z+^b?›Ðę#KMQâRþØøts“$ÍŠÏĸzĘÓ‹o—ČĒ$)ĄŨĄ}@ūCë?5ÅĮät öóHÎSúhgŧ=>xåŨˆČą.įälð�8e\ĸŸ#Ũ‘Yýžðĸĸ^Šųü"āĸ�p +þßïŒgë&þ)ðĸKĸ_ +ü�NÁĸaĸŋøĸĨĀĸ/þ�§āĸ°‚ĸ_ +üĸRāĸ—ĸ€SðXÁĸ/þ)ðĸKĸĀ)Jþ?ĸĀpdûũÎ!ƒlĸïÞ9díĸÝ;‡ ð�ˆSÝĸˆ‘#Õĸ{ũKEŠĸũî—( +N旊îVĸXæĄķĸÃÄ w[ äða�čþÐüäāĸƒĸ@ð€öāĸ ĸŸü�š€ĸīĸ9øĸÄāĸ�Ðü =ø?ČđûĸBĖÝw0�ļ ø?@{ð���čþÐü���zĸīĸ��€^āĸ�íÁĸ�� ø?\­ĸę ‚ ÂFāĸ�{î;ö§~ųSyžð‰þ}Jü‡Ąâ…ŅâĢCÅĮF‹Ÿ*^-^*^-^*>9TüG…xï{ßÛũ‹ÂN#õģø?\Õĸï&ŸÁûūó}wOþîp|N|ŊN|ŸZ|ŋNü€Nü Nž_'~H-~X'~D'> ?Š?Ķ?Ūԉéćuâ'tâ'Õâ§tâ§uâgtâguâįvņÜsÏ-ŧOíduxü`ÏÞĸï>/ų#ÚÁĸĮ5óąī3QË1sU3WŌrĖ\ÕĖ•ī3wÍžbü|86ĸĸŪ”øôþZĨāĸ�.‡ûĸōOþŽþĸ /`æJZŽ™ŦšųXZŽ™Ļå˜ųˆZ>“™—Ä/ˆãųįŸßü_øœŧ–·LÁĸ\ +ïĸôĢõšö“WĢÜĖŨåäiųš{-_W3ooæJZŽ™Ŧšđ’–cæŠf>––[0óĪøÅÜ8øŋ䑟uÎf)ø?€KáýĸŧĸįyŧÐīS~ŊÓknw3DE_W3o`æci9f>Ē–cæŠfŪĪåÍ<ĸ RžųÍoÆĸ†ĢðþĸĮ>öąīÔ=OžOÞū™ïCOËŨÂĖ2s%-ĮĖUÍ\IË1sU3KË+šų!þĄNžå-oĐ"ó!åĨÜ_lŋÝâ>eýØ?þ§ðþĸÝĸ―Ōūšųá)ÛgTķwîoÓ){3ßßņÞį†n‰{įqÍ|›įāØÞé۔Ëmķ―™^t}ßÞaĒ›ē‰ô“ĮáÞ]Ë1óĩ3QË1sU3WŌr=3ĸG:ņKĢ—ĸo){ųßĸˆĸD(žĸĸņüpÃÜÕrŨĀŊ#YŪ`‡Ü۝Í}―ŸĮ{ŧû Ó!wįßŋÞôû âÞŨûyBŊïqWčýë5Bŋrģk9fŪjæJZŽ™ŦšųXZŽ™ĻåŪ™ŨŠ·ūõ­―üïüųĮĸâÞĸŋbÞûäîëÓÓâ-|íĘüþuüîũaŊ{ýü`ãŊũąN_-zĸúðĢüWãj9f>Ē–cæŠfŪĪå˜đŠ™+iųЙgĮ?I‰ŠþïÎyęĸû7Ą*ø?€Káýĸû!RîSQũzõ’ãÞÜÃăW‡ŽûTČOýžäõöãŦWï_~Œüjûqī3W5óąī3QË1s;Zžĸī Þöķ· áĸIĸÃôÞĸņÅÝ[čnD„<é&ų~šûQ–­\ä6øaũWĄé§žũzÕiÉkáŊö.―­ėÕī3W5s%-ĮĖUÍ\IË1sU3/ŅōHüģŠŅŨĸåŸĸ)ųŋƒŧŦ@u +ïĸßý?~ ="äĄ_Ķ„|!ŲÍãūu’„Ÿūބ|/įōŨĄ_­"―þč +vhz/3WŌrĖ\ÕĖĮŌrĖ|D-ĮĖ5Ė|‹ŪųČGÞþö·Ũz˜7ÕĸÎøĸˆPxĸĸĨ—^r}>äÕņv]ÝÕûýkŊoS։q wį Ý0‰·DČ·ŨŪĮ_ïÃkï돛Ko?nYûéû_u4óąī3W5s%-ĮĖUÍ\IË1sU3ĸˆNü _žãïĻøe>ō”ÔïĸÄĸöÞĸŋûÄĖÓ3xÜÏéúķwĘÁÛCsšvíÐ<ÞéŪŦĖ\ø:$íë‹ÍĨ?î§xįtįŨĖĮŌrĖ|D-ĮĖGÔrĖ<bæåņ/áõĸxtųĸŋîĸæĸÔÞĸųå—ãŸO +ÉįRNލüOŦôļaŽ™Ŧšđ’–cæŠfŪĪå˜đŠ™ĨåSšyFüŦôxį;ß9„ĸ—DwUĻNáýĸW^y%IÅ ÍüpÏžą™+i9fŪjæci9f>Ē–cæŠfŪĪåW0sIüëâØûĸjݒh™Â=|�—ÂûĸwĸovÏ<ōī3Ũ6s%-ĮĖUÍ\IË1sU3KË-›đ7þMíxŨŧÞĩjö]˗”h–‚ĸļü?‰ŧĸō“ŸėrÏ|,3KË1óĩ3QË1sU3WŌōĖ|Ŧĸîĩxũŧß―jķYð�—ƒĸߕ>‰ũžį=o|o*ž*ž-Þ<TžeīxëPņķĄâíĢÅ;†Šwï-ÞÝ<VĮķþáāĸ…ÏČAAtü Âý Øĸåîþãíö��� +þĸ��€™Āĸâāĸ���0ø?@ü���fĸˆƒĸ��ĀLāĸ�qð���˜ ü þ���3ĸÄÁĸ��`&ð€8ø?���Ėþĸ��€™Āĸâāĸ���0ø?@œ ĸ_æ Þþ���Œþ'ÏĸŧÚzgŒî=���@ ø?@üãýïĸ0þ��0:ø?@üĸ��˜�ü þŋĸ��L�þ§Ŋĸ?<<éū„ ü��`ð€8Úþũó=îo‹qü���^ĸˆÓĀĸ#?šĸ��˜�ü Ncĸ?L9ž>ü`}―Ÿčþát Þŋ;xÁĸ��&�ĸˆcÄĸ―Š2áRĸրĸ��L�þĮļĸË_ãĸ���pÃĸÎ0âĸ7Ág{ō– €ĸ��L�þĮŽĸĮ+y-Ÿâĸ��˜�ü NßïĸÁĸ�� .ø?@#ßĸï!õóĸ%_þsÃĸ��Ķ�ĸˆÓũĸĸ5þБ‚ ‚ļLāĸFĀĸ:r?ú>õ˟Ęã…Ožðïņ,Å –âĢ–âc–âã–â–âEKņ’ĨxŲRžb)>i)þcqžũ―ï]rcõmüßø?@GVĸŋ›|ïûÎũݍúŧ}ņ=•â{kÄũUŠïŊ?P)~°FžŋRüPøáJņ#5â•âGkďՈŊŽŠŪ?Q)~ēFüTĨøéņ3•âgkÄÏ―Ï=ũÜޟ“°ð™4üĸčČÞĸï>/ųãéÁĸëšz-]ĮÕqõq]―–ŪWqõZš^ÅÕkézWŊĨëU\―–ŪWqõ―Ū—ÄÏûbóĸïJ‰OĸílpĸŋÛō|āĸ�―8Üĸ—ōgõĸ^xÁˆŦŨŌõ*Ū^KŨŦļz-]Ŋâęĩt―ŠŦŨŌõ*Ū^KŨŦļz-]Ŋâęĩt―ŠŦŨŌõ*Ū^KŨŦļzHŨSãÎâųįŸßü_øąŸŧüŊ)ƒú―G,Fw ļ&eũĸ?úŅzUüÉŦaóÖúÚ[W=W_—ßLŨŦļz-]Ŋâęĩt―ŠŦŨŌõ*Ū^KŨŦļz-]Ŋâęĩt―ŠŦŨŌõ*Ū.ŅuIübJü_ōÔĖ:įļþ�P‡ēûĸwĸũjųŠĐÚ·ÖŨ*BK?üXũÖš\Ë ]}-ŨõužūŪ^KŨŦļz-]Ŋâęĩt―ŠŦŨŌõ*Ū^KŨqu;Ū‰o~ó›ņ�€B +ïĸėc Ý`Ęđ0žî-4ųmķl??Õõļ–Wžĩîš―+Þë<ļ:Ū~WŊĨëU\―–ŪWqõZšžíę‡ø‡5â-oyËÁĸï/îĶƒóߧŽûĮĸ�\ +ïĸßýß{ŋ}oŊ‡ŧŸ“quPnwúá#7îDïl^WßĸÖUúí·IZūMÜĸj/į‡{cwį9üjSî} wŠwb]]Ŋâęĩt―ŠŦŨŌõ*Ū^KŨŦļz-]Ŋâęĩt―ŠŦŨŌõ*Ū^KŨŦļú=þQøĨ]ļþŋÚþþ-ĀáGü�ā@áýĸüãûÁüðãOÂė_~ĸzĸĢŨÆŋ +Ýuß~<ųþuäGïô'E?―åūMŲôû âÞŨĄy6ßÞĸ(yíý•WŊĨëU\―–ŪWqõZš^ÅÕkézWŊĨëU\―–ŪWqõZš^ÅÕšžĸ8o}ë[―ŸĸŲœĸ ĸø?�€KáýĸûĐ5ōI‰ŪŸ*šðW!?ČųéŊö~ļÓúčËá·Ēąôý!Ėģþļ*ũþ5·Öíļz-]Ŋâęĩt―ŠŦŨŌõ*Ū^KŨŦļz-]Ŋâę]OŠ"ˆĸoæï~h,ĸïþœ�p +ïĸßO­ņÁxu―\Ņ―†‰úÅëę{ë–ßEwÃÕō'NÄE=bé§ŋÚb?qSn·n­ãęļ:ŪÞĀÕ%ņOãmo{Ûôþ/ü^S‚ ˆė(žĸĸâ‹/šwÝÝp?ãõðÓ_Ĩ~Ð%2[äVųéŊ܏Áī<r§=$ęĄŨ‘_đŊWßÞŋvÄÕ;ęzWŊĨëU\―–ŪWqõZš^ÅÕkézWŊĨëĐŪŠV!ĸŸæó?ø?A ĒðþĸÝĸó>“ý‘õ {?Ļļkāō_…n•ŧŋ ÍuĄĀŧŊWå―vTŌõ*Ū^KŨŦļz-]Ŋâęĩt―ŠŦŨŌõ*Ū^KŨŦļz-]Ŋâęĩt―ÄÕũņÏkÄG>ō‘·ŋýíËÔÏĸâĸA4ˆÂûĸ/―ôRä30O5yWË#ÓÝÃ<qî“oĸ>ņÝ]M—ÜEwŧõ uũõúĢWæWåvŨw?}}ąŸmĸ+;Ū^KŨŦļz-]Ŋâęĩt―ŠŦŨŌõ*Ū^KŨŦļz-]Ŋâęĩt―ŠŦŊš^ĸâqžãïXĶþþOüŸ ˆQxĸĸîĸÛ'ar.·ũÐGÖÝÛæOœ;ęÞÄ―uŸÞ]?ļúö1Ŋx‡nĄ{ëšųÞĀO_oąWîÔý<û_…fŧ‡WŊĨëU\―–ŪWqõZš^ÅÕkézWŊĨëļzKWώŨĸOĸ'"ąn‚ļZÞĸųå—C‰‘„ðCé§ųp‹<Š| ĶĘ­õ*ĒŽŦãęļzE]Ŋâęĩt―ŠŦŨŌõˆŦ'Åŋ’Å;ßųÎåŠþ_ÅTÕ]·íøŠŽŋ•Žė6Ïþ>įaoõŽ#ĐTZļRōu?ĖéÞO–ĪK6―p‘Bō9ĩŨ=2gáxš…JîĸŋōĘ+wõŸVøĖęĸ]―–ŪWqõZš^ÅÕkézWŊĨëU\―–ŪWqõZš^ÅÕkézWŊĨëBW?{ĸ_Ý^ËāþŸ}‰ũ.Šp ]B"îoOWöa'ĸņéï’ô u…+%_ũÓ9……Ü額•Â%4[ũøĒjí~eũĸïþßLŨŦļz-]ŊtgÝŊëŦĸ7võZš^ÅÕkézWŊĨëU\―–ŪWqõZš^ÅÕkézWŊĨëU\―–Ūgļš7þMYžë]ïZ^õįŧü']ėÆõĸÃåūüĒ_’n'øŋ|bãPõų<‘OG)[þã…ōÂÔš{į”ėŠĐqðĸ$îþĸÉO~rŽ[ëÕ]=#ėļz-]Ŋâęĩt―ŠŦŨŌõ*Ū^KŨŦļz-]Ŋâęĩt―ŠŦŨŌõ*Ū^KŨ ]}[)þÝŦņîwŋ{ŲųsÓûĸ6Ãáé~Ę~i‡9―éĄeĘCžî6y˜îv_ÍxuÉH +'&…·yáœÞu/ÜFû…$Íüøœ’Zņuã‹:-$ÜĩÖ]Þsd5[<oŧ?<öĸŧŌ'ņžũžįŧx“ĨxÎR<o)Þl)Þb)Þj&Þf)Þn)Þa)Þi)Þe)Þ­ŦÉËÝĸ—€yzgsÁ•ļNH&Ę#)}ß[ŠD…VóTĒBm„æOUYyÛō9Ý_•oĢB>íÐ-wZ(4gh/Íp`o·’yōÖ]Xk‘―§(ßũþĸ@AÅþïú@hž<IˆĖ)Iw›ÜZMM—ŨÏ YHĻ™‡zŌåH|-⋠+eUiIŌ‰ž|Ŋ‹4)YZŌZXXwųßÏ_8ž‘%GÎE���ƒ2ĸ‡L Õ +ör+qõ*ö’4sĸ?•ĸŒe +ãôMÁéœå=xkĨÎĢęĸÂŦ EģuÏÛ[„Õņ��€• üoėņŦžÜĸ 'Ęc,ĸ/\Ķ$44ŌˆĸW|ë4œĸ [Ę.Ī·+âĸ��0øĸA?æówþýjzíK~ûԛ_N<ęúĸé.‘ÝØéln{§Ģ]Ëęõü?ž^ēîņ…KÖ(u<Oĸ�€Y™Āĸ—`ý$”~‡ÃbøĸáĩÛį~Wûũmoĸ†ôĖÍõΚ_ūj‘Zysî§dwrX |NïĖ’QŠŊŽwk†&>øöá*ČWJ8›pÝ#Ë<]ũÐ2ģŨýĸ�€Iy˜Âĸãþ@$Ãh3Ūž]šŽ;þ��ģ2“ĸUâʞI[āĸ��0+ø?A„ø?��Ė +þOáþ��ģ‚ĸĮ@øa˜øc˜ņ…xg“?áØ8"in/ÜuOęᎡvđ6+8_!Sĸ�ĀŽāĸņŦĸ"ÐÅÓ9#KðŠiČWå-)EČ#~šŋrgŅhéĸÍķŅ|…Žþ��ģ‚ĸG.ý’OÝōôæŋûcŌ›‚fám#2=iĒjļ[Ņ+ų‘BcÅþ?ĀčÜO5œF :øöĨßûãá,ōw +I…Nïųwü€wŠðO—ķņû… Æ(þß{œ‚(Šũðĸbš8ÝĐð_<Ôļĸŋß +’B‡™Ý#-5‹PîtwÝ%ĒßĄč5ÐlÍWČ`œž‹,ÐÝ� îGņęĸ]O·DåļoÖĸÏ +đöHæ<} °YąëĻÁŽ,S/„þš?>ģRšœĀ–į+d0ð�h@ũĢĸŸ/nønīôwNï2˜XčOCøĸâüUEŊû#…Æ +üä<<<i–e–ÉV§ݏbüūļáĸđQøųŸÂ·ųĸ!ÜÆ,4ĸÛ/d0õĸƒƒ•(Ų=wĢŲ™uČxcÃų•Ōwķ+ƒĸÕã†ĸDäƒ7‡LýŽÎé-ôÓÏØt<TOïóũíęÍķŅ|…ŽE†ĸï…đ9kû•åd5…Fc“ų?ž:&'áĶDüŋĘ)å4ĸŸ/nøY„îŧÝ9wÅÝé‘)§éyŦS‡“˜û[ïœņ‰mĒĨĸ/ ·Ņ|…LÅéđĻä‚[‹öþŋūØ{ˆWKBģæ9Lt%§Ī‡øŠČ;wó6YĩHņŅðŽÛé�VYoÝCVd5åÍĖG’üßdũĸkČĄ.x†Ÿ;nøŋÉā@#ûQŅĸãú'cĄ94ðđÍz_KÆĪJ§ ‘t~:Ī‡Ón%ŦYf|iĐŦ#[áÆ:mf>äōËõĸøYÂ}+·Ŋį6€–L7üŸ "+ÚøŋPŒåþ/ÉĘX‹Č=ÞėŨ’Jz/Ī|-âcž7yō_ļšŲë%Ų@ÂĒs ”ĸ[–ĸWŲĨũ āĸ“Å ĸ'‚ČŠfũĸ…qđ9Tôĸø=ÆÃ<-Yþéz…zp—ŠnÁĸÝf:úŋ°ü?ŽDþoõü{™9Ô�þ?YÜð‚ ˆŽĻûųĸÓëōޑNm6ný?ÉCä~"™A˜+\MŊĸįuŲū’A“F/ĸ—7ƒĸŸ"9oäųč,qšoxĀĸ'‹þ_ōĮ#sĘŦmNũsƒîtá2Ŧ‡[:ÔRhNÅæņÐöųß6%žĸUŽŽþ//2É{‡ŒĩŪ‚äuŠ‹FîE ­ēVį‘í{úۇĀß2öá{ZþšÖ…úĘÞĸw§sĸŸļáĸą·îė9+ūƒh/ąÞN„mDælßyãĄkcËÍÆģã†ëuýß;ą\ŧûĸV+ÏŪ·Dwšûcd4ž=ÔíÜÛI|ÎøZœŽÆéŒT)_ČĶ U -_ŌĖ•áóĸDõļáĸđ7Æý§ŋ’V‘9CöÕËĒ#ë.Ÿģqó-ŦË7zy•Ð#2mü?Ī ĄÅæ��–QýþŸýĖÞåÜðĸã†ĸįFÜęŸÉ‰ĖéÎ)ũátíøĸéœû›øƒ(ņÉå;4ąš9�€ešÅøĸ|qÃĸsĢüþ­IÚkÞ78ÞOžØņĸ%esÔ-ŨfųøŋFTôĸÐGSð�č~ãĸóÅ ĸÏ đö\Üĸ“> +úąAāĸÆ Œšũĸg5�(ĪûQŒĸÏ7ü?7 +ý_õC2}SyÃøģåãĸĸ@šÅøĸ|qÃĸsĢÐlœˆ +ÍéÍę~ęĸ‹óŨ +íZ-—ĸkÄ(þ�Ģģðĸîg3ĻËéN…ĸĮŊþ‹OBĒ.4vɍ}›ōŋäúĸr6J b&ĸ_Žgũ Ũ+†ðĸރDDčxiĶUDãĀĸģ#dŒ^Ĩ~\'ōļĸËĸĶ ÞęĄŋ\DĶ7nŧqõ–ÛĻŲxöÝp―bĸ��Č�ĸoT)‚.ð��˜üŸ  ü��fĸ'‚pĸ�€YÁĸ ‚ ÜĀĸ�`Vðĸļ�?Ŧ�6ūÓGh3–ЁĮ™ã͇&ķ ·gírmÖqūBĶĸ�€YÁĸãWĸE ‹îœrYōŠĐÄWŧø˜Ŧô‡ß&Ml-Ŧgėēø?��Ė +þđôK~”čnjĄS_í%ĸKúšņĸHÛu E~ĪÐXĸ�ĀŽāĸ‘KŋũĮÇXBš›ũqá­þŽŊ`‡úÄĸ)d?ð��˜ü?ré—üXņv·}ųũVũūĮ‰žņißĸaĢL`Ëó2ø?��Ė +þđô‡~LsbĸÏļĸßËĸį€^!ï+ð��˜ü?réý˜:§Äš†ĸ%āųûå:iîĮ·rĪÐX1·ĸßOĪ�åtߓ‡ ûf‚iĻļ[âĸ‘KŋäĮ*Ÿĸ‘ŋkč.`%ëÞŦyüß~!ƒ1―ĸ?DYÜwŨōNž8nD•Ļ{Ä=āĸŅŦĸâS mC„ætSä?ĶNlÞßĸZŧŽÍKžz-íõŊĩ8= Í*$―Į˜8žâąN™ė`áp#,Dõ#ĸÄÁóũÓOį<žes§ŧģmÓ――u[FĻ%ï"Éjķė<ōĢFđ6+8_!Sqz.„„(Œę621nDyT?âðĸæÁy€ ėþO‘pmdûqÝŧšïävāp#ĘĢú‡ĸAļŅĀĸž $Ä q°‘åą™…Dx”)‘%ÜĩýöīPh†x"‡QUŽļĮ;-þOqŒ<ĸ_]boÕ]Ē +^!YÛî1ØÄxą7ÅũĒDHŧzčðŅóĸÔBýŸÃHŠ*GÜãĸ'‚8F†ĸ§ZŠ)ĸßT'!$áڈû]…IþQņfþŊī7Ē<ŠqwZü?ōĮ#ĀÆâS>ąe„J Ũ―oį‘TÔŦ2Y!Sqz.ĘsũõánįáhRî>=ÞÕAH‚“§ąIČōÚˆnȅ$îÏō―=2ģwą‡%xÄHŸņ%pļĢîwÃĸÃąŨÔ9ģeiSýH•.RčÓUöŪQãui\―-—ïlÖ +Y‹<ĸũ^ý#ž\ïĖ Ą·Š_õęĸÂ―=rXIę–n„jÔ=ânø âÆxļÝíþ*ϔâĒeÐĸO―:īFûɐZ%ô㈅ F†ĸoî!ü$CõŨōL $DaÔĩÉýĸȜ’ÃDR·Üĸ9ÜĨĻ{ÄÝðĸ@ąƒ7$ÆûH-ęMÏ[ĶRĪúŋpšRī—Xü‚ČóĸMjđýöĢä=ÅþÓ Ą·ĮŸFðÎSũó?ÞŨņž•øŌÂ9ÜíĻ{ÄÝðĸ@Ô―ĸ/ą&e*…ðŪūų?mSĸŸ Jü_č þ/l!! +ãVõÛH2üŋ\Ë#‡U(ĸ'zEÝ#î†ĸBŪ=’9Sý_ō+ü?)ðã… ††ĸgßKŒO‰‘äÉËNB°B +6’öĐđfþ/é„ÍÐ…#ĸũDcĸÏ`ĘĸOĸNáýÕétíĀĸ2þųėÍ6ņôÓ ŪQxĨ"”ĸÄBDH^]eūœÆ­öĸFßŦCŊÝ#ŦŠĸ{%ïü‘ęnDÅĻ~ÄáĸÞhüųI9 &–=,‘‰ÍâáÕhVŦåōņ(žĸ_ŊQČ?ęã…ĸ”( Ũ@ķóäb8܈ōĻ~ÄáĸĄˆ|Ęå`’îœIŒņÝ°čĸqĨ7.ĸË\þŋ„wķq Y #þïýëĀ ĸ'z‡k#·Ý7“w9XĖÂáF”Gõ#ĸDČ―Æz› ûpšZfƒxpâðŦÃĖōôfŅĶnËÕl6’―6Yß0âĸ a3B6ÂÍ7B#Šqøûā<@öĸ'ˆHxmäÆÍ7B'Šqø?A„WðĸîmĀÐ,Uĸ7Ē‰ápƒ*Ô=âð‚ 7ĶũĸÞLĖÝũä!āp#jEÅÝĸ'‚pcnĸ�€+ƒĸĮ@ø™=ïœĐnszŸ–íþ­[:ĢÏ.ŸlÜCģ­3_!Sĸ�ĀŽāĸņŦĸ"ÐEïœĐūQŽÍŦ“X7$ +}:ą—FķôųnC!ãĸ�ĀŽāĸ‘KŋäGïŊ2ä?”eÄūNZ"ĸĄŲīãðūCŊ‡fo4æ+d0ð��˜ü?réũþč~ƝSÉĸCŠiUþÐ,ðû… þ��ģ‚ĸG.ý’#þ/tõČþÓB]ÂíÄ]ÍКũōĸ%:Îu …~ĪÐXĸ�ĀŽāĸ‘KčĮÓ9“n8 ý_þ+í•–Üðïčĸ‹óF@ŊũG +ø?��Ė +þđô‡~<3/=Éĩz™Xę[ yä lyūBĸ�€YÁĸ#—~ɏåþˆŒš…Ī%ãmãĸ6  ü��fĸ_ýŸ…D=’ųŅ;ýôģ@íMLؒqĸŨî!īPhļĀĸ�`Vðĸļ�H>ÓâÓ{Kņ―}ð.64C$]5B§ýå">ąqĸßƒ4[Áų +™ +üß=ũ@EJŽĮÞ'Č+†{čÝQ,NŊYøûļ JÄpĸŧį^ũ>�Ayq?―x­^îĸÝÏ WãÁįĸÝŧ’wë΀ĸAâô\t5Vĸï―Yb†ļųÔq"<Õļé Ęze+xŧ=€ĸAļĸ{/(―7 AĖ7ü4ðüŸ ˆ+þï― ôÞ,1CÜuÜ~”˜››Úāĸ—ōĸíCzysî?æwšëÎJïu vûô~ qĸŦÐÚ5ýZÝȏ *ęU™ŽĐČðĸ‡‡'Š§ôČōïŋÚ~{ÚFh†x"þOĩâöX—Į)‘·ElžÚįĨ’óXÞđĻ …þ_ūFIKĀĸKbođsĘß8$íebÞ>#MšYÍĄąĸ·ŲFōýs”BÖĒÐĸįę*—3áĩēĨĸŊï;zl‚8n;u\|yęonÖz0îoT<ųTdVĸߏŋÛ?þ?ŠĸĮ1Ēĩq1Š{ĩqĸ/héĸmÖ·ŲĩĸӉ(ũÉeŪĘų?uáĩü3ÞDRÜĸwŋ4Éĸ#ÎoÍĨ-ũAâĸ‘-bĄ[gCāĸžˆ ĸþoKĸũĶt‰­Ï}ėåÎŲūÉCĄTÔ^>þŊþ8ų‡.sņŨ‡OōHnæî8đoCâĶø”Ýø<y<\ž ilęļžöĖŊq…[Âæéž"ž'“ČÉ!2óééEX"ÞyüÄxš‚Ŧ–ęĸ‘5õ–óŪBdiņ†ņĸėĻrĸĸ Ƨ…ķ™ãéÝ,IõSD)B=k—kģ|ü_#ĘýÆúŋũä/y āý1ï HĻ"þOĩâVüčč’âĸîĄ-< ÏÞRÏ?‘ÜøĐI~ģĨdÕjųĸé*„Ö7ēw +þŸrí énä=‚ŧŊųg4Ó&B Äý_> ĸ/d0jųĸá@áëH-áU,ŧþOĩâÖÖĸãs&ݐûR‰’ų#Õ+Ūšķĸįõš‚ĸgGđĸ Ó―K“ĸõĄ}œEÝĐøŋņBĢŠĸo/zųĸCāOÛ…ð‚Ļ·ĮŸĸņÎSũó?ÞŨ“ChĒw ‡Ōōó°įÓ ŌŠUĸüOęúž.a?ĸÏđęnFzG“4fÓĸįoÚĩZ.ĸŨˆZþŧÜĸO―ÖļāĸQ+nUŋĸ'Ãĸón8?œ}'õ<ĢáĸJŦVŅĸóÆGrÛ?þnřĸũGčŽņþã:Ą9óÞ>dĪ· ·nĻąÔi3ųĸÛq Y‹þ_åķ|äō—z”\þßĸC9qŦýýŸĐœ}Ãųt Ћ•œ?å…ôV­ðûðĸü ĢŨ„Co$o„é#{―2âÁ‰HŸKʀ4‹6Ĩ[nĢfƒŲqŦuŒÓsŅŲĐõäZpļâĪ^ōä—?ï_ŠãÍýĸÕQâûĸ "9ęļ<–ųžĸĸë!ðiœļũZ―[ÎÛRR‰Ô“ĄWƒŦŊZ­ïĸOÝF’%ŧuZÂĸ[ĮUŠ †‹BĸŸþĸ_‚Ļ7Gā·%ææĶ7ãôvÄļÄW­ðĸĸm þO‘øŋũ‚Ō{ģÄ qóĐãōÚĸ 9ÝtUNoõ‹pÕðüŸ ˆ+þï― ôÞ,1CÜþ/žųïMUðĸŅý?ô9v‚ ˆ}āĸÞ JïÍB3Ä- ŽōóŒ7ôĀĸ-ûŋäÚä>”Zv1gāĸ�ēÔøĸŋîG%4#äĸÝv{`ĸ—ßÏĮĸ ‚þ/9ũ‘%ĮĢûaĒAŒĩĶũĸ‡ĮßOþUúüŸ Aœž‹���ĸŊį AĖø?��ĖĘþŋČĖ?gčG‚ ˆ5ð��˜•9ü ü/šĄkzčG‚ ˆ5ð��˜•iüáó?AÔ ü��feĸįóĸATü��fĸŊį AĖø?��ĖĘþŋðýĸAÔü��feĸß_Ŋ%ŨôĪ‚ .ø?��ĖĘLþ/žĶĒŠ*1Yāĸ��0+Wó‚ Iļį"‚ ‚˜&ð‚ ˆCÎE���S‚ĸAŽĸ�ĀĀĸ ‚ ÖĀĸ�ā +āĸAkŽŸžŸ��æĸ'‚X|ßFAģþOAą*Įw}Ũw}āø„,î3ßSŒŨ"€5ð‚ ‚ ,þÐüŸ ‚  ĸīĸ'‚ ÂBāĸ�mĀĸ ‚ ‚°ø?@ð‚ ‚ ,þÐüŸ ‚  ĸīĸ'‚ ÂBāĸ�mĀĸ ‚ ‚°ø?@ð‚ ‚ ,þÐüŸ ‚  ĸīáâþĸ@AA4Œîö —ũĸOýō§ōxá/üûôøãĮ SÄGĮŸ"„w)-Į‹ãĮKSÄËãĮ+ãĮ'§ˆĸĻï}ï{ģ―kUÍîö øĸjōžï;ßw—áïŽÆũčĮũ*ĮũéĮũëĮčĮ*Įûõã‡ô㇕ãGôãúņĢĘņcúņãúņAåø~|X?~B9~R?~J?~Z9~F?~V?~nÏ=ũÜēSĮ$ø8–ðĸÍĸï>/ųĢÕÁĸ[Šø6>Š7°ņ T|ŨVņ9l\[Åį°qmŸÃÆĩU|ĸ9ýøųhlþĸ])ņé?5âĸfĀĸũũĸåŸüYýĸ…^ZÅį°qmŸÃÆ'Pņ6>ŠÏaãÚ*>‡kŦø6Ū­âlž<~!1žþųå5ĸęÖ]þŨüßøÉýĸ~ôĢ^Đ~ōj”ÛøšœT|ŨVņ9l\[Åį°ņ TžO âsØļķŠÏaãÚ*žaãņ‹eqðÉCFëœøŋðĸ’ûĸwĸũjķÐÛO]z]ŽeŨVņ9l\[Åį°qmŸÃÆĩU|Ÿ@ÅØø*>‡Šļ$þAíxó›ßžāĸƒƒĸ—ÜĸĸØĮ>’vWÝ3ėz]ČĨl\[Åį°qmŸÃÆĩU|ŨVņ9l\[Åį°ņ T|P?Ä?ԏ·žå-Ëcĸŋŋļ ŌÁųïS֏ýãĸÁĸKîĸßýß+íŦŠß_ėÍy•ųí…ũ·‡é‡”ÐüûX-ڝrYŨVņ9l\[Åį°qmŸÃÆĩU|ŨVņ9l|o`ãĸH?~É ŨĸWÛßŋ8üˆĸ[ĸ/đĸĸņüpcܕðÍĨũBîÕõČëõÅ^›#SöŋrgëĻâ l|ŸÃÆĩU|ŨVņ9l\[Åį°qmŸÃÆĩUž—Ũ,ˆ·ūõ­‹ïó?›óäĸ7þ_rĸĸūK:âÞņÝéw[^_Ŋæzĸ­;g3ŸÃÆ'Pņ6>ŠÏaãÚ*>‡kŦø6Ū­âsØļķŠ mž0þIz„ü3ũģ@øŋ5ðĸ’ûĸũ]:$á§*îýq‹ÕŸ%ŊC?šK]Åį°qmŸÃÆ'Pņ6>ŠÏaãÚ*>‡kŦø6žĄâĐņOkÄÛÞöķĸüŋäþĸ‹/ūļŋÝíŠwHÚïķžþļšģäõúãáEhķ{L`ãÚ*>‡kŦø6Ū­âsØø*>‡kŦø6Ū­âŲx$þ™N„üŸÏĸ þ_rĸĸîĸßOđÛōAËũ?J^o?z'îĩŲ‚·Qņ9l\[Åį°qmŸÃÆ'Pņ6>ŠÏaãÚ*ŪgãûøįĘņ‘WãíoûÂóŋƒƒĸ—ÜĸéĨ—ž>ïĩņƒ–ïtĸd2ųmĘ*Ė돋ޚÁ‚ŠÏaãÚ*>‡kŦø6Ū­âsØļķŠÏaãĻxŸ@Å7Wá‹wžã ßĸ98øÉýĸŧĸĮU|?ý0ƒũĮÜۋ͙Ũ)‡ũáNŋˆŠÏaãÚ*>‡kŦø6Ū­âsØļķŠÏaãÚ*>‡ũRņšņ/eáúĸiāĸÖĀĸKîĸŋüōËuo‰ŸÚøŠôöm|o`ãĻø6Ū­âsØļķŠÏaãÚ*>‡kŦø6.Tņ’øWđņÎwūsÁĸĸ/đĸĸĘ+ŊīTņUþŊiãÚ*>‡O âsØļķŠÏaãÚ*>‡kŦø6Ū­âÆm\ĸš^ėýu{I,øŋ%ðĸ’ûĸwĸofãÛįyšŦø6Ū­âsØø*ÞĀÆ'Pņ9l\[Åį°qmŸÃÆĩUžŪ‡âßĻÅŧÞõŪåUužË’táĸvĀĸũþŸÄÝĸ?ųÉO^ÁÆĩU|ŨVņ9l\[Åį°ņ TžO âsØļķŠÏaãz*ūÅŋՏũZžûÝï^vę˜þoüïĸwĨOâ=ïyÏĮ›ĶˆįƏįĮ7Oo?Þ:~žmŠxûøņŽņãSÄŧƏwũŽÕäåāĸÖĀĸũþ/ųü?AA!üß—ũĸ%šú���� þoüÁĸ���tĀĸ ‚ĸ/ø?���€øŋAðĸĸ���Ðĸ7þŋāĸ����:āĸÁĸü���@üß øĸ‚ĸ���č€ĸĸ_ð����ðƒāĸ þ��� þoüÁĸ���tĀĸ ‚ĸ/ø?���€øŋAðĸĸ���Ðĸ7þŋāĸ����:āĸÁĸü���@üß øĸ‚ĸ���č€ĸĸ_ +üŋĪnũãq,îû!LIũ]Ë2Ý·(qØÐs\Gš  þoü)óĸėcĄûņ8ũýð˜.ē ‹Ān?eļŧ}ށð`ė:Ēīŧz‡SĮX<āĸöxĀĸ›ûĸz’ė~<ŽÅ:h―ũĒfdAŨÝ~ūðîöîáūŅ}ÕÞ]#Ãemõ!þoüÁĸG�š/ē ëĀn?_xw{wŠpßčū‹jïŪ‘áēķúĸ7þŋāĸ#€ÍŲGÐu`·Ÿ/žŧ―;EļotßEĩwWwpķ Ž�„Āĸ ‚ĸ/Ũóĸ‡‡'ŲŋÕčDRš/ē ž―—Ýž°ÞÝޝ"Ü7ŠĩīþĻîS‚ĸĸ_,ųĸýĪšąŸ˜~ŽeZP^đ‚sÂaŅ*W–u`SgØo”HVh†Œ^$BGÐ~|RũÆÐüėöI36AhĮý6o ïnïN9ĨÁu$õxņîŪ…›{?8ÞQūp>L‰ÏÐōü0%øŋAðĸEÓĸ―:_eŦKRĘeEhŧE4ޝÁ՘P–7Ũ+Bņ^'BGPɈĸ"o·Íšâ=d"ĮŅ•ÃŧÛŧSnËĮaßčĩ' ý_ēwɇk}á~;ĻÐĸ>ĸ·ĸ7þŋčøäԝtÞvïä„nėl#ũNÝ3^ü4™Á;Ý{Žõķđ=%ŋģ”ēĄýšš<ĘŌ霧Ĩ‰ÐwxųÅn_e·—ėą§ d·ßÂŧÛŧSŧMhßH=|NwEÉ.Ü]ŦœúķÁY^{æŨ É[�üŋ/øŋAðĸEÁĸãįŠČyûÔ^Bæ 99Ku IčĖą—ĪZņEÝlˆw:þŸĄ#(ēũJvNvû-Ęw{áî*ņĸ=Ēî' ïnïN9=(ēŊ#Ų{øéĶęĸ…lïnĸFÖĸŊþoüĐíĸ§' +Éį6% JHhz]ƒŠ(B‘A+ØÐųãYŸä9ü*2CŌüŨ‰Čtz čų?ŧ}|Ę᷇ÝXĻ|WÞó―ŧ―;%ū7Þ +Ū#Õ‡ÐîŠĸÃn�ņsāĸ‹™ûĸûôșĮĩĢlĸũŠVhžÐ ‘ķSÓO­`C—ŠPvâé; ĮˆÐĪýî•Ý^8ƒ|įÜæÄĸOÃŧÛŧSNŠėëHÆ[ÔøþÚ]ëúŋûąĸ=ō ]7ņUðƒāĸ‹™ÏĸŌåŊģý?>Ož―DšJ]”;hĸ7Ą#HÛĸŲí…3āĸáÝíÝ)û=$"ۑ'ī§í_$]\úúĸ-`#ÛDáPāĸ]Āĸ ‚ĸ/fūĸį(-ũĸPV•ÛDË?ų0heÛúäkINgð΃ĸgGčĘVčțnvûĪÝÞýQ>sŌqtÁðîöî”øþ|+ūŽŽ?ŠúĸRãðÃāÜKļE―Ģ +ïü_üß øĸbæûĸĒßÛsð‡ýŲÛ{j +];ÜŦ@ä4čÖ +õZT|uZŠÐōÚĮ•Sâ3lŋ:žvg•8ĸ::‚öã#ÔŊÏ°ÛŊ‘―Û{uȊ2މėöÞÝޝrJęuDr9H:„ŧkáwgĸ@(ĸކC‡­üð9øŋAðĸŌĸ7<‹NeÕτ’ōĄÎŲGŧ=1nxw{wŠpßč{P4Ø]ÝÁŲœ_.ĸÐüß øĸr=ĸ/>;Ü A„æ‹ė#ˆÝž7žŧ―;EļodïĖÞ?QÜ]―ƒģþ �ĸüß øĸ‚ĸ�"4_dAŨÝ~ūðîöîáūŅ}ÕÞ]CƒƒüþoüÁĸG�š/ē ëĀn?_xw{wŠpßčū‹jïŪ‘ÁÉ4čþoü)öĸøũ{ąvÞķƒ6% Wð(ėöSâîöy—kû†RKœ%&�ĸ7þŋøĸCAt?ĮbîýðĘŅ}Ũē ŧýŽqØÐs\GôvŨîŦ…āĸÁĸ—ĸ���€øŋAðĸĸ���Ðĸ7þŋāĸ����:āĸÁĸü���@üß øĸ‚ĸ���č€ĸĸ_ð����ðƒāĸ þ��� þoüÁĸ���tĀĸ ‚ĸ/ø?���€øŋAðĸĸ���Ðĸ7þŋāĸ����:āĸÁĸü���@üß øĸ‚ĸ���č€ĸĸ_ð����ðƒāĸ þ��� þoüÍĸï[4`œŧŒ3…eį.ã<ÝĮ”HÚ ðƒāĸˀþĸ@ԎûnĀ87wœ9(ĖE›P:(ŒĀ>3eĪîīøŋ=ðĸ1ýŋũČMũQ]ŠÓŧĩĐÂ;Î6ƒƒĒMčF`Ÿ™/2vZüß øĸ‚ĸ_>žg3Æđzd\58(zE›Ð;(ŒĀ>3_dėīøŋAðĸĸŋ|xÏfŒsõČļjpPô +Š6ĄwP}fūČØiņƒāĸ þųðžÍįę‘qÕā čm"õ xxxRņĀ -m?―°"ûĖ|‘q&Įĸ ‚ĸ/Åþ?=nT<3s:mÞģã\=BWý”w(ąąŠE›ˆĻ”ũp°æĸ§ýxũ™uĨNG2Ņ>";mx?Áĸ́ĸ/5üŋâ ų.ÁÕÃ{6cœŦĮéU#ûPbcUŠ6:(Ú\V$þŸ·„Č>ģY}Dï·7>ŠƒOäÅé™Ü·ŸāĸæĀĸĸ_§ļũmsšģInõp ŪÞģã\=NŊÞžƒĒKpPī‰ÐA!ž3úũršV -äЀäØ<(}Üðņ›qz&ũíQøŋ9ðĸEĮĸC§ŲÐ;‚ÃkT§e :mâôŠz+ÍAŅ>8(ÚDč } +.t) ]VNg>=ã‡^ę{sü‚8=“ûöüßøĸĒðųĸø=–ės2—`ĨðžÍįęqzÕ8 ‚ƒĒMDŠø{Éå#ÏØCóœ.MrlâĸÄé™Ü·ŸāĸæĀĸĩÏĸœþˆĸ ïŲŒqŪ§W üßNpPī ÉAqjãÂŨĄ ŏDɧXå,ü‚8Ýi}{þoüÁĸ/Þģã\=NŊøŋā h•ŠûDéë~þ'ãjåî3øĸ!Ųi}ĸ7þŋčûęy˜:7ïŲŒqŪ§W >ĸo'8(ڄDĨNïÆņáąų øþá D—ėīÎ>ƒĸ›ĸ_šøĸþ\-?‹Ē:mÂ{6cœŦĮéUCrāpPī Š6:(žŨ‰#’Ũîû…ÔÏĸŧýėPųąųĀũĸ§grß…ĸ›ĸ_øĸ/Þģã\=2Ū―‚ƒĒMT9(N?„ËĻ;-þoüÁĸ/Þģã\=2Ū―‚ƒĒM”ĄōĶ`Ÿ™/2vZüß øĸ‚ĸ_>žg3Æđzd\58(zE›Ð;(ŒĀ>3_dėīøŋAðĸĸŋ|xÏfŒsõČļjpPô +Š6ĄwP}fūČØiņƒāĸ˘þß―ÉXŠÓ―ąÉpĮđ +l, 8(zóL°ÏLIęN‹ĸĸ_ôĸÞÃ6g0Îm‚ƒb `œÛDũË +,"5’vüß øĸ2šĸ���ŒþoüÁĸ���tĀĸ ‚ĸ/ø?���€øŋAðĸĸ���Ðĸ7þŋāĸ����:āĸÁĸü���@üß øĸ‚ĸ���č€ĸĸ_ð����ðƒāĸ þ��� þoüÁĸ���tĀĸ ‚ĸ/ø?���€øŋAðĸĸ���Ðĸ7þŋāĸ����:āĸÁĸü���@üß øĸ‚ĸ���č€ĸĸ_ð����ðƒāĸK™ĸũ^b‘lĩÞ=•ãjýjë›cŌXÝšÁí2ƒĸĸ_Šýŋû‘uq„—Ņî}BEŪķŅŊķūWĨąšÍë`ĸ7þŋāĸ#sß?GŋŒB*WÛčW[ß+ŒŌXÝfũ°‚ĸĸ_ðĸ‘ý2 +\mĢ_m}Ŋ0Jcu›Ý?Ā +þoüÁĸGfôË(dpĩ~ĩõ―Â(Õmvĸ�+øŋAðĸEßĸ?ðu?úš‘šē…ƒSņ2úððĪûčõ%{R ‡Zɝö]™ÚFqÅūƒÖ`”ĘWp[Bõn+öVqīVðƒāĸKUĸŋÛėÆ~âŌûŌ܌ԕ-œžËčýJ·ąŸØ}ôú2ąĸï·xĻzhgčūcTÜÉUŅĸ“FĐŊĸĮũaü,ƒĸĸ_ęųĸęüûåoӗËøĸ-ņ[{ĸ—čß5E+ntIWÝwŒlģmž +ƒúŋžĸîþ?ÜhŽāĸÁĸ—ŠþŋøTv~øĢĀöŦÃ_ +žU"ÓÝÅzĸ�áΚîíSޞû:ēâ+‡1Lęþš·&ņ„ČŲûįï}?={IĒ;ŋ·ĸžŧåI…R‡·ŪĸĮĸ$œŠ›ÃÛC]ģ ­Žŧ’9ĒiFéæėE%CTe.ßđĨyÏWĐýŽāĸÁĸ—ŠþïõÕmúōęŧ€ýôÃÄ― Ÿ~‚čðį†ÐÄPioõ-7ī"§í^ĮW|î6/ė?ĢûNP.Žû饑Ũ‡%‡ĶļWØÓfâóĕ ĢÉĖ%…2†Wé>ЛĩŲæĻhķĄ‰ō­“1PsŒŌéĖIYzþ/9đ Ot‘Ōø?$ĸĸ_t>ĸ˜ļ–ŧíÄusÝmũ…wÎÃbSnÎ[’PoK‹OãÝņ9žŽ/žp@ +?ô{˜čūÍŋú‡+\fáëš ‘ŽlvĄžá-üėtIįĐ#\e›*=䒹5ģjŽQŽ˜^·…þŸ―vÞ)ø?$ĸĸ_jĸÏâ|Ô'ĪŧËcQßOß>9ãÎđįôAãxwbčc9‡%DÚ;õüšRō5%jīūpĸõV‰OĐîĸyJsš +‘•UōĸPESũĸOW°|sÞŲí‘­ęYū"óRhæЊTï6é]FųęÝ+ķņHĸ7þŋč|ĸgđîþ4āýīŒwĘĐĸÆ'ī^‘öôüß[ąðkôæóĸZo"ÜņĸŒô*u•>ŲZÁÓy4üßþ(EfpwŅūþŸ·ÉNÏTýŽāĸÁĸ—Nþs>âr˜ūD?üĐåþÖŧX·Ĩør ĩ—ęü…Ēíĸ·ģ‹ūũW‘*‘eöõũŽŸ|eK +e Ŋ†ĸ‡šŠoÜ6›ĢÁįĸó#8ß(ÎŽÝmümþ–Áĸ ‚ĸ/ĩŸĸýĀîĄŨmšũõ–â.'4ĸo­ÃôP•HŦÞeęFړøĸūĨÂiðQðÛã ·d~·ĒžŒŨÛÂOåd߉ŠĸG +ĨoÝïNũv%é0csäR›ïĸq{ð6æŦøþ3Į(Iö +ųé}ĸŌHz_‡NVû)ø?$ĸĸ_ŠÞĸß/<4›7%ēXũ·nđÓé‡õ‘,SÞ^č·Ą/QþkTĻČÕ6úÕÖũ +Ģ4V·ŲýŽāĸÁĸÏĸ'þLÁ@Œ~… ŪķŅŊķūWĨąšÍî`ĸ7þŋ\Ōĸ‡î|Ïč—QČājýjë{…QŦÛėþVðƒāĸËUýFŋŒBWÛčW[ß+ŒŌXÝfũ°‚ĸĸ_jøĸ}” ōËhũVĄWÛčW[ß+ŒŌXÝæõ°‚ĸĸ_Ęüĸ0lĶ ÆÕ6úÕÖ7/ÆĨąšuĢŧUÂ(<āĸöxĀĸËü����BāĸÁĸü���@üß øĸ‚ĸ���č€ĸĸ_ð����ðƒāĸ þ��� þoüÁĸ���tĀĸ ‚ĸ/ø?���€øŋAðĸĸ���Ðĸ7þŋāĸ����:āĸÁĸü���@üß øĸ‚ĸ���č€ĸĸ_ð����ðƒāĸ þ��� þoüÁĸ���tĀĸ ‚ĸ/ø?���€øŋAðĸĸ���Ðĸ7þŋĪøĸ}46î‰ũ)ũũ���ŪÊCøĸXāĸKĒĸođÛÄnÝAAôü8ðĸ%Ýĸŧĸ) ��� ;ÜĸüÁĸ���ŌÁĸĸ_ð���€tðĸAÁĸü��� üPðĸĸ���HĸüÁĸ���ŌÁĸĸ_ð���€tðĸAÁĸü��� üPðĸĸ���HĸüÁĸ���ŌÁĸĸ_ð���€tðĸAÁĸ—bĸïžÄ.N·`ïĮ†Ņf°]ŠCŠŒmË8müāĸK ĸïuÜÁɧ{“öamÂvaH‚ą55Úzāĸƒ‚ĸ/øĸ,Ü·W†qVØ. é@0ķÖF[ĩúéĶÄĸ ‚ĸ/øĸ,pÅa'†íckmīUŦŸnJüß øĸ‚ĸÏW†qbØ. é@0ķÖF[ĩúéĶÄĸ ‚ĸ/&ýĸááIŊcY―Uģ|ÅŲŊučĩ,ã•Đē] îoÔZ‹–ŧšå‘ŨčÍėiĪúĘZØēø?d€ĸ/ĩýß=dœ$)ũy6„ŋŠĪ4cĸOL ĸWÉęÃļĻӞŦŽ”…+rõ>3ķKęđĻËļĨ>ûÔ;c 1ōŠÕÛûŋð$“ąŋé^Ë=YüPðĸEÁĸ‚§áĸņ ĒŨ0HŅþŸ*$Ą,\;ī‡ąŲÅT{dŠÓÞĸ Ž[uSRĨ‘ÄĸëŪEááĸĐÕO7%þoüiîĸî=Šõõ~büTæ=iœÞažjžíyuũÐðé<ÞÞžC!™ÓØėŠszét­ãĢ^ï€DæÉĢĸ‡vŅýZHÆÁŋ Iïl’í"Üú§[°úv‰Ÿ:BûpÜBë™.áŪYfžą6g Ցn‹Ôí_xęđňĸ{‡%> §Ķwo” ÚaÎÔ3@áhëĸ +þŋč|þĮý7tō :Üų― ‰/9^EēäÐiÓŧØČ<§ ,™ļmîþš$Ģä―jä―ΠĢĸG'i}#nIåÝpō­œšĨęúŋüĒ·^Gī|K–ß:ŲC*Dcä“ķ…Ō9YŽĸï<ĐĶw‹OņfJĀĸ!üiëĸÞc?t’—_nūӚũlãNŒ,6tēŠb§ņ’Ō·­ÓÝĸ#[$od +—™ęįĸÝu‘Ļ]d4lJi—.ÜRý_ēRũęÓ―]âĸI'Ļ9üŋĘķ Ņ4þ_8h§›ã4QØL ø?d€ĸ/jÏĸF.Rōž’Dý–rę-đ―ĸĮÍÐ;b‡Eí4âĸĄV“F&c™ĄÁLĨåįĸåWįÐ8ĪzŽwŠ,ģĘ.ŠĩķËéðƏŧøČg Ž·Öéé1)ũī™6gŒę#_w[Dķ‘äL+ÁČóŋō3ŒäĀ<=ۄÎ-’fJĀĸ!üiëĸrߋœRÏBKðN)ĪÓUÛĶË5iû­ĸŨ™ę&§™ĸŧ:ūRō―čt4„éЊ%Ņ†ė­Ķôý?ĐÚĢęĸĘ^æaJßïĸIÚęž{…Ûčt"ô―ĸŸ1ėuý?õB_þāĸKÛïĸĖðÉiM.Q‘‰§ČŨ(u­3&šS,|ĸĸ/žĶ˜úüjŠp$ÛË}{’·KŨÚRĢûŁĘ^æa +þ/\ļ°É=Súŋ|øŋģĶøŋ9ðĸĨųũĸ?ėþ&č:FäėáÎóāüđ3’™?ÔÞ~ŠĪ=7ë4Ũ­%Ÿó0ÅČũĸŧÛ7u”ž4dĪîö-\Ŋ6ßĸ·ŧČq‡øNĒøļeĻ”üx õYkŧD†=ręyTŌ^īūĄÝ8ēŦĮ—?– АZ#_å é*2Ož‡S†öĸÐæðˆäT:ĄÅ Õm=ðĸAÁĸ“ĸĸo*UÎ!Õ[j\Ņėĸ89 ã;‡ۅ!-ĪåÎ|ĩąí þāĸËþģũ�ĸ†ņVï)aŧ0Ī…āĸģ‚ĸCøĸ2‹ĸW†qbØ. é@0ķÖF[ĩúéĶÄĸ ‚ĸ/øĸ,pÅa'†íckmīUŦŸnJüß øĸRÉĸïŋ‚îŊ8Ýû4Ãhķ C:Œ­ĐŅÆĸá�þŋûĸa)NÏB„$F›ÁvĐ Đ^0ķ-ĸ‡$ðĸbĸ���ļ øĸ āĸ þ���þ?(øĸ‚ĸ���Īƒĸ +þŋāĸ����éāĸƒ‚ĸ/ø?���@:øĸ āĸ þ���þ?(øĸ‚ĸ���Īƒĸ +þŋāĸ����éāĸƒ‚ĸ/ø?���@:øĸ āĸ þ���þ?(øĸRėĸŨØÅéėÝāÁ0Ú ķKõ`Hõ‚ąm§ĢĸÃüĐáĸ―Ž;8 đâtoŌ> ĢMØ. é@0ķĶF[üPðĸĸŸ…ûÖáŠÃ0Î +ۅ!ÆÖÚhŦV?ݔøŋAðĸĸŸŪ8 ãÄ°]Ō`l­ķjõÓM‰ĸĸ_ðĸYāŠÃ0N ۅ!ÆÖÚhŦV?ݔøŋAðĸŀĸ?<<)_ÂéBö3H*ĶÎ_w2˜æŠ“ī)Ŧ{ŊaėēÏ „övé;þ…ÕÝtÉ[îęÝwïÆ#<ÍŲxðČ�ĸ_4ýÕōS9OĩņŒôþķąýK6œŌšįĸyö•‘Ų.Ą_É7Ĩ7Ŧ|<kQkũŽ TöŠ,J2þ%§šHÖéĒŠ i—“žýÅĸãGAÆ § ø?d€ĸ/Ęþï}A_ĸŊØ­ÉøšôWHj­Th†ļ• HÅÃķ"ŧwŌšfÛééFũĸÂæ§á ü?ïW]Āĸ!üiîĸë‹―#đģy…JxBriˆ_hÜZÞfžYÞåŸÎŸ4V!―Ôöoϑí"―ÓýÁ;zĄQMÚL^4ü?c­%EļĸH6ĨdąÞŲܝ3cÅ#ŧVÉvIZŧø1ŲÕ―đōÁŒW9=ï…FõtóÕRų‰+ēĖ7ÂĢûĸéo +ü2Āĸ—þŠm‘ôx•H–diyB·57Wîr^w +-Īî$RG&i"ëx:ĸ!%ĐÐéšį ãæ‡ËŨ:>ÎU„ãāŪ…woĄĪÍ-ß|-ýŋÁ)Ļ$7$ŦI=ŨRģ'ųū#Œĸ·ĸ‡ ðĸĨÓýĸÓŲ"Ŋ#é…KËðĸøĮÛ[’ĸKÚÛķNõÏĸWÉō!MÝLÝý?i­%ãZwwŦnĘP-IJ•­`ÐĸóŒčĀév mƞ#Y)/ÚũĸS;œi„GņĸЊãĸIÕ‡ þoüiþüŊÆĨĄÖŌ„đŲrŧŸž*B‡ņtëVŋâėŦD.ūņíY…ÐN/î…‹ĻB|­Kžĸ•lļČZË&ūîņM‡Īeflánï&6{þW8=ēuäcÏõv[ÅN+Н“žĐū”ĸŸžTĩÁĸ!üiuĸ?2ąÁĨAļ4ųü‹ÅéĨ'þ:žînęWœÔkŦûŦÔu ý*éu| ŠcÜĸKÖ:ÞsŌî-žj{íčtóÞ5fŽ'6xžåīCá2KķKųĻķũÉÄö'ųū#Œĸ·ĸ‡ ðĸe^ĸߒ’8€Ðĸåŋ•Ï&ņwiÍü_.’þĩý?õjUýû?3Ö:Uc$ĨŊĸĮW|Olæĸ§$mšĪÓNÆëĪĄ>pĸï2Âųĸ-p˜ËÏ0øŋā0Áĸ́ĸ/ƒøĸMėEû9ó.4‘܇”/‹u_Č-z} åޚ|@"Þķ|ÓėWótðKĻÃH·‘Ą+FÉĨ3u­“6M(Ý;ĸé8ļY§Į]äĩ[=R7’ØŌĸ·ž##ÉMÝŽĄ*ÞýߟÐ֏…5ĸŸi„'ðĸý DÎ䒓Š6ø?d€ĸ/þĸ_ĻÂXWģŒ2Œ.ŧÕŨ(ōÛQķ‹Æš+-pî!í;—ÛîāĸþŋāĸģĀįjÃ8Į[�―ŋË�CĘØ^ü2Āĸüļâ0ŒÃvaH‚ąĩ6ÚŠÕO7%þoüÁĸg+Ã81l†t [kĢ­ZýtSâĸÁĸ—JþĸtGxÅéÞ§qF›°]Ō`lM6þðĸĨØĸKqz"$Á0Ú ķKõ`Hõ‚ąmø?$ņ€ĸû?���ĀÁĸĸ_ð���€tðĸAÁĸü��� üPðĸĸ���HĸüÁĸ���ŌÁĸĸ_ð���€tðĸAÁĸü��� üPðĸĸ���HĸüÁĸ���ŌÁĸĸ_ð���€tðĸAÁĸ—bĸïžÄ.N·`ïĮ†Ņf°]ŠCŠŒmË8müHübjųŊãHŪ8ݛīÃhķ C:Œ­ĐŅÖĸ”Sîð>ķaāĸ3ąūĄ‹ÏÃÆb…íckmīUŦŸnJüß Đ<øĸLpÅa'†íckmīUŦãĸ#‚ĸãĸÓĀ‡aœķ C:Œ­ĩŅV­Žĸþ?œĸ?<<)ŸSū’íU>LÏļâܗÐq―$ ėŧ―Ní9i~Õ ·ņŅķ°üДķKß-Ō—ŠCjv―'kŽmƒĄ°<ÚŠÕņĸÁĸŦûĸáĻwÜpš þ*īīģĩ ž‹$ËÉHQÛLĒÉūâHNÚ§ŦŊô–ŠĸWÆÃ―;sÉ0FUýØ)ĄðXSō-Ōï*„V-ūWdß102Œĩv-q68ķ…r>úhëĸ +þßŌĸó~%™.XÓRĸ·‰†ļæþÚvá0 +ŸęĮN!vüŋúé5ž{‚w-ōÕÎ0ŠžÆ ĮŲāØn‚ŅG[üP\ūZ4óđØHf“HÎūôáŽÁú"rg,”JÜĶˆŽÎaáëPV3qõöā—·ÏmĒ$EļŅ#ÛśoūĨĸŸc|-äĢtXēw BãßÏOĮÁ­{č3ūÖmü?c‹dœ"ŧúéICū:§{…žĢĶãa C%ž§ É>i2~Žeģ‘ą T|æm=ðĸA9ð՘Ãĸ3.ĄËdEÜtwQ§WސÉgpÛF\ģG^~ąHrÉfMZ‘–oĢ’Ö1cô"óKŽÓÓý\B•-[ū]”ķHÆy ŪaXåØQrÔĪat§gœú +Gcœ-ŒmörĶm=ðĸAÁĸ5žĸ-álņŦmžzƅIãäšYrĶu[ë‰ģ}Þ~ĘĮD>ō…#ïÁ;―ýÛĻø(íį9āýUjKÂf’6ÄéÂã xŅöĸž-"_æĐS%”$[ĸtŽš:ŒņӂÜH“öaų™${œ-Œ­d™ōŽ>Úzāĸƒ‚ĸÛôĸÓóÏöcDS…Â#ž0ĨšîВIÎoÞĄų›ųHA―3DŪ‹•tß.ÞųũÓÛ<ĸ[x)Ū dp„Í$mˆČ…S\īŸĸՐŦÐy oW?,Mē™â§ gTó†1rn?M^WŌL­qķ3ķ’ŨĄ]tĶŅÖĸ”uĢÜ7Į5Áĸ# S2Îx§Kˆ”ŽĪ·ņĸÔŨĐk‘šØĪJ.[mĢ.ž”gŒ’ðp5“ī!N~š‡ŧTžĸŊąEäįZGPųf*žG]kCgÞéāœių8ÛĪ]4ï=ĘhëĸJÕGi‡ ĨïĸðÝtĘóóž%ȗŊíĸōŦ˜üŒ§'ŪŲC—áBíý_2ÚÍūFIū·doá6•4SÅĸKĻíĸ…[Dūœđý?cãk'ó*#\qœŒí~þŠþ?âhëĸÈ4öĸmšũ·ū? +ÏÞӂ;sÆÉ3û,_‘à û#‹u—Y]\…{čÜ;\‘V#č°ØT…ð{dOp'ķüÕx'§đÂí%œ'>nI"īäļNÄÛĀĸKķHŌy oW˜’d·Ŋ2ĪՇ1r9Î:ŽŠžtÆ8[ÛÃŊ$ŧčöï|Ģ­þ#ĒįĸzĪšĮĆ‚ĸqūĘūÁ0ڄír!ā$ovl§ĸHeDĸ‡\qðĸ‰aŧ\dHOĸ46ĮvVð€Tðĸ™āŠÃ0N ۅ!ÆÖÚhŦVĮĸa8ðĸ™āŠÃ0N ۅ!ÆÖÚhŦVĮĸa8*úĸýWÐá§{ŸÆamÂvaH‚ą55Úø?Āž*þ_ðåĢDý8= ’`mÛĨz0ĪzÁØķ ü@ÎC ĸ���ļ ø?Œþ���þ#‚ĸ���äĸÈāĸ����yāĸ0"ø?���@ø?Œþ���þ#‚ĸ���äĸÈāĸ����yāĸ0"ø?���@ø?Œþ���þ#RÅĸÂLœnÁÞ Žĸ+y��üFĪ–ĸw?�aEâĸݛīþ��ðü&î[ĸo3Œ���7üÆĸŸ üŋŲ0��Üðü&ðĸfÃ��pÃĸaLĶôĸ‡‡'Ý{čBGĸŸiĖņ��‚ĸÈ íĸwįÜ8L?MLZæ~bhúiW hāĸÍÆ<Ģ‡Zƒĸ�€üFdtĸ?}}š(YĶwþÐB’:ĐKĸŊ;æĐCyߑú–Īd��nø?ŒÉü?éþ<þßxĖãÃč.'oCTF��€þc2―ĸ{ūÖýų;ˆ6ņĸĪ1 Ģŧü��LĸÈĖíĸĄ„”|þß;ģĪŦXðĸ’1?-$ũ>ĸ�� ĀĸaDFũĸļ:æđĻ;O\&“>_ĪŠ…į3Æ<4ŒÂ…Č?STq��nø?ŒÉčþŸ^âĸÂų#Yíi|ĸŋ֘Ÿc’ĸ—?þ��Bð‘đýĸPGüßԘŸcd9Õå_8Œ���7üÆdzĸŋž0<vęūÞčÅ;QŌUŒøŌ˜Ÿ>[‘—Rōų+ü��„āĸ0"Cû?čøĸĸVĮøÛ(��€þc‚ĸÏþßl��nø?Œ þ?3ųŋņa��ļáĸ0&øĸLāĸ͆��ā†ĸØTôĸûŊ ;BĸïÞ§qð��ð~üĪŠĸ?–âô,DHĒû5��ėƒĸÈ<Ôð���€ ‚ĸÈāĸ����yāĸ0"ø?���@ø?Œþ���þ#‚ĸ���äĸÈdø?����Žāĸ0ĐþŋAAŧĀĸa,Rý����äāĸ` ü���@üŽĸ���čĸƒ5ð����=ð°þ��� þÖĀĸ���ôĀĸÁø?���€ø?Xĸ���Ðĸkāĸ����zāĸ` ü���@üŽáú?AAQ1ð0ÅÃcĸ����%ð°�þ���Ðü,€ĸ���īĸ ŽŸIŧï����  þÝéö$ AAÄ%Ģŧþ�����������ØįĸhÍĀæ>`3� \ No newline at end of file diff -Naur wfdb-10.2.5/doc/wug-src/wave/ppm/galeon-new-helper.ppm.gz wfdb-10.2.6/doc/wug-src/wave/ppm/galeon-new-helper.ppm.gz --- wfdb-10.2.5/doc/wug-src/wave/ppm/galeon-new-helper.ppm.gz Wed Dec 31 19:00:00 1969 +++ wfdb-10.2.6/doc/wug-src/wave/ppm/galeon-new-helper.ppm.gz Thu Jun 20 12:49:35 2002 @@ -0,0 +1,64 @@ +‹Ÿ=�galeon-new-helper.ppm�ėxÕúĸũŨnUðŠØDDŠ‚‚ĒĀ•^,p)‚J/z‹ !!Ī‘@ HHŊ›^IBz€Š +ÁŦþŪÞĸÏįî–Ý;lfN›ŲŲr&ïįyŸ}fΜþžōÍĖėf\ŋ?õïÕũé~―^úSïū}ĸtæD-˜"{ýõŨ…O������37n%„ËÅ / L…É%ğ>ų“VöįOþüįđVŧgî=f›gĩ{įÝkķųfk3ŋÕīiŧ í][Øöū…ũYmŅ}YôŅî_|ŋ­=°äŅ\ōāƒK­Öni;ģ-ģÚCËēšĮC{<lĩå?ēü‘ŧķâ‘GW<*Úcž‰öļįãŊžkOŽ|â /Ŧ=éõĪŲVYíĐUO™mĩŲÚŊnoĩ5íŸ^óīhÖv°ĩgÖ=#ZĮu;Ū·Z§õĖķÁj7t6ÛFģ=ŧņYŦmzķËĶ.wms—Ū›ŧŠöܖįl­›w7Ņš{wïþĐÕz|ÚÃl>V{Þįyģųš­§oOŦmíųÂÖîšß ―üz‰öâķEë―­woŦ―äĸ’ŲŽÖ' Ųķ›­ïöūV 4[ŋĀ~VÛŅŊĸŽþĒ―ôē­―üŠh‚ ąÚĀf ĩÚŦĄŊš-ĖlŊ…―fĩŊ Ú9čŪ…>XīŨ#^퍈7ÞØuŨ†ė2d·ÕÞÜýĶŲ"ÍöVä[fÛcĩĄ{†šmŊŲ†ífĩĻaÃĢ†ßĩ}ÃĸšïŊĒ―ýķh#ĒGŒØŨFî9ō€ÕFeķƒf}pīÕbĖ6&fŒÕbĮŒ+ÚļCãlm|ÜxŅ&ÄM˜oĩ‰ņ͖`ĩwÞ1[ĒŲÞM|ŨjIf{/é=Ŧ%ŋũ~ōûĒMJ™$Úä”É“SïÚßRĸö·4ŦMI›bķtģMMŸjĩ ģM˘fĩĖiÓ3§‹öņ[›‘5Cī™Y3gfßĩYŲģfåXíÜ͖kķŲđģ­–gķ9ysŽ–?įĢüDûļāc[ûĪðŅæΝ[dĩyEóĖVlĩųÅóÍVbķ% ŽVš`aéÂŧvxáĒËD[\ķXī%eK–”ßĩĨåK—VXmYÅ2ģ1›ĮŦUšmyårŦU-_QĩB4ÏjO[[YģR4Ŋ/ŊZŦ­Š]ĩŠîŪ­Ū[―šÞjkęŨ˜­ÁlkÖZíĻŲÖ]gĩÆuëŨ‹ķáØ[Ûx|Ģh›ŽoÚtÂj›Ol6ÛIŦm9đÅl§Ėæ}ĘÛj§―?=ýé];óĐÏŅ|ÏúŠķõėÖ­MwÍŊÉÏïœÕķÛfķófó?ïoĩÏĖðY€Õ>ØþųöŧöÅöĀ/EÛqa‡hA‚‚ūžkÁ__īZČÅģ]2[čĨPŦ}öUØ]ŧķóōNŅÂŊ„‹q%"âę]ÛuuŨŪŊ­ķûëÝfŧfĩČk‘fûÆl{ūŲcĩoũėývï]ŧū7ęz”hûnė-úFtôwwmĸwûũ7[í@óģÝ4ÛÁ›­ö―ŲbūąÚ­˜Ø[ąĒš}H4 !@B€„� $HÍ%„Ē*„@B€„� $H !,BŅĢ !@B€„� $Hû%„ä6…" aI$H !@B€„āZBžŽ‡,!lïB§ŒÂ*ā.H !@B€„� ÂFB˜æ™?-BžMa‘âĐEBˆ§Ē„Ž-Ÿå Fõƒp,HK ­„cÚJ1ÐVBXB@B€„� $HŪz“aŅâ]ŦŠ°đ a>øũ]ģŠø·„°Ļ‹~ïBˆ*B‚  a>øũ]ŦŠð0ˆw!Da>ļsBT !@B€„� $HÕ‚p Béŧý`„dā$„ø )!Äŧd w!@B€„� $HMîBāôã]œ„°E.!lAJ[TH[āAH !@B€„� á Hý`§„ žNi{Bō.„ü.„ä]Ĩw!äŊSƒ  !@B€„� BÃw!äúA+ áī&x$H !@B€„āįuJĪ„#CōĨÎŧO1Pw!ßȐHøFH !@B€„� Á‹„€_§ $H !Z­„ØČ H !@B€„� $„eũ'üĒ !@B€„� $H­ $H !@B€„� $H !@B€„� ‚ !ĀĀĀĀĀĀĀĀĻ&—&������ ƒ !š������P€„�����@)ááá !�����P +H�����T������€„�����@ !�����PH�����T������(•á€āŠ‘����-W.! €K[C���€; NB8íĮ·[„ž\` ���ļŠ%„KjÛĘ ���ļ !xÁŌóM !����ũ�$/Ø)!œöŠ'��� 'ĻHũ'Ün á‚W?���ž!ï8 !xA áĖ—?ãĮ…@į;čX,;GB"WŠƒrķ­$„ÖõZ 0~\tūƒ€Ž% ? A8Õ= !�ãĮ…@į;čXŒ;Ž$„åĀöÔö6…m*äąäž†<[yđ’HĀ…Āøq!Ðų:–@Ŧ’Á@–ō„älqÂà €„�\Œï  c čRB ߅`đÏ@= ĪĒ:€ ņãB ót,]JäĐ=Ē‰ö ƒą,' đ„Ā՟EhÉ#ā.‚“{°ÂÄgt%u88X&/đWĄÏ‘(ÕÎėCÜfįL@BH"Č?Éđĩ ÛëÅcĨ1ĐĀRÆ)ļ‰›PrĀõŠ á j„hú–,ĮJ%„óĸŽÖĨ„ K>ydļ}á*”J‰ģlO%N—øįý֌R ëÕ&%“‹]ō‹ + Áē•ā:_~Œë^ō:霅Q—ÂÛpd4I 9ūü*ÕïNž\zAX4äË5&ŋØz„ęĀ9 '>ã:I=hĒyŋ•ĢHBP;_…#ôŠŠQ­â*ãtĀՁœĘq Ģþ$„ŧBēÚ žF Á8 ÕBŽV +î"rŌąoXėzEÝĻV*Tt/UBPkk? ! Ũ7Į―NIVŠbRa™ļĮ"Q�[l‘N Ą-JïBtûäj ŊnTS{•ĨóÅ˜ČŠáÖIy*Į-Œ !„Ŧv1]JyžļãÖ° đ3ŠïĨŪ‚„`ĝϞDĮĻëXÛ% ·$"Ųû™ !pĩŌ:ÃĄ_ędÛԘT%{�į íãx–hČ"Z'ŪzBŦúŧ-öwŽĒcÕúMé$Ō:ÃÍ%„\5Øį‹<jæ€ãÐäK8đČē·f\ø }Ģđ„hjŲ“äþĪ.•ČÏi Ģ$D8ā\XJvī{j?Ī„�Ü +w?šG÷Ée‹3G5w=Ïļã„Ŧ’€Ŧ :”ėh7Ü Äŋ§�7ÁmĮOk�$„ƒpÚĻæąÛ*!L€+П„@Î,§›îqÏņÓJ� á œ3Š9ísGKVĀ ? ðŒï  c €„Ð:~p`üļč|K�$„ÎÐPBĻz—híĀøq!Ðų:–�H=ÁčPrr����`„šã€„āM$„Ģ^ô���tuĮq apĖϐóQTŠĻĮ\H���Ā™Pwvæã4@B����΄šãļđ„ĸųoûŒÆ6ū|ĢCÄķ!„SIrLEö����p&ÔĮ%á@ˆÜБTäIÉh'n(!Ä UälOZu ÉņŲs%f‹­ĖvPþöĪ"$Ũ“UÏ&düV> 2ȑV1—@ÝqļȘ„h„öÆJē$W;K'§U—H͑t…#zÆN ĄyÎî‰ķ:ž•ÏEŌeØBÝqÜYB4Éî0HÄ!2đ<Š„ į‰Ŧ�Ątdžvâ !Wږcö@SËy$ÏPh{JN‹,ŨÎЧČ.Â՜œ ĄEō†pĄōļ†#qŊČM&O!ŧW~] Ļ―&âhTäyđzžQMípî î8n.!$!ōKļ@\*y 5OÆ|XŠdŽļUū"áqėÔhödŪŪ’ķ+ŽŪ’u›ëđBÚé)dVŠbēU~;_ŦđĐz:óū9â .&ķ~ĶŽX. î8î,!ČÛ=ygOEÍSŦ@;qôƒ Íe�c)Z)j5ė”*ŠANÅÞiîa7qū„@ĶBú‘ëžWÚ^dZöLtķ30īw ƒžĘ ÔĮ$Dęm82Ķm.OyÛ@É1.OÉą“hŽ~ĄbÝ`_ļĨØS.KäU\}äáb ĩ„īė įrÃM6ŒŒFõē \éļ*áNđCi{MÄŅˆĖ„0SäĮšÐ(jo(Û\@ÝqÜDB�Tœų Ci y7T‘VE {5Ļ•DÂXa\žJ; ä;”<\~ŽhŌPB /éĢóŲÛŦ(―ŸõŪQöt8ŋPwžÐj߅âķ-%â‘ųģKMt(•äSváGĐhŽrÚĸZÍMÕSŌ6­žP'!ØŨū î8 !xÁ ßȐ|"·o–―Rūķ K‘KyZŠ„`)Ņ6„å*2ų)ĩD\Ã%Mãwy1Ų4Úp1—!–˜&”k.&ŨŠ ĩŨ„äžÁåcâķßČPr:›hÎ)Ô$/8íw!Ņļž���€ +Ļ;H^� ���8ęŽc„œ H���Āi8HB�Ū ����LŽž 8���€Ópœ„Pą‹v���pÔ$/8í]����0„Ðn(!Ä UälOZE ĩH°}QĮAųۓŠ\OW=›ņŲ3ŅSŠČß@#GvZÅ\uĮ Á î,!œœVQšŸã.DŌ·Žčj;%„æ9ŧ'ÚępŠĖ#Ô$/8HBȕķÁÁŋN)9%§E–k.”7Ysy•Č%rČããF‹üŨۄaC(ÔD™ō:ðëhEí51Ï/ÆélâđëØ3ŠĐÎÔ‡# aýŨKyˆš íĖĮ98BBāVTäƊÛm‘ėÔhJ󑷑‡ąĨ�ä +Đb˜0―­.&ûXåŨÅZÍMÕәũÍa%‘+í=î î8 !ėÏĮ98úA†æ2€ą{ĘO å&ēšM Cpó%2Rįpí_uŠš͞)Đ' -ÁÅÁČã ŊōuĮŅ„=.đ* ī AJB>’äNÆŅ2*!ĨØSŪm抚ƒĖ„ #é:ų"lýáO]ŪŲýÂ2~§ÜĄī―&æŲœM­g‚Eí Ec› Ļ;Ž>$„Aķã7ĩÜë‘„ŦŠb:g>ČPˆŒÆXŠ=åR‹ÆE–Įo=+Ī†(íCJB0AMÅ8*$—øuąšö* +dïg=Ąh%aėp~Ąî8|I9Čh’ö@ö$ΧÕū ! d‘’@–ĩ‘ÜR�‰ +F8%oXŠb*ŦœzYŦđĐzJÚĶÕę$cïquĮáKBBäšB„ įÓÔōĶ„3qÂ72$ŸČí›eĢ—Ŋ-ČRlOqi‘u@^•Ÿ’k.)Kr ŨåQsä=) 7ŅÖRdrÉU–˜&Ô ’;YN}­Ļ―&”SČóڄésĪguu€É;Ðö*.>§Pw}Hƒrĩ€ ”Ą(ÐĄĀęt­§Ĩ���dĻ;NŦ•qh>N$„sh=-�� CÝqô!!šZ~“Âöģ /lՅž\ÉU§Â9īž–��Ąî8IˆVŽþĀ5��� cĻ;H^� ���8ꎂ@B����΄šã€„ā���€3Ąî8 !xÁ %„˜ĄŠœíIŦ(ĄķŅôŪąęüčÐ/ŋŦ˖etéÉãŠg“ïNëĐE 2ȑV1—@Ýqė‘á€sq[ áäīŠrÐýWVBß]m§„Ð<gũD[ÂA‘yÄApšK1gÛ1œ%ÐÔrÉ3”ڞ’Ó"Ëĩ —ĘˆŽđžJäåŲR›)Ŋ'{?SKa ÁEc ČäI—MCã +RZ%yåÉë@nĢ;ĢĻ―&žSȞR:xĮžQÍ2 ųÂABÅhŲĄ8·ĒĘW$\ î€=Mi>ō6â0ķ—Š―þČ՞―tEOMHmn‘D&aW* +R“―—ø]Þĩš›ŽH\ĢnÖ3öwPwÜAv(ęƒ Íe�c)ö”+žĘ%Ldu›.\“W:Ą‡íŲÁĐY"KâĻ“%ŽČTČ^âwa7ĐUԄhvQÝ`h .î@y•Ļ;Hî ;õA†C%Ąm%cs™āâó$gng{‘K™|eCF ö5Žžh2ÔäbđÔ6Ęó$øŽÐoŠšæ†(mŊ‰ÁãōÆ$z‚Ð(–)ƒŒĖoGQwÜAv(E2”"Ģ1–bOđÔĒq‘åņ­š4“―iŒuPá–Č+ŠĒ䔄ĀeŪīJŒĢBr‰ßĩ]]{ŠH\Ģh%Q: đƒšã€„āēCqðû.„$EHYÖFrKq‘ŲëŊīKÕeȘÐU‚|JÞ°ÅTÝ]ĄÕÜtÄ@âuģž}.óuĮ Ád‡â`ųF†äđ}ģėžōĩYŠí).-ēČŦōSrÍ%eIĻË#ĩ™ČlĐQ3D֍Ĩ&&LŸãōAæ€KÂâqdĐ)Š’žDđӑ5Ą6Ó=QÔ^Ę)ÔAĻn q u€É;Ðö*.>§PwÜAv(ö߅@Fãz(Âi-m=] +��§PwÜAv(Œ€„���°@Ýq@BpŲĄ8@B0��ĀuĮŅ“„HJJzųå—ûßaŅĒEŪŪ‘C ;‡#~ā���Ð1ÔGOâĢ>Ðåá3áSæžÖũđ'|ðÁū}û.X° ''ĮÕUÓēCq€„����AÝqt#!JKKÛĩk·nė3?ÅĸíŦ°Ą?ÄNnŋöý^ĀĒ%–-[Ķ-Av(���€"Ļ;Žn$ÄęÕŦŸ}ēݍ]oŸũX>ĸiÁ*—wûvï؟â§Ôoũņ';=zŸEKŽ\đ277ŨÕõUŲĄ8@B����Š î8š‘]ŧvýdȓ?ėW:ïÉŌOþmóž,ŧsp+zĖŅc+6™Ú§í3˜ĩÄÁƒkjj\]k5ŠÃĄĸė[EÎöĪU”PŦh:øŠ·#0Øā üíIEþŽŋĘ:đŠg“ïNëĐE 2ȑV1—@Ýqô!!BCCÛĩkũyȈ†•ÝŠg?\4û!Á +ûðÎįĖ…ƒŌm.m;âõ›ŧ‡ ėņ،3 + ŦŠŠ\]wŐŠÃĄÂÉiå IŦq?žÓʑĸŽĢ‹Ð0•žüĻ­ á Č<BÝqx—IIIBŸzęĐÝÛÞÚ3īøƒ{ +§ĸđ`Ę +§þąĀjŋϟüŧ;ößæÏ)ŋ/švϒ!öęÕ+99YPÜ݋ ;ËŊSŠ!b8K IķÃĘĨŧ$Ðö”œYŪmļ<PÞ@dÍåU"—H.ĨuBþ7ZäĮļÞ& BĄ&âȔŨ_‡*jŊ‰y~1NgÏ]GĀžQMípî î8žKˆyóæ :īĶĶúR~PŊįs'ĸ.û=ƒqâgČ>Į›ēÆŌîœæžcȟōŧā·ĸÐķmÛĻĻĻôôôēē2W7Bd‡âāũd(ÍGÞFBƖĘã+ĪŠa`Âô­š˜ėc•_‡j57UOgÞ7G„•D~Žīũļƒšãð.!šwïū#0āĮŋß|ýēPąģ%ą•Á3S§>70Ōøķ!i„!I8ļóYå3þ֕sŸ§o­Ý4Ļí† "ī:33ÓÕíP�ŲĄ8Ļ24—ŒĨØSŪxJ(—0‘•njüŪŽ†āįKd*ĪÎáÚĄę5!š=SROZ‚‹ƒ;ĮA^åęŽÃĩ„HLLlŨŪ]әÍŨŊ +ĩĘ.ũ>OŊm:uī1'úðķY)ï?zč-ƒ`ņà 'ãķü$(oūúō|ý7W?ûūųZÜĄ˜iÓĶvëÖí0`Āʕ+cbb\Ý&:d‡â >ČpĻ„ ”Ē­„`l2Eņ9’î’/ÂŲþÔåZ+ aj9Nä§ÜĄī―&æŲœMėŽāBĢĻ―ĄhlsuĮáZBžóÎ;C‡―}ëÆÕKMB­’‹W0Î +s+J2Ο=~íę…ŊÏ5\i(žýý·ŋýÝĩËįϝ(;wžT°ģĮ‹ŋüŽáëËįo5_;\RčéđBČęÁėÚĩëØąc\Ý8,d‡âPô Ci 2c)ö”K-Y_]æ­E}(+ڃ4”ČKüzV]{ēũģžPī’0v8ŋPwŪ%DŧvíâÅ|ũíå/?;!ÔŠ *Ð{ïĀÝ)S…ãŒä蒾Ĺ#Ų§–^þōė•‹gÏ?lŅgk,ėŒ` § +„Ï˗N}ĸÝŨMgŽĮĮÅLŸ>íĖ?H5fĖ//Ŋžž<W7īd‡âāũ]I ‹ ēŽŒ-lQ*!ȧä KQLEc•Sįj57UOIÛīzB„`ė=î î8üJˆÕŦW ŧüĩŦýÐtŠNĻU~åvψŪkÃŧoÛ7Z8MŽßS”_Sn<^—æhņŲcĨMĮJlôCE?œŠÏ;!XmŽ`ĮkÎ5ÜžqåöũßZÂÓsE=štéRQQQWWįę[!;Ë72$ŸČí›eĢ—Ŋ-ČR’�W„ĪzōŦōSrÍ%eIņų] Ū[äÃq9ōg‰iB *đ‘5áÔ§ŠÚkB97ڑIåę ę�“w íU\|NĄî8|Ic™ŸgøsKC:*Â?jĪ’·ŧ0ëPõáŒc5đ§ŠN Ęáh‘åæƒD?ŽÚ(XcuFceFCeƉ†‚oŊ^8{úXĮŽFcIIImm­Ŧn ŲĄ8ā?u2ŌzZ +��@†šãp'!ūšrîtSՙsÕÂįÉ3G„ÏSM5'NW4ž(9˜õŅŌO/jŋ|ĮÓkß_ÚŨŽ"b# +ģbŦKӏVįžŽdCáéú|ģxhȓč‡FÁ*-ú!ĩĄ"ĩū"ĩķ4aō„!íÛ·‰‰TDyyđŦn ŲĄ8@B0ŌzZ +��@†šãp'!ŽŸ:ž~wŸUĄ]W…u1[hŨÕaÏ æŌÅ3ļÓr‹„jŋ,øéu=·í'$Iˆ ÏÏ<XYœÚP™}Ē&ũĪ !ę-ú!GĒŦ°ę‡úēdcBā#·>|øîÝŧ“’’JJJ\Õp[ČÅ‚‘ÖÓR���2Ô‡; QwÜčņĖē°ËC::A°%a=Â: §^ÁO[Læϐë#zōR%ܙ—đŋē(đþˆņxMöņš\ņå‰~0‹‡ŠdA?Ԗ%ïÛđĄM›6K–,Z˜˜ØJ$����˜t-!žÂ:Ž +éāb>°˜gļųsíO!\Kƒ:ûE;­‡ų‰FLXAVLUiJC•ņXuÖ1AHī|ųAžųpG?$TĮMžðÆã?îïïŋkŨŪäääŌŌRW5ÜēCq€„����AÝqø“Įē,RAbfQņŒÅĖ‚ÍO4û=5b\!Õvß5ûvoËLŠ,-ˆŊ-K;*ĻˆŠL›—îę‡ZÁJKņ}ôáÛīiÓ­[·ųóį§ĪĪ€„����ZÔ‡; Qs4kUPûUwޙī<ģ°ž?)Ø]fūą`Ë/|AHēŌcŪÏĶ‘a>)ņá%9ąÕeĐGĪ$„E<TĶJôCuĐųDŌ­ëW-þhÖĪîÝšīmÛķcĮŽÓĶM‹ŠŠrUÛEČÅ���PuĮáNBl X3lĀþŊô|õĩÞŊ―þŌëoö{ëíƒßė7rĖāžï›_3ŋ#ąĀįɗúwâ/Y0kįüm>ŦĒ"ķf$î.ɋĐ)MŪ$đt›—'“%úĄ,'jŧũügL\ąxf€ÏZŸM^3§Oęýbϗ^zĐŽŽĖĩĸܓėPýgß*rķ'­ ųŨL7iūí·Š”ŋ=ĐČßņWY'ũCõlēóÝi=õĄˆüįȑV1—@Ýqļ“ĒÓ<Ė/‚Ú úáĩŋ>"„,œ7Ãkų\ïËwmŽ?’—UQ_[.Ȇ4AEH^~õCeq\BÔƧŒš>iô‚'Ŋņ˜ā―rOøķÕ+æõėŲ3##Ģļļ؅ŋAv(‡J'§Õ*.pg !Ѓ#Šd§„Ð<gũD[ÂA‘y„šãð%!„íûþûï_ŧfõîˆÐ�?ïë–Ŋ]đhĩįÂU+æ ĩJÉ XâûÔĖUõôāýðÁJOķlð Ü―#+9ē$/ķŠ$ąū<ÕV?ˆ/?T—ÆYôCeAĖþ0Ïũ& ŸōÞĻyū·rņ‡>ëŊZúá}ũĩíÞ―ûÁƒFcEE…Ŧ:ėP,ŋN)†ˆá,Ķ–ó)Ý%ķ§äīČrmÃå,m$—…lĄOĻĨ°„āĒąxÚAČW%äąžųČK„˜ķLx'"ëāč^rŠÚk"ŽEÞ!NÞągTģLmū î8|I//Ŋ.]š.-JIŠ=ļowx`xĻČö-Û·Ūj•`Ü>}ŲĢ/ôy@8^<æý°,tûƘ}fýPœSYœXW&č‡äËĒ~(5FúŪĸhâčĄS&Zðņ”5.údĘā}ÚīiģråĘČČČÔÔÔÇŧŠČÅÁïĸČPšc e!WfÆ>al#{BjŧĻýæPĐ&ŒÕÅdïy~—w­æĶ#'ŨĻ[I{;Ļ;_bРA Ė?qžŪĒŽ°ļ +;#ޘ›™“eļ#!ūe~~áąxķųųŝûķúĄĶ,ĩŪ,đū<EþōƒE<VQąęýņoZ$Äž9“›1eÜ―ũÞ;xðā€€€={ö…ŋTIv(ęƒ Íe�c)ö”+žĘ%o7ŒURīýzÞݖšđh‡bÔ‘ē'GÆDĶBö<ŋ ŧI­Ē&DģsØëCKpqpō8ČŦž@Ýqø’Â&ūuĢWi^\cMqCÝáúŠÂšĘ‚šōüŠ’lĄVžŦg ŸŨ,YŋfąÏĶåĄcĢķKôC P/?ü[?ėŊČÛžlÔðAĮ>iô's&͙>ą]ŧ}ôQooƒfggWUUđŠČÅA}áP A(E[ AnŽ<+Ææ°Ô đėČW!dŠ ĻqXZíhČU2Ųīė)Ī Ĩ㊄;åĨí51Œ"ųc=AhË4DFæ·ĢĻ;_BĻÞc><íŋåĖM +/ˏ=^[pēąâDCYuEžPąØýŧÂCýwoÜđMЙfýpPĒl^~ļŦ*Ë3뇂ŒˆOŨĖ$Äŧ†Ïœ2aúäŅƒökÓĶ͜9sķoßū{ũîää䒒’úúzWuŲĄ8=ČPHÞđTĪĩ3Wšę*ąWƒą*zŒ%joh‹|‡"TI<Vīi(!—ø]ÛÕĩWQ ęÁÉ5,+‰ŌįęŽÃ—„HJJš1cÆýũßßķmÛ7_{É{íĮŲI;óÓÂŽdŨW–edĨĮÅĮF&Įí3ĶÅį§T&ßŅIý yųÁĒĘˉÚėųΘ7F<iâۓ';æ­ķmÛôîÝÛÏÏ/,,,66677·ššÚU=ÐÔúޅV0u; cŧ+Ėž!cB=Iō)Ų}ŠbŠvGh5718đF„`_ø‚šãð%!***ŒFãĖ™3ŸþyAH<þčC“Æŋ‘œrp[núޒüԂœä’žīōRcCUÁĐĢeįNT4+;V“xųĄ8FĒ‹\<bøkãF yoÂÛïM|ŧëģÏ<účĢ^^^AAAQQQéééeee.l~“#ŋ‘!ųDnß,;ē|mA–‚”ļ"$Փ_•ŸēW ŨÉĄnäRXBpŅȍ’į@NĨ9á&ĒËL˜æKŪēÄ4Ą:M>š5qZwi‹Ēöšðã„Ü3*'ŨPnĒ1Nmū î8ÜIˆÚÚÚââba+]·nÝĻQĢÚÞačk/mðš}pũ–Cŧ―ˋRŦ N7šõÃđS•ŸŸĐųėTõŲãe•FäËýPš•—æ―föĻáƒß7l܈7ßzã•6mڌ=: `ŨŪ] ……….üE d‡â€ĸÔi­žų��īNĻ;wB ĶĶæðáÃyyyiiiqqqûöí›2eJ=!ŅĄýcï{#6jsBô–’ė}gŽÄÃggkϟĻüėLõđ•gKë+2l_~(ˋēč‡RcdTðēĶž0ęÍąoŋ1iÂð{ïđįŲgŸõóó ĩžEYYYéÚķ7„p­žų��īNĻ;ÂBuuuyyyaaĄŅhLJJķøĩkŨŽ1ÂrSbØ >ŸŪû$.Ę;9Ęŧū2ãĖņŌóf QqþÎíˆ3ĮËŦÕeɖ‡Ĩ9‘‚~(6F†ų/>äÕŅĢ†ŒņFĮOĩiÓfÕŠU{ũîMMMm%ĸf $„œVÞ|��Z'Ô‡_ aĄŪŪŪēēēĪĪ$777--íÐĄCQQQSĶLąž)ŅĐÛøVLÄš˜ČuÅQ'ŠÏŸĻôƒ %N5–žj(nĻĖĻ,ģ臜äĀ+ƍzsÄ°Ũčcy„áïï_PPāÚ·(EČÅĸf ���PuĮá]BˆHnJÄÄÄŽ[·näȑ–›#Þęïģ~nT°§19ŽĒ4ųŽ !ŠE!‰ãĩyĩÅ‘þ‹į8~ÔðAF―yÏŋa„„„8pĀĩŋh-ėP !����EPwÝH ’›â›–›ÏuyzúŧÃ#—ÅDn4&ŨWĪžh,mŽÎĐ-K-ȈöýhÄ°ŨƍōðCJaļö‡ $Š$��� ęŽĢ3 !Bū)1z؀­„ų.HŽņÏK Ŧ.KNņÞ―cå„ŅCúõé!čAuXaäįįŧÉ# d‡â� ���(‚šãčUBX ߔxąįsÓßė=7pãGū >š6ęõŨĖ?Dių!)Ë·0ēēēÜį†ēCq8ôŸ}ŦČŲžīv&tBn­ƒ ĘߞTäïøŦŽ“ûĄz6ŲųîīžúPÄ ƒŲis ÔGßB„|SbÂčÁ>kg }Ģß―ũÞky"888**JPnō- [ČÅáP áäīZå�؉ü‡t]„†Đô4~īÕá !™GĻ;N+‘p7%žxâ‰ĮîÐĐS§5kÖíŲģGPEEE.ĸ!)9d‡â`ųuJ1D g 4ĩœGHé. ī=%§E–k.ÄĩQRay•Č%rČããF‹üŨۄaC(ÔD™ō:ðëhEí51Ï/ÆélâđëØ3ŠĐÎÔ§UIųM A3M >ĢĒĒÝíēCqðû?2”æƒk#r.3ķĀAîU“ŠąĖJQLöąĘŊ‹ĩš›Š§3ï›#ęJbbëgęˆåęŽÓ:%„ۛééé‚lˆOHHŽ + +Üá‡(‘Šƒú CsĀXŠ=劧„r YÝĶČ!ļĀų™ +ĐsļöŊ:EMˆfϔÔ†–āâāäqWyšãīf !bđ)!h‰ĒĒĒââbáØ=ï?X ;õA†C%Ąm%cs™Pã�d$]'_„ ē?üĐËĩVÂÔrœČOđCi{MĖģ9›ZÏ!4ŠÚŠÆ6PwÜAv(E2”"Ģ1–bOđÔĒq‘åņ[Ï +Đ!Jû)!‹°_B /ņëbuíUČÞÏzBŅJÂØáüBÝq@BpŲĄ8ø}BČ"ļŋElQ!çTũąĮT4V9õēVsSõ”īMŦ'ÔIÆÞãꎂ;ČÅÁō É'rûfŲčåk ēĪ$Ā!ОüŠüT’­IķúÖO―.š#ïIIļ‰ķ–"“KŪēÄ4aĖŠZ+.PÔ^Ę)äymÂô9Ōģš:Āäh{ŸSĻ;Hî ;ü§N[+ôŅR���ûĄî8 !ļƒėP­VB(ýc“ß–��h uĮq ah‰#ōŨ$đËŲĄ8Z­„0)žČuK��4„šãļ•„ œjžŋ““kŲĄ8āßl���Š î8n+!$!’ŧ’K’cņ“M~Ŋƒ؄š ,™D[ČÅ���PuĮáBBāDá*nĮĮĨ%â2$—���āęŽÃЄ`<`ŋjOđŠ2·ēCq€„����AÝq@BØģ<. !"fĻ"g{ŌڙÐÛYã üíIEHŪ§ņĢz6!ãģgĒ§>1Č GvZÅ\uĮá]BČ?ÉņĐW‘ķŠÃĄÂÉiĩĘ°‰ á;%„æ9ŧ'ÚępŠĖ#ÔĮm%á^šc;ՂŠ{\HđŌ68øŨ)%§äīČrmÃåōĘ?‘E2ú +įJäąÜŋČK„˜ķLđ)ŊŋWÔ^óübœÎ&žŧŽ€=ĢšÚáÜAÝqÜJB؂ŧ* d?–"s 2% χPĒ$‰ķŠƒßĸ‘Ą4y›Ķï…ŅA WHÃĀ„évu1ŲĮ*ŋūÖjnŠžÎHŨë�ÂJ"?VÚ{ÜAÝqÜGBčũ—ķh.Ką§\ņ”P.n"ÛÓ +@ÁΗČTHÃĩĢÕ)jB4{ĶĪž0īw ƒžĘ Ô$„ķ0·&4„ėPÔ•„Rī•ŒÍQŨ +€ŒĪ{勰Aö‡?uđÖJB˜ZŽų)w(mŊ‰yv gŧ#x‡Ð(jo(Û\@Ýq@BhŽ8f”?ŲĄ8=ČPHÞ|UĪĩ3ZšŠV�rä;”<\~ŽhŌPB /ņëkuíUČÞÏzBŅJÂØáüBÝq@BpŲĄ8ø}BHXÁXV<Ĩ­�(•äSēûÅTäeNÝ­ÕÜT=%mÓę u‚ąũļƒšã€„āēCq°|#Cō‰ÜūY6zųڂ,) pEHŠ'ŋ*?%äĀļ�T 6 ÃMīĩ™\r•%Ķ 5ĻäĢ YN=ŪĻ―&”SČ3„ésĪguu€É;Ðö*.>§PwÜAv(ŽÖüŸ:EôŅ +���į@Ýq@BpŲĄ8@B˜ôŌ +���į@Ýq@BpŲĄ8@B˜ôŌ +���į@Ýq@BpŲĄ8āßl���Š î8 !ļƒėP !����EPwœÖ&!.^žxþüyWŨÂ.ČÅ���PuĮi%ĒĄĄáúRSSKJJ‘ŸŸøðáęęjWWM1d‡â� ���(‚šãč^BÔŨŨ777_ū|Ųh4/\ļPĻĸ!Cęęę„KđđđÜ ēCq8ôŸ}ŦČŲžīŠ‚pr(”ŋ=ĐČßņWY'ũCõlēóÝi=õĄˆA9ēÓ*æĻ;Ž^%„ Ž=zãƍŦWŊæååegg‡„„üņüŸĸųŸĸøĸ° Œ={ö1i!D(//ŊĐĐqu­™ ;‡C%„“Ó*ĘAũs܅ČHĮŅEh˜JOC[ÂA‘y„šãčOBÔÖ֞:uęŧïūŧtéRUUUJJʧŸ~zĸýũ·iÓæOúÓï~ũŧĸüÏĸėÜđóļqãžyæá    ąą155U8ĻĻĻĻŦŦsu (ŠƒåŨ)Å1œ%ÐÔr!Ĩŧ$Ðö”œYŪmļ<ą\B>�#äŋņqĢE~Œû[ę>d|qdĘëĀŊũĩŨÄ<ŋ§ģ‰įŪ#`ÏĻĶv8wPw=Iˆęęę .âáâŋåå剉‰B‹üņ‡~øhÛķíŸĸüįßĸþũĸõ_ĸ%4A™:uę[o―%{xxĘAHž‘‘Q\\ėæÏ5ČÅÁïĸČPšŪÔü ;PÅ00a<Ļ.&ûXåŨûZÍMÕÓYŊs‡š’˜Øú™:bđ€šãč@BÔŨŨWUU}õÕW7oÞ<sæLQQQjjęšuë:uęôôÓO?ņď<ōȃ>xß}ũÝsÏ=øÃþûŋĸ[‡'N\ķl™pÐđsįØØXA<deeåįį ššYXČÅA}Ąđ `,ŞrÅSBđė ‚ œ/!Đ:‡kïŦSԄhöLI=ah .î@y•Ļ;ŨĒķķöȑ#WŊ^―qã†E<äåå7ŪgϞݚu{öŲgŸy晧žzęąĮ{衇þō—ŋÜ{ï―âë<ðĀô;lÚīéĨ—^ÕŦWŊúŌŌ’ĩk„Ž„Ė]Ý>4d‡â >ČpĻ„ ”Ē­„ 6‡p°rW‹pŅČ€š ģŒÂ)w(mŊ‰avČ“č BĢX–dd~;Ššãp*!jjjęëëŊ_ŋÞÜÜ|ėØą‚‚ĢŅ8iŌĪþýû zā…^čÞ―{—.]:vėØū}{ÉģŒ1cÆxzznØ°ÁōC`ÖŽYĩFcŅėŲiŊ―ķķC‡Ýŧwgff +âÄÕ­DCv(E2”’wdií D–Ū(Ā‚|‡’‡S%cöKä%~€šö* +dïg=A]ILĘ;œ_Ļ;wBĮûúÔĐŊŋúęðáÃYYYiii#GŽ|õ/ŋürŸ>}zõęÕĢGŪ]ŧJžežņÆĢGž9sæģÏ>+īBœ={vejjņėŲĐŊūš·[·°Ū]―ž~zĮŽ‰‰‰Bæ.l&ēCqðû.„$°‚‘W<šĢTBOUļSŅXåt h57UOIÛīzB„`ė=î î8|Iˆššš7n\đxQPyyy‡хW^yĨoßū/ūøâóÏ?ĸÜsÏuîÜđC‡O>ųĪ /^<dȐÁƒĸņ|ęЧÖŊ_ĐĶF)îéÖMÐ{ŧw}áABøųų 9ŧŠ™dČÅÁō É'rûfŲčåk ēĪ$Ā!ОüŠüÔ6OrcÕl@†›hk)2đä*KLjPÉGē&œEí5áĮ?đgpų˜ļí72Ô†[@ČÎ)Ô‡/ Q^RróæÍÐÐÐÓ§O ’āU čŨŊ_ïÞ―-ŊCĮÓĶMóōōzĸýũzčĄûïŋРA{ũî―\[+ˆ‡Äþýũ<ũœĻē§OïßÕÓOûúúÆÄÄī !·k9.���·‡šãð%!ōrrþųÓßĸ~š1æĀīīīˆˆÉ]Ëë'N|ï―ũæϟ?nÜ8ËëC‡MJJúá‡ūĸþû‹xø·~(ZžļvÛķĖũߏ$D‡>>> !X���CÝqø’iiߟ:q!*ėfEŅg55{víĘĖĖ\―zĩäY† FýöÛoŋûîŧ:u"œ8qB·nÝÚŋĸÁƒEýpdÃA<dOŸÕĢGųŠU/ŋ $���`Ō„HIJúþôÉŽþ/VL™ð}EŅweÅĨFcrrō&Mš$y–1{öėM›6]ļpÁrįaßū}ý+臄áÃņ8|xTũîeŦV^ū|ßóÏï$Ä3Ïīr ����&ÝIˆ$ABœ=“ÝŋWÖĀ~Yý^8ę―šųpþÚęÔC‡âãヂ‚FŽ9pāĀQĢFíÝŧũįŸÄCssģplŦĖâÎó‹‚đsvėĻ ÄCī`={F w ņ!‹Qwū$DbbâO7oæLŸýJïŽþ/_z>ĢÏ gķnþ67óóęęaa‚NČÎÎÄÃíÛ·Ŋ_ŋ)Ũ‚ØØÛ―{ŅâÅfņÐĢĮū;âaϞûzöÜŅŊ߂öí—/_ū#p‡ W*Ę+\ÕRvJƒa/Ųt)!~ųå— §OŸ-.Î<ĀøRĖŧ§wï”ŌŊũŸËЉÍĮęnÝšõå—_îÚĩKĒ:'č!ABDÝý°ģ[ũõŧ.ėÜ}ã ū}7hÆĸIųž?cís‚}ýórr]Õ^$ !ĀĀĀĀĀmz•—/_ūxņbSuu]xXfïé=žMíÖ)ųđŽ)];ž‹?pá‰~ˆ‰‰ąč‡„„„ĪĪĪÔÔT‹~ˆ~þųý/ž1dČŽWßōŸ0Ĩt‹ũ•ŽÄæōŒ›é_§FŸð­\3oũäIsßĩÞk­Ŧš,Į}$„Éüše‹įĪĩ3ĄK§$ĐÎÜĩHōØÔ ýÆ>läœßųÜ9ÔA-åĻïļžVŪë }Jˆ+WŪ\štIP‚Z8‘›{tóŠÔ.R:·Oęüô…`ßúúz‰~ˆŧƒ6%%%===+++Ķ_ŋCÞžÅoöÜéÏũ9ķÕãJRČõžØïŦ38šwŦÚøMVĖĨƒÛ.ėöšīßûíŧ>˜=gôäôÔ4W5Ü7”NNŦUîfÜĩHRa'ԟ# aɐ;Ÿ:Âxėëė€NЭ„ļ|ųēEE|þųįŸ}öYCjjĘs“:>õŲöM ‚~ˆŽŽ>pā@lllRRRrrē ŒFcNNN^^^AAAüāÁukßųÛŌî/ÍûYāÜŊø^ËÜũý‘īr q-sĸÅhï {V]ŽŲvÍļïzqRî§~Kߛ™žšîŠķ‹h+!äJ[\ú%Ó )Ý%ķ§äīČr ˜õ™žkājŽk{ŧûSÞcļ>áÅpýO$ļ6’]`›VÂR7Š7Đõ${WÜļeäŒ=Û†sœŌžäÚô*!ūþúkQE\ļpÁĒ"Ν;Wå―álČķĢGŠú!>>^iii‚~ČÎÎÄCQQŅáǓ‡ óîũōć;íyuPÉīQg6MûrŨšŊS"š'ÝŪÍūUųuzԗQ/F­ŋšö]qâíúÜO.ÚōņļĐŪjŧŲĄ8‚°ø0âØĐŅ”æCm ļ8§ äþäŐˎRW*ōcnä"ĻÞTáYöæĻh‹ĒüĐ TÔJŠ-Ŋ3ûBÄi{1 7 !聛7o^ŧvÍĒ"ÄĮ‚Š$„á›ĮÅũ ‘’’’™™iųŸ………đŲ•••aƒ_ŸøXįüAŊ'ô˜ðÚëÕsƝóųäŦƒÛŋ+Œŋ]•yŦ"íJ\ȅÝŦ.íĸôz^œ ~n*ĸõRýŊ&ŽŲē~Õ:W5ßŲĄ8Ļ24_jKą§\ņ”P.c%íŊ5gšđ™ZĒĒɌžb-„šąošø‹ÚŠÚB.ķ#LūČĻh8ïĶK !ˆ‡šš‹Šg*Âr#âÖ­[ĮŽģ|S –[999Õą{šVÏ9räČō^ýĒ_|vō_ëÞ~3ïÕŨr†―ytÁ{BW^Ï>xģ4õŧü„ ŧ|>Yqé`Ā’”ŋ/ú勚ĸwõøĸ]=þóųš%c§æįæđŠšö ÃĄ‚PŠýKœ$[ĨIâ‹pŅäáōJŠ§Ū]îoÚn”,.S‘2–qžY:ah)m đóa`;Â$ufq"ē'đ6]Jˆææfĸoŋý6;;[þ8CĮ·üþC\\œßōþd^^^QQŅÉ-KÏyÎ(Č/XŲó•“s&_ZøĢÏž3žâõŨKG =å9íüŪ /e|ST{no|㖠_D‡}W–ýãÉō|VũËŦMZ―y§Ŧz É)2”’Ũ +ií ”—.ĸÄå#FČÜþæģ4Ám ·ĖŠÛ(Y<Ĩ47nbw yČiØ3„R``;ČTH—ŨŲ 7 ŸðëŊŋÖÕÕĨĪĪĪĶĶŠ/Eˆ3 qâÄ ‹~HHHHNNÎĖĖÜđsghhĻ !voŊŪŪŽÞĩ7jä{ŨW~ãģčëusŪxL―øáؓã†ýuÜ7Ĩ'ûņ·ýō/Á~þę‡ÏãJŋ-Ęŧ]Wrŧūôvmņ­ęÂïäŸÚģoó'Ë\ÕM­ï]I adYŌYŽÉ§Z5ŸQ€đģQ%ē™öxJs ĄtĻģø‹\4{/)ęØÚcG)Þܙ.%ÄŨß6Ũ6žū~ýzMMMddĪäqÆíÛ· ąuëVáŌôéÓĨáëë;räHAK˜_„ĻĻČČ.üdúŌōĨKnÜvsŸOóŪ7‚Wģeá…Åģ>ÜĸۏĸũMÃų#YGūĻĸâŨ[ŋþïåŋŸßŸųM–ņcÆĩīÔŦɉW’âÏïÞ0}ayyđŦ:AC !ÎÛÝYüDnß,‹‰$ŪÛS\ZdXĶ9uúã*†ËŠÐ.r4BÉcōĩø—YIŊēŽą,ýÆâ,œY܄t ÕģŒEģO.Ĩý[[#Œm~ōØRb'čSBE§§ä– *ĒīīôÔĐSķ3 qōäÉiÓĶEDD 6læĖ™BĢrrrōóó3ēr6ïˆúÛRŋĐĢ?:đ}ˏÆČ3wý==â‡Ô·‚Ū„ĸýøĨ_ŋû9zÚÂMë7íÛđïĘĐ+ĸúå_įũåŸÜõypÄgÁ;Ï… +9ãïðÎGE…EŪęēCq°ĸ.゠fß܄þtSsĻkt?đôÔ0Kˆ™{rϞĸBüv†åq† !Q1`Ā€ū}ûΚ5+))Éh4&&§-Û<dšŨČŲë'/Ų:uôĮM{ƒþ·4öįŌC? Ÿ‡c*ý69þ_}ĸóÕ[oöööÞŧ{ïųÚó‚„øbáąå>'žüŽYlĨï1Ŋ-þc暊@BčĀ ?ÝÖ@Bļmï9Ųô)!Ū7G&ä…Åd ī?=·īÚöÛ‚„8}úô AƒŌŌŌ222ýðŅ’U―âąÐ#7>ũö•Ûŋýø[wÜąu;ŊÝŲļ*ôĻgHƒG`ÍbŋņŸ”–”šŠė”TCFƒĸōĐ­Aš­9Ô5šŸ\zj ˜IâÚõ›‡ē%ĩŧârƒögėIŲ—”'Ļˍˆ~øáĖ™3ýāõiČāI‚$øõŸŋ5|y›%ĸēĶfÁ„$ŋÜü巟~ŧZtþČęČã~qĮ}â7ĮÝpāčš―å‹|§.ŽŠŠrtcqØ'!����€ ęŽÃĢ„‹1îNČ ‹É +>°7eëŪÄĀĻ”SgÏ *BgϞýtĮîA“<zž/˜ ūøö§ˆÔ#Đ Ņ–nØ.$đÝpéóĀĪÚYŽŪÜyĖ;áÄv㉀ėãþ™ĮýŌ’>ôõ^ąÞU=Ð���p +Ô‡/ ‘˜tízsøĄėôŠЃ™›·ïō ‰Úļ}ïÆ> OČ(ĻĻn<UÚgÜB‹~°Hˆ_ý hƒ1 D[ķ)HHōåĶĀĶÉsÏÎXqrųÎÆuqĮ|Œ'wŸ)9\īiĖÜØčƒŪę&���€S î8|Iˆ”””onÜ =hÜ—#HˆEŦžŨø†zŽõ]šöÓu;,Ú‘WqtwBnŸņ‹THˆ_ý5(ŪhŅZ?!ÉõÐ‹sž›ęqvIØÉõņĮžģO>zĪÚ;eæ˜É5Õ5Ūę&���€S î8|IˆÔÔÔ/.^ăąĪ6xúĒ5[=6lÛŋ`ÅFŸ°˜%[vå•7D&æõŋ)!pŲž={ķūūūđđyûœųŦ|„$7"\öXsnŌŌģóBÏŪK>―ĩčÔöōĘõ™ôŸāÂïbX ;‡#$„˜ĄŠœíIKNJəlpPþöĪ"$ŨÓ8Q=›ņŲ3ŅSŠd#;­b.šãð%!ēģģ―ÖŽ[ë&‰åë|Vû†ynÞ1uîŠĀĻTŸČžē†=‰ųŠîBüóŸĸž}ûvóD ņÝūĪŦëķŸšâôœ Ó^)§?-­Ų˜ģiä"Ÿĩ[\ÕvēCq8TB89­V9�v"q#<b§„Ð<gũD[ÂA‘y„šãð%!ĘĘʒ’’<==?YžĘwgĖZŋˆ…ž›Ŋņ―hĩ§OļįÖ―ų {“ō{]`ŅÃfŽ&Hˆß~ûíįŸnķA”ÍŒ_ûD~>gÉ‚N,InôHY2pĘF5õõõŪjŧŲĄ8pBŪī-ĮėĶ–ó)Ý%ķ§äīČr%EË3'§ī‚ü7>nīȏq>" BĄ&âȔŨßáĄĻ―&æųÅ8M<w{F5ĩÃđƒšãð%!ęęęJKK322üüüfÏ]äđyĮÚ­áŦ}Ãޟĩ`áÚmž~w%„ ÞYā=hōr䃌ӧO766V·Ī…„8”wmûĄ ËýËĮ­ÛóæÂi/ŋëŠVK ;RBāVTävŒÛĢ‘ėÔhääœu°Mļ9ČRÅ00a|Ī.&ûXåw`h57UOgÞ7GļF)]ĮĻ#– Ļ;_B ūūūžž<+++::zî‚Eëķ.öō^·-bŪį–æŧGĢS &-ōÄCŊŅóŧ―õü.ď?þ،A”Į|#KmÞ3æã Ģ§ûymČÉĘqa“%Šƒú CsĀXŠ=åĘ/QÓŽ€°›8_B S!Į ŨĢBi{‘iŲ3i=ÓĘÐ\܁<ō*/Pwî$„…#GŽäįį'$$Ž^―zĐŨÆÅŦ―?^ūiŲ–ABD&æõŋĻëĐ/ŋ1âåWŠ⇟þ!č‡üã8ýÐxæ3QBė\å}ðHÅW·U +ŲĄ8Ļ2*!ĨØ/!p§ú˜Â!épų"lýáO]Ūĩ’bYļSîPÚ^q"3AzGũӊÐ(jo(Û\@Ýq8•ÕÕÕÅÅÅþþþ+Ũ,^í;éã•éųåþ1― ïŨĸå1cÆlÞžY”‚…%—ČŲÞŌdûGÅS‹„puãHŠCŅƒ ĨļÍ]uZö@ÂĐîŨ:—Ģīį‘‚ąû%ōŋC]{ēũģžĀ5ʞįęŽÃŊ„húũCœœœĻĻĻ+V,]·mËÖĀĢƌ?ÞÛÛ[ĻjLLŒ(!ÂS+RsË-Ŋ=;vėÚĩkÍÍÍB&A!aĖ[ą|KHņ�ũũˆ<wĀĻ4-Y?Pë hˆ +ņF8%oXŠb*ŦœŽ ­æĶę)i›VOĻ“Œ―ĮÔ‡k aĄŠŠŠĻĻ(99yÛķmK–, ÅĄC‡ŌÓÓ + +D WdŅïϘ7sÁJA?œ={V8ŌūũÁĮközl +jmÂds·ÍÔr–Ž„@“lēČŨd)rI OË"!$Đ$z]čÜyĸKÂMīĩ™\r•%Ķ 5ĻäĢ YNGˆĒöš0ÓP“q:›ļí72Ô&ï@ÛŦļøœBÝqt !jkkËËËÁ••e4srraPQQ!„[$DHbĐ ÁÐØØøÁ\å[BÄodŅޝ6{•ß.ˍˆÖ&!ä Ģņ8 xŽ3��€û@Ýqô!!,‚AUUU§ø‚Ø°5xGlū ŲpíÚĩŋ}ļpåÖ‹~8räˆ 9ޝþŅjĸ= !,€„����L­LB Ų·oŸ –ŊŲžhÍÖøøøōōōÝwˆˆˆ Ųīi“——ŨČņïŋųŨQCGŒýØcÃĪ™sAB0š9<Ö��Ā} î8š—ŅŅŅ‚*0ÛķmëB/((t…åTPŪŪ2 ēCqĀŋŲ���AÝqZƒ„Ðd‡â� ���(‚šã€„āēCq€„����AÝq@BpŲĄ8@B����Š î8 !ļƒėPJä—ÐБ5GßđÖ”ŋ=ĐČßņWY'ũCŅ”D&Īē'įƒ rd§UĖ%Pw^$„ħÎŊ€û@v(GHÍ#ŦËVũģØm‘ĸŽĢ‹Ð0•ž†ęķ€„ãë›û@Ýq8’„ÓVŲĄ8X~R Áh?…‡ÜSX6rÎķĨãŌ·ü7ūĒqÅ28Đē Qyø?ŠÚkÂ;…ė)\>&žŧŽ€=ĢšÚáÜAÝqx—–ÛS ’ČōhäTČøō ]ŲĄ8īú7[’%—9Pm%ųŠˆKÎûôÔHĻW&ĖØP“0ð$üŽuíU—w•ßÞ#@XĢäĮJ{;Ļ;Ž$rĢ—JbRS‰*''\Ĩ"ČÅA}ĄbĐgObĒ-8öĖD~§§n 8Ũų™ +Đsļ9JۋLkįžæšqZ‚‹ƒ;ĮA^åęŽÃ‘„°Å6œ|L ””Â~ā*ČÅA}áL A($ŋH<%_„ ē?üĐËĩša€KE8åĨí5į2ĪwĻŽāBĢĻ―ĄhlsuĮáHBPÑĮÔĀĶ–úS’K:ÁŲĄ8īz T—ē&öd8ų%—+ōŧĮĮ›äŋƒG]{ēũģž ŪQ&åÎ/Ô$9NuŠähČÅĄBB Å6.P’a!ŊKŠKœR A>e,1Y)ïK―ęöŠH‹ŧĘiŨ‘Q'!ôšFQwœÖ#!,^E*ꁓ!;Ë72䋃dČĢ!ó‘_’”ˆŽų@ū^IJ\‚Ádļ‰ķ–’ý(Tdģ QdM8EŠÚkB99đóWŪž 0yÚ^ÅÅįęŽĢ' ŅĪðČTļ˜†–JÃ%`ėPüþ:%§Õ��āęŽÃ‹„Ð~kn ŲĄ8@B����Š î8š—Ė3 ~!;H���@ÔGũĒ ótƒ_ČÅÁŊ„����\uĮi BgŠ$��� ęŽ‚;ČÅ���PuĮ Ád‡â� ���(‚šã€„āēCq8âŸ}ģdšEßlpPþöĪ"Į_eÜES™Ȟœw 2ȑV1—@ÝqÔIˆĸßÞÝ?YQ +ŸōSŠvkïÞĘþQã&?äþÝĻIŠē›J•[Ū–IęæūėfóRw·nbŪđæ5ETD†·APy™˜gf80 0C3Š(—€15VÎöĖ ĶŧŸ§Ÿ~Nŋ=O?ujęLŸ~;§ûœþNŸ33Ą ĨJˆÔG†YÂH'ëEĪ8•M{Ķö}!!Âx}óË.!ÂІŽ]št)õ„ðfî"šÞĒüŨ)ý#DTY“Č…Š"’Į?é~ĨēsJÆôP—îĒáu0w/Jtëâ"ßRŠÏJk4ģWĮ>āÆÉ4!jČWę ûŠxI—L"š<rGÕ[ĻŅÏM;DnýŠ.Ø7ôƔėx+æîBzũWoZŅ­æ>zÚŊQĒ+’y– a“,ÎBx4^ęÕ'ĐĮ―āĪxÐAþ$7ĸ„ˆœ*ēsŒÞôZ]2šÆóÚčPĪåjĒqDWÂãDÞj +ÂsüøņņņņĄĄĄ}ûö―.š2}##τHeĄáE XM~n ýāûrVBÔŊÞÃß'éý­'ÞEn럀’;ûh$Ú·@B4;vėōÅËî:wuuõõõđ!Qôé(Ñõæ“âš á#TxxlB(.Ēų„ˆžÉÜ]Hïþ&Ļþ8ÛDû5*ö&‘Ūņņņ‹“ýpęøGîŨ5kÖôôôėÚĩŦčõJ,į„ˆŒmŅĀĀ|$Ŋ3Ŋĸąk‚B$Mų·ō#Ņ˜’]Tņ@Y~ÚũWcZŅ­†>trz Ąø臄pûáŌĨ‰~8wúâĨ‹—ÆþÆ―ūjÕŠ-[ķWYĸFFøÅ!ð,9ŸðM%FîŦ9$ZĨÅ'rx=îĩ4rōĀ­*cÖÕvŅČ51tGJtëQÅû*ydŸ•ÖˆÝÁ ĸVŅø†ŠxB;vŽŅ‡>ū|ųōŏ/ĸî·ũũœp‡Ž\đŌļŠČôã”%đōFß#�(đ*'ÄŦŊūÚč‡Ņ=Ü~øðýKGþæĢ.î;·Ũ›&VDÕ"ō'# ~x�#T6!ž~xeïÝ+įÏ^<včÝąýoŽœ?óÆï‡koėÚqŌļŠĻZBÔĨįQMž;�`j&„Û—'û᭓.üéŌŊßš°ũÛ}›ßÚyæāðŊũyýÕwvõė}ÕŽŠĻ`B��ŠRÁ„ðúá䱏>ūpų„óÁ؁ßÔ^~Ŧý§gÓŦ‡öÛ[{swĸë‡OïØvl{ÏQƒ*‚„��äĶj áõÃņąũ/~|ųßNĸþ•}įœÛēîØčÞģĢûÎî:3ēëôóÏîėÜp`xũk―[Ææ?ąÉ”Š !��đĐTBŒ7úáÕW~ũáï>>wæũ†Ïlë:þŠƒíkĮöï93R;=<xjhāõĨó_^øä槟ėZš`ë‚ŲíKŸî1Ē"H�@nŠ“Þų‡c‡Þûý—ÆFÏŧÁP{síĘ}ëVîáŲýÏ.ÚđéÅĩþĩūëŸ^8·įÉĮ6-šŋeņS[Ėîœ7kcų+"Ÿ„HũŨ'éŧĩød4ĸfĶ’ĸŽŋæ:•Ęý•O;P}rÓĩ„ČGÎmÅ +Q‘„ð~ĸblôÝũßýxėāŊũ žj\V· =ß6īré`ÛÂKŸîíßzl{ÏąíÝG[įn^2ŋ{ņÄeób7$æwŧCJ^ž… !þM™Ž‘âT6í™é>=IˆŒF6QbâüÃĮ“ýpāß―sáõWßÝÝĸš{ŲÕrgïÉ‹ÚnßžáāöÍcO=ŅąäĐ-KŸęY2ëây›Ý+ËôīN&Ä3‹z—/ėÝēá`™+Ēĸ‘Ņ"ø#l*ŋh˜§hþĐ,Ĩ^gŪä?ã6Ÿäščg―ĀMą?†wČ9p“đûRĒû[oų–ŠÚÓ°™―ZåEĖ,Ö'ÄÄų‡ ýpäĀ;ï―sáÐþ3ĩí'k}'vöžØ6ūnåðŌų[Ėî\4ŊkËĶƒ+–ž<gúšŲ3Ũ͟ĩąunŨĒy“'"æõ<ŧhûÚŧû{œ[đ_[ĘZųĸ ïŠč5J20r‘/z’EĮŪŠđ-ÔwŅžÓä˜ōŲÅÜIïþęM+šÕÜGOBt§Ô_-%ãĮøĸYščŪÉ+ûß>ûևýāÆÃËĮ·ïčqcāčâyÝOÏiŸõðK3ï_õČīÕí/î{zvûã­yę‰Ms:—ĖïynIĮ‹ûûÝņ·ëëvz·}đsŽœQTBd10­Ē $G“ü"rŠČßč―(éýœ6­W�›ī\M4ŽčJxœČ[MaqB;vėã>n™øĸįϟýhtß[;{ŧý0°mžËŅūÍcÏ,ékÛ9ũąŦÛúV/ï_ū°gÝŠkVė˜=cÍžY/-xbÓŌn? Ž[9<ļíøĀÖW{ŧÜx˜č‡mŊto-aEdôoķęI^+"Ÿ_Y$„âRP ~ŽÜŲä/Ũi%„·,Ņ·ÆIzëQ%öIZÁ§ĄäNÅ>‰öm#ؚ‡þÝđũÝuxóė›ėßýƎ­ãý[Mœ|˜8pdísŧĖnŸũØÆũŊ\ŧrpŒ—gÏxņĄ_-ŸöËķ93Ũ>õxûâyÝËô­jŦmí82q +ĒĮŲÞíļņÐÓ~Ļ§}īkӁΗö·”Ž"J’Ē™$š<­Ĩ @á#TxxlB(.Ēų„ˆžÉÜIïþ&XͧĄčN5ó€›Ëʄ8tčÐŊßxÛ]ÞÍcÃŧũo=Ōđ~ĸ–M‡ķu™h€ŽC/<;8ïą n*LŸšrę”ÅSï^<cęsÜģėßĸŧŋšfŌõjnūųw)‹/îîî*ęþz2úŒØú-uÁ+ģ<!’v…ŅUo“Ī !ĸV~ĀJ4ĶJēšþRŊ}5ĶÝjčC'§—ŠžqėK·Μ<ë.―kÁ­ûŧ;öŊ]ĩóĨÕĩuŦw―ôüîM/·ÎkŸ3sÝãÓ_œųĀĘÕËw,˜―ņáûVŽjë_ÕķãģŸýėå$N:500ÐļŋëÖ­ëïïß·o_!ũš!į„Ļû^%ÂÃS‰JĢŪðD‹Ąd}P ŸČáõļŨŌČÉ·ŠŒYÚ="wæțdwēŽÝßzÔF‰|ö)>ŲëÆ>nrą;Xøôß*ßPö%D­oÄ]ôKŦũŽYŅŋú™ūUm[W-ßūjyßē…›{xõCŋj{øūåO]~ĸÝËĶNi{iõŪõÏïŲļfOûÚáöĩ{ ņá‡Ráb” .ėÜđÓýšfÍw‰ģfÍÚ°aƒ[ÅÜëIVþuJ―ĩ*į}�›X˜ĩÚ3‹;ÜĨßóÓ§ïųŨywĸdޔ;įLđóÉ{ïšïÏæĸâÎ9?ŋóņ™īÝûģ§î―kÁĘ%}žßóŨĸņ?%zĸâ›ßüæO~rįųóįŨŊ_?eʔï|į;_ýęWŋþõŊ·ĩĩuwwïÞ―ŧĻ;^ņ„°āĮF�0ˆ} ągϞžžžGZčŪĀ/~2į§wĖšëŽGîüጟüpæ]?šõãĸ;ãŪ>ÞÖÚõĖĒîĮ^=ĸ‰—V?ӟčý‹‹/6ÞŋļõÖ[GGG§OŸ~Ë-ĸãSŸú”[ ģgÏ^ŧvm__ßÞ―{ đïOˆš'Āö%„kpp°――ýžŸ?2q.â_įüóĶýŸŋŸrŨi}rÃOĸå‰;þßôĨOwļ—å­[–·v?ģhģöû·Ývۉ'ÆÆÆÖŊ_ï&ÄĖ™3Ÿ{îđŪŪŪĒ~AÃʄ��”“• áØīiÓ―ŋ˜X‡î[úŋĸųŊĶ,˜óØ O=ąîįw>ņôėõ­sÖĸÕøëæßŋļûîŧ݊pįÎgúôémmm6lØącG!ũš„��äÆքĻ]ЈĮ[æŪɏþéÁ,|ÆĘĮgŽšýčós}aîŽĩzŋxĸÂ}@:ØßßíĩŨš—,YēnÝšūūūBî2 �ČÅ QŧRģf,vWæŅiÏ<:íŲÆŨŲ3ݐX•Ęû_ųĘWvïŪmÛķ­‘‹/n|Ēßî$!��đą;!jW*b惟Ūœy›{yôå>ðĖcÓW4âĢ>’ÄÅ?û“+ōý‹Ŋ|å˃ƒ;܄ļîšë ņâ‹/ڝ‘ĢiįGnݒîjCQ‹OFóof*ųïøkŪSųĻÜ_ų„ąÕ'7]Kˆ|äÜVŽÖ'DíJELðiw•ĶO]6}jیûÛÜ+þ„ļāó‡+>šâƒ>pŋ;}úôŒ3ï_|ųË_ÚÝŨŨë&ÄÃ?\…„ˆTþ„(áŌ­þC:Y/"ÅĐlÚ7Ō}z’lĒ*$Dí/ą`âӕS—>tßŌï[ę―‘>áÐāu„;ÎûïŋĸÞ{ï―ûîŧũ/ūôĨ›jĩÁÞ^;"ō/-ķhýuJĸŽT41#gžÛjC‘üg|•­9ĶčĶ؍Þî‘{Eā&s·~Ēû[oų–ͧnōC'ŅĖ^mßËKEĒvĨ"ž6QÓ~đč_.j$„Ûüã}įÜ^xï įϟ?{æĖ™Ó§Oŋþúëoŋýķ{ÅĸþÅM7ÝÔÓÓÝÕÕUÁ„žtŦLĒ>Ïðš^Íäë“éjC]ä+ĪúĢŧ ôÆTŲyL?ęÝ_―iE·šûčIH^ĢÂŨ“>zÆĐNBÔžŠļĸ)wÝîĸek#!ÜTøÃï]|č?íāfÄÛΝ;wÖ―œ:õšĸý‹›nšąŋŋoÛķž*'Dóëq/8ŠÏÄV$7ĸ„ˆœ*r/2zĢ'―ŋ‘ÓĶõTēIËÕDãˆŪ„Į‰žÕ•JˆÚ•Šxpę|wõ áFŸO:4Î:Lžv8û—'NœŸtôčŅ#gΞå8cþũ/nžņ‹Ēõģ˜Ę-įWŌ„ĖA4ÏðÜ2Zmh oēĀ†‹Üjō—kõĨē3Čw*ģ$―ŋuéó.r&Õ|ÖHîTėĢ‘hß6BÕĒæUÄ}s áFÇFœv87ĄŅođ—·Þ:}ęÔk§OŸ:|øĸý‹nļÁí‡-[ķáá[õ&!<fėÁ(•Õ†šð*<\qŦÅ.Ēų„ˆžÉÜíŪw Žæģ&ö5Šžü7WĒvĨ" áÖÂoû›ÉT8>ípäČ!7ÜxxíĩŊ―vÜý:>îøßŋļá†/nÞÜnëg!bę?ķÔĢ^™Eó]Ļd)­6Išōow •1íN†nzíûŦ1­čVC:9―„P|ôŒS̈́ĻMVÄõŨ_ï&ÄŲģgß}ũ/ŸvðŸvðĮƒÛĮO\ÆÆûßŋpĒŊo[OĩodÔã^Õ#“ üę˜bBÔ/VYŽ6’jņ‰^{-•o‚ĀN%ßXá%Jö" ^áÝßzÔFņūJŅ|ęÆ>nrą;Xøôß*ßP•MW#!ÜbxóÍ7ý§:č^Þ·ohxxh2œņqũ΍đ_ũėōŋņÅ/þŨÞ^· Ž}#�€H$ÄéÓ§&Ï9ˆN;ļņ0æ8‡ĮÆÜË!ũĘččĸûnBī·očėė$!��•BBļÁpōäņÉÓîaxxxhxļ64äÞ>PŦõ ôšåā^=thÔýę%Dãý 7!šŧ;Ÿ…ĻČļ� NB\ū|âÄņS§Nļ!á^ņŋgŅ8íp%ļ—ŅŅ·"öîÝãĸâoþæó/ž°zþüđnBĖ˜1ƒģ�Ļâøņņ#GF‡†jCC>íÐßßÛÛŧuōŌģuŦÛ ]==îĨŦŦà ‰]ŧüï_|ō“Ÿžæšk>ó™ÏÜzë­ģfÍZķlŲúõë·oß^Č="!��đĐvB\į&ÄØØć$'Ï<ž<į0qÚĄqæattÄ―8ā^ö6.“ßîõŋņéOzʔ)=ô{—ÝûūjÕŠŽŽŽÁÁÁBî �ČM•âšë&Âm††ûûĸ|ÚaōĖƒwÚacãŌŅŅļŽwûaddĸý‹kŊ―Ö}XæΝŧxņâ•+WnØ°Ą··whōģų#!��đ!!ÆÆ_9í0ņQIĸi‡‘‘‰`h\öîr/ūĀû>úĻ{ŊÝ~ØļqĢÛŧwï.ę‘�€Ün9LūgqĀĸ†Eãlƒ?öėŲå^Üo‡†vúßŋpûaá…+VŽ(öüC �ČM•âŸø„›ííŧš:ŧšÚ—ÎÎÆecãâÞÚÞūÞ―lÜ8qq‡lŲŌÕøý ·æ͛į―ąmÛķÏ?4�€ÜT9!ūĸýïßxã_øÂ>ĸųÏîsŸûϓŪWsûí·Ïš5kŅĒEexĸÂCB��rSå„põũũwttļāŪöÜđsįĖ™3[;ōēeËV­ZU†ũ/<$� 7O—{ôųå—ݐXŋ~ýÚ+^”jŒãŽßŲŲY’ó $� 7$Dmē"·oßޗDŋ;UIÎ?4�€Ü‘öI―vB$� 7$„MH�@nH›�€Ü6!!��đ1+!Dóô†‡ŊHÆ ;NŲ�€Ü—Ēc―w=é˜* Õ\Ýܑ�€Ü* }˜[xĄ‘§/ē;ĄAB��rc\BÔĒâĒ72TÆT\h䷑Åđõ·ZšAB��rSå„PüœƒúYˆĪSGB��rcbBÔâĘ!Ņ˜ę •ĖArj"œ(ž‘�°� ĄūÐĀ•„H4Ûæ‘�€ÜšĒë‰Nh,Ô?DtbÏB��Š Ę ĄũYˆČ^T„‡‹ŠŨ �ģĒ<D( �Č ĄAôÖFáH�@nHˆĪTÞŨ( + �Č a�Â&$� 7$„MH�@nēKˆK( �ČGF ĄqCZäT„„��${Ä!!Œ#ß "$� ‘Ø# aų!!��‰ÄqHãČ7Ļ �H$öˆCBGūAEH�@"ąGÂ8ō *BB��‰=âƑoP�Hė‡„0Ž|ƒŠ�€Db8$„qäT„„��${Ä!!Œ#ß "$� ‘Ø# aų!!��‰ÄqHãČ7Ļ �H$öˆCBGūAEH�@"ąGÂ8ō *BB��‰=âƑoP�Hė‡„0Ž|ƒŠ�€Db8$„qäT„„��${Ä!!Œ#ß "$� ‘Ø# aų!!��‰ÄqHãČ7Ļ �H$öˆCBGūAEH�@"ąGÂ8ō *BB��‰=âƑoP�Hė‡„0Ž|ƒŠ�€Db8$„qäT„„��${Ä!!Œ#ß "$� ‘Ø# aų!!��‰ÄqHãČ7Ļ �H$öˆCBGūAEH�@"ąGÂ8ō *BB��‰=âƑoP�Hė‡„0Ž|ƒŠ�€Db8$„qäT„ �HŠ„°ŒvBWē��Sɏ,$„Yä�€|Æ!!��e@B‡„��” a�P$„qH�@Æ!!��e@B‡„��” a�P$„qH�@Æ!!��e@B‡„� ’ų;6MėŦč,D‡xÂ8áR­@åɟ#U~}ˆĪ’ųŽ‰)HŧUy‡oė~@eÅ>ýŦüúĶrĀâóKzˆ'!ŒSåūąûqn(žĢðôĄRHˆĪHëUy‡'!Pe ‘ ‘ a―*ïð$ŠĖ!!"!’"!Ž§―Ë6œ7<|E2f€úâšAB Ęœ2%Dø ^ÂCC û +_ûÖ‘ÖÓÞá#ũdĸĀ@!ĻŒ)_œÞzJĪ›ÞŽ4æŲĖīMNX ų:›xĖâ”,!ÏņŠMÉ·ąã'š5E$„õīwø<ÂßÞþ‘sˆ|’D{F ‘óīiÍĄlėŧGeã”,!ÁģÛ =‘%Ģeš’åIGúøČo•›.ÂzÚ;žč)™ŠcÆ..r>Ž8]Âcú…Â{6ų‡xÃUÖŊ>ö…gčĸV>märýÃÃECDk.šSęũKrOŦxÄD 2â’’—Éõ,”3!äšÆ­)"!Ž§―˞ËĒ―T>f€hq‘óI4Ð/’ĢŠâ@ŅõąĢ%ŸüÎjŽmZwAþx"#NųB~E}īŒI‘ÖÓÞáE…{EïđŊūó‹Ę$<OÉĐC—ŌĖr―o%ËMÚŦ;g"]N)‰zĄ?‘IõĮ'é­)"!Ž§―ÃŦ‡ú˜*‹ ÏGt=vķ’722MÉRš?vf›tAņ―DĢ…‡‡Ũ0°zzũ ĐsĖIŅøáŊ™*mBHÆŨļ5E$„õīwxõ#xóĮúČ CԗëQ|##é@ųAPcÚæŧ"0BøŦh>áŅ$3WYĒ<œē&„#xF+^ÏNyĒɗ_õÉ&‘ÖÓÞáÓMˆ€ČÅIöv/*"_ˆDû˜‰Ÿ… ”ŲåĄ~]þmZw_>9ēā”8!œÐkEäģ[2yJûw!ÂÃ叞ĸ[ų‹d“Hëåö‘.ɋ‰:ųodūFūUŽ’ŅDK‰LŅ"Ŧū5ü­d&’ÍJrŋäĢIąð˜Ēŧ€T8eJ#ðŨ)“"!ŽgâÞgŌJˆ°Č8īĨ‹Įģ ‘ ‘ a=―ū%Nęëé_īâĀX$DIðxÂ)MBōJĒĄĻ„0åņ #!Ž—ÏKD9‘%ÁãY§4 a +ÎB$EBXŊĘ;|šā0‹CB$DB$EBXŊĘ;< *sHˆ„HˆĪHëUy‡gũCő‰I‘ÖŦōïî~Åüø”†ü9ŌĄW(&DŅŦY"$„Ýb_C�TVėï^UXRęû a�P$„qH�@Æ!!��e@B‡„��” a�P$„qH�@Æ!!��e@B‡„��” a�P$„qH�@Æ!!��e@B‡„��” aœÔBqƒzĢąd!üĻĘgķ€Â‘ÆI7![Se›ēÝ3EB�0 aœ|"ð__ýßúGĸsXoö“Dä !zœņ.Ų4iŊ;€Š"!Œ“bBD’DŨ%WyËCƒ$!b7‡ÆĶ€æ‘ÆŅKˆVo* ĻxhóŪŧ‹k­ķČįQā֖(*ģâV dĢ�P!?âī’ĶŅNˆúÞĀČ–“vB4Öđâb7‡ü,„Ī+$'$)ÂF (|8ðŋ”‘f‘oP‘pL*ž9—ÜŠžU™ņYlõI�@g!ė“sBHʁ„P‘nBDnM�ąHû䐎āóü-Ęŋ‘!ZD5ŸNŠŋ‘�ŠHûĪ•ȇbBhãų #$„}Hģ� EB؇„0 ĀP$„}Hģd�Â>$„YH�†"!ėCB˜…„�`(Â>$„YH�†"!ėCB˜…„�`(Â>$„YH�†"!ėCB˜E=!Z”•ęŋĪšÂÄĸj>ļ·’֑oP‘Ø=‰|äE[�”Oã›č‰ßJWœĩ@B˜%iBäüs�9įĘ9„DÏzã"ōāNBØGoW$!ŠBB�FsHˆļĐHƒčíŠ$DQHĀh 7 a―]‘„( + Í!!âĶ"! Ē·+’Eą#!ä+VÚÕšįĪÏj&{AÉ Q‰öd Q;BÎÐÕT8$„ĸĶ’RIˆŠHī'{HˆĒč%„ĸ y=ðëfōIczÃCÂ3ņõ+YĀ&NTBDþîgāđėŋŪ+þoýģõOy=|N#Ņ‰Ē"äTD1!ZŊĶą d‘ĒĻH:0vīČ1å“–qrLI0Č"<Ąh|Ē"äTD%!ZCÚ(ķ""Ÿ>)Ō›mä“(•9kÐ~#CņHÝLB„o L:CĀŽā Q?8 + 9aėu•+ąs!!*BūAEũ„ĀsG^Ē–NQ“ ‘úœ5d”þ— Ā$ĒŅÂÃÃË +l}Éʈ–qğ…ý�ÕĖ’ëōr‰Ļp"‘!ß "ō=AōA>Ʉ’=!Q`‹öðĀMąÏïVÅįWė―HE“ þZĮÃĢÕãîō !€zÜĮ)#_@2MˆðŨØđĐ !*BūAE${Bė/ŒŒŒHž>’}؉{vˆž2MŽĐíĒ'`ęīĒŪðĄĘzčð­2É•ōÉË8yýF†âÏ\ōëęŊ™ąëė6Jī'{2JˆÉɁü"rŠČÎÉgOÎ"!ęWĸ„üīƒĖĀ@ųh’ŪIEĀVN^"œá—ĐØņåsž6’‘hOödš UīũŠFË4!œÐóˈ„(ĄōŊ!.‡ŋN7 a―]1‹„åąčp™ōÕN1!"oĘag&!�Ģ9$DÜT$„AôvÅ2$„üÛīÎBøO/$š’0šCBÄMEBDoWÔþ ųŧĒ·!üåGÉŧNĻäï>„—(#CēV)ē,!€ŠqHˆļĐHƒčíŠ*{Bc?ÅOA@‚„�ŒæqS‘ŅÛcũ„ÆœGŪVþÝūü’&D^ë@•—­Ę"B}ōBU]B8Wž)þüiÐX7ŧE>ō’�JHôŠ'ávkL^•WŠĀ-$„QäTD1!:õ„�€R!!ėCB˜…„�`(Â>$„YH�†"!ėCB˜…„�`(Â>$„YH�†"!ėCB˜…„�`(Â>$„YH�†"!ėCB˜E#!S#š<ü 5ņ9ÛõWĘ÷*Î$Å1ę !ėCB˜E/!bĸĖĨK—"§m‰úĪ&>gå ‘t&)Ž T aÂ,Ú !ųCyĩZM#!ü#Ŋ‡ĸBäšču@}ŅÄ Üä}Õ^•EŠE}^a1Â>$„YŌMwøīiÓD !?úkÜ*(:úŦL"Z™ČiUæ#I‘ĪwJ}^ a7Â>$„YRLˆÆ1Kr"öBŌ ˆí +ÅuO’(!TîˆÞĘ$ õE !ėCB˜%­„ðúAž~þáąW“KFóƌ\yIƈ–ÕdÆ$]™ČEŦœpM؊„° a–fbÚĪÆTD&„ä'ýĀ•ðWGz菜đĘ@•UIz@}eš,ų›ö!!ĖŌLB4~æmôCĢ%šLíëzĮbÉÏøōŌˆS>CųŠĄúЉð›ö!!ĖŌä~hđú},ÂņŪ—æ\}œ ÍDē8õ™DÞ ÉLDŨSæŽēķžÂz$„}HģĪōY•„ČNĨžō•šģ€ aÂ,9ĸ]ˆÔUíų^ĩû Hö!!ĖĒ5Đ|"é“―%JFë–ãVČ aÂ,z qIAÆ+ ęHûdšŠĸČ ę4�ʀ„°Ov þïNōŠČí|uøsøą‹S_ŸŽũg€ĄHûd”ĒŋˆĻþOĨsØ1H�Č aŸ,Bō+�ũå#§%DĒ_·—LâŸĘđúóås“Œ ųíþĪ“(>H�†"!ė“zBúÁ;bÆþ +aŌ„œCPIõđ‰F”CŌIԟ$�C‘öÉ4!ZŪ›~þááëĒ$cŠ\‰[ėTŠ·ŠÆ"!�Š„°OĐBýzI"Ü<*'D“Ļ !�Š„°O9ÂŅúq><yøŦüŠ|n’Đ4V[ūD€ĄHûôYŅOîĒ]HýTFó Ąļķę]!BB�0 aŸœ#Cō·”E áøĮĐ'D`ķĒđIfåO…ðn•OĒ‚„�`(Â>Y$„såïRŠũƒ}2ÚąI�†"!ė“QBļÜZ(ä9• �~$„}ēKgē"ĸ‘S‹€Æš• �~$„}2MĪN#!ZÕĶJ·åÔįĘ ‚ÆLx!ēFB؇„0‹^BˆNōx“K>ݚĐĒ^x!ēFB؇„0‹vBDþ‚LÃČȈzB$úõ“ĪcNzˆ~{%ü5銉æ ;$„}Hģ”6!"GhrĖØÉ…ž6rq’Ø�Â>$„YōL?ĸððõØįÓS>Pąb $„}HģrĒĻ„7LZ !Ÿ3€,ö!!ĖRÚ72DĶ2fä$Ú Á@!Hûf)OBАOŪ7& ˜‹„° a–‘~|1<a` Ę˜áũ2DŦĄ~%ō.øï/D@ÖHûfÉ-!� ]$„}Hģ� •QBH^ܐFžÕIĢh'ĈTķfËՊ^�)Ë.!ē\kD#!LĪ—*I™ņŠĻ:ÂÞ[H$„Y4�ʀ„° a(€ĄHk†"!�Š„° a(€Ą,Hˆt?õ­>‡ē}œ„0 ĀPv$„äÛ&įfÂP$�CŲĒŋĶ>_þŋōɝÐ_ÜUœgvHC‘� eqBˆþöūüÏïëMŪ8ÏL‘†"!�ʎ„ˆü,„Ļ +˜Đ|Ēõj B� ĀPv$„čz8-5@““GŪUvrHˆÆ"ü+BåČįQ*!€Ą,KGpY―šœÜŽ„ðķŽŸJEīĻ} „„ˆ�ĨR‘„P˜â ‡Čyf*ӄˆė‡†Ø]H”Ē7žÔã-<oHxüŌ& + ĀP'„#>šˆÆԛ<Ņ<ģ“]BHúĄAō!Õ=ųcĨ2­dīŌöƒCB�0– Q~$„üš7Dō@)žŊP?­Q ŅŠ&0UËÕRŋ#Ųý˜ šGfÝ;Ā\$DFōA+mBˆ[á—ýĪ !šI`q%? č%DKœðäĒqųIBe8€ŒŲÉųĮ―&DøūK†ī$#C4“Ø…–ŠvB$Ý"ōnøGûĀȉŠ ‰MqÍc‡Č a ģBåŠhBÅiM9 ”!!Ô@ŁÚÛH%I $Hkd—Žô˜ĨøAˆðĀOōó þņ%3ņ†Äέ<ōL?ĸpųõØÚdĖØ}@ēŅLņcÜŽ‘iB(~č iÉ.!ž­ĐÞPųČË7Gkg!"‡'JŅá;2ę4&­đü„†h…ĪNåĀĄ‘(Š“å_§l›üč‡æ™›’;ūU>7ųl[B}�Ō’QBH^ܐŽĒ1s?ɘō΁ĮŽ„PĻr%öVŅš“@Id—YŪ5ĒåH]ĐÂ)åod8WĐdÍÃ#“@vHkdýYd$·„�€t‘Ö ! EB�0 a ÂPÚ 1"˜œÏĨ�H a ÂPz !9áÉxÅT5 !ĸyŠØŸķōY: a(„�€2°#!ZBī0r„Ē !�Ęî„ðÞíõĸķW`*ĸ˜á[ý>šč—ÔHH� eABHŠĀŧ"OõĐMžOĶHC‘� U…„pÎB(Ž)Ÿ$Ņ‚RGBŠ„�`(;"ō—ÔäŨEïDč%„âä™"! EB�0”é >:ĮÄà Ąņö„|$óÏ a(€ĄŠ‘t}ÛĖĮ—žÂP$�CYœŽøw""§ +Œ,9MŲ$Ē‘‹Ë a(€ĄLOxHC‘� EBXƒ„0 ĀP$„5šO%ōy�åGBØĄĩđ„ˆųMČ›€ĄbL$Dų5™��ĪŦ™„Čý„JՑ�€ōhÕJÅ!!��堗…Ž*H�@h$DþŸå@@!ŧ +��~I��Ā!!��€��h !��€��h !��€��h !��€��h !��€��h !��€ģ��ŠĐ™„Čį?Q�€j&!�����h!!��€��h !��€��h !��€��h !��€��h !��€��h !� ērųŨŽÆ(zk˜§•„�€Šâļéáx§„�€Ę"!<ï4�PY$„‡ã�*‹„ðpžÓ@B�@eĒ^%îą/pßīĒW<WG)žĸ�PMá„(hE +ÐLBd°:%EB��"U6!Į>ĸ",ü(EŽ@B�@‘"Œ„��ˆ"Œ„��ˆ"Œ„��ˆž<bîÜđ7_qÏ=ũ49·ė��“[B,]šôï~ðíÎގÚp­gGũÔũM:ĩ™f‡„��ˆĪ’ĢLË$Å =ĒđeĪĻ„pûáĸāü·ã‡WķŨú†wŒŋuėÞï™ņȌW^yE4Uø1‘?Ji=†$�@$­„ð4‘U š*ō[ŧâßúÆóWoėúĮïĸÃÍ7ßüoÝþĖÚķŅ“ūõßėîîMEB��Ę&­72žfÐëŅM‘s ItÜ,*!jŧj?šë‡ũL―ŧg[ûmggį-·ÝräÔáŊÝüß;::DSÉBr&ĮŋQ4֖„��ˆĪ›ę‡r•„cG‹UTBuŽöîčõjáoŋý·7oØT{éģĸåz―„ˆ}”š9―CB��DRü8eĒSÍ'DäŽĘŸ~_ûÚŨ‡öŽïųö?ëūîŲÅŧÉ?ščŠCB��R•EBdzÂđú'k'txU\ÛbbŨŪ]·Þþ?w õŨ^øĮųŧØßȐŸ…t �ČHFodÄ­šIÉhęŠMˆĸøĮŋ˜þÓÚØ Ûwß}wėøIï> �ČZv§LZŠ?A§õƒvá qËm·|óŧ·_sÍ5*ã+&DäƒÓLk‘��‘ÔĐÓIXá1#g%Yœh4đbĒģģóÉIK—.U_’ŋ‘�(BZĘi☕›Â?Nų―ï}ïÚkŊm~>rMn� ÂļöäüFÆžEózF6+ū‘Ą„��d„„ðä™O>ųä~öÚį{ßýîw›œ• �Č áÉų ·"îļãŽæį“)� BBxōĸÓRåGB��DH FB��DH FB��D"ĒĩšLˆĒW?'$� RëÕ ŅR1þûŪ~ž+z­ó&ßZH�ĻĪ@BTĮ; $�T ááx§„�€Ę"!<ï4�PY$„‡ã�*Ë=ÔqEŅ[Ã<$��Ð@B��� $��Ð@B��� $��Ð@B��� $��Ð@B��� * ‘Ņŋ��F“$DĸU��˜C”\ļpá… .ą‚ .\ļpáĒqņâA��€$þ��€–ĸÎDTcāu� \ No newline at end of file diff -Naur wfdb-10.2.5/doc/wug-src/wave/ppm/mozilla-new-helper.ppm.gz wfdb-10.2.6/doc/wug-src/wave/ppm/mozilla-new-helper.ppm.gz --- wfdb-10.2.5/doc/wug-src/wave/ppm/mozilla-new-helper.ppm.gz Wed Dec 31 19:00:00 1969 +++ wfdb-10.2.6/doc/wug-src/wave/ppm/mozilla-new-helper.ppm.gz Thu Jun 20 13:23:38 2002 @@ -0,0 +1,32 @@ +‹š=�mozilla-new-helper.ppm�íõŨėČuhûg‡™i ;œ8ĖĖĖ“˜qĖ_Ûcfšö˜1ĖĖĖÉ :'Ėø‚BŋŊG}õÔ§ŽJ*•ĪÚ{ÕK]]$}Rí.I­ï îv—ŧÝ|óŧÞõC?ę.vŨŧÞåõø[AAŠŧßýîWŊG���(ĀĩkŨzÕV—>AAė/P-AA _ĩwųöŧĖop7čâ ïņ†oxÏsžŅ=ßčũ:ÅßëOqïSžÉ―ßäũy“7―ϛžãūoúfũ}ģ>Þü~oÞÅ[Üï-ÞâþįxËûŋå)pŠ·zĀ[â§xëūõ9ôÖoó ·9ĮƒßæmüķįļõmßîÖ·ëãíōö]žÃCÞázŽw|č;žâa§x§‡―Ó)~Šw~ø;Ÿãïü.x—s<ō]Þõ‘ïÚĮŧ=ęÝúļéŅ7õņî~ũwŋíïqÛ{œâ1§xÏĮžį)Ūâ―Ū―Ũ9û^ïýØũ>ĮãÞû}ũ>}žïãß·ũŧýýúxĸÛßĸýŸpŠxœ≧øĀ'~ā9žôôĪ:Į“?胟üÁįxĘČS>Ī}ę‡öņaOû°>n~ÚÍ7?ýþôĸðgœâŪÏļë9žyŨŧ=ónįxÖÝ>âYqŽgÄG>û#ûøĻį|Tý܏îãcžû1óžs|ėó>öcŸŠ{þĮãũņ/øøs\ĸøOļþ }Üý…wïã_ô‰}|Ō‹>é“î8Į'ßņɟüâS|ʋ?å/9Į§ūäSOņŌOýī—~Ú9^öiŸþēOïã3^þ}|æ+>ģÏzÅg}Ö+ÏņŲŊüėÏ~Õ9>įUŸsŠWÎįūúsÏņšÏýžŨ|^ŸĸÚÏïã ^ũ}|áëūð ŋã_ô_ôEßyŽ/þÎ/þâï:Į—|Ũ—œâŧŋäKŋûKÏņ=_úeßóe}|ųũ~y_ņ}_ŅĮW~ĸWöņUßĸU_õįøęøęŊþÁs|Í~Í)~č_ûC_{ŠþÚŊûáŊëãëäëûø†ý†>ūņGŋņėßôcßôM?~Žoþņo>ÅOœâ[~â[Nņ“§ø֟üÖSüÔ·ÞōS·ôņm?ým}|ûÏ|{ũø™{ÜãgÏqϟ―į=îũúđ{âįOqïŸŋũ)~áũų…ûœãïsß_žoũûĨûõqĸ_šĸýųøå<āWÎņĀ_yāõú՝âŨNņā_{ð)~ýÁ·þú­ĸ?~ãևüÆCšxčo>ī‡ýæÃö[įxøo=üáŋ}ŽGüö#Nņ;§xäï<ōŋ{ŠGýîĢÎņ{zôï=š‹ÛþÏm}<æũÓĮĩßŋvíÎņØ?xėcĸðûÃĮâNņø?zü)þø·ĸņíįø“ÛŸð'Očâ‰ŊbOúÓ'õņä?}ō“åO‘§<åÏÎņÔ?{ę)þüOûó§â/Nņôŋxú9þōéÏøËgœãŊžņĖŋzfÏúŦg=ëŊÏņėŋ~öģĸæÏų›įœâoOņÜŋ}î)þîÏûŧįâïOņüŋþ9þáų/ø‡œã_pýŊwņÂ|á ĸé/ú§―čŸÏqĮ?ßqŠ9ŋĸåŧøŨSžä__rŽ{ÉKĸíĨįøũ—ūėß_ÖĮËĸïËûxÅžĒ‹WþĮ+_ųŸįxÕūęĸuŠWĸŨŦOņߧxÍŋæĸóšŨþÏkÏņŋŊ}ÝĸūŪ‹<ÕođÕĒZT‹jQ-ŠEĩåT{íÚÕĒZT‹jQ-ŠEĩ…T{5Ĩ=vÛĒZT‹jQ-ŠEĩĻv”jŊ${īĐÖđÏy”jŧ"ĻÕĒZT‹jQmƒŠ―šŌ^Đö +‹j‡ģړmmŠ―ĘÉŽÕĒZT‹jQmģŠ―v§jošéĶlÕ^-\yöôz§jûio§ÚþmįŲþmŊÚŦå+Ï^―vŠí3ôŠ―ZūRm—8TmŸsĻÚ>qĻÚ.ÕĒZT‹jQ-Š]^ĩÝŲã›î$yYQmgÛÎģýŽö4™―œÕž…{įŽķ·mWž›Õž„{cV{ēí ՞l{įŽķ·íÉ°7fĩWË―gûYmgÛÎģÝŽķ·-ŠEĩĻÕĒZT[HĩwnéÜ:ŒÎģ§Ëĩ7Î$_Ī[Ū՞=;Aĩý ä˜jûČAÕöģZ]ĩĖjQ-ŠEĩĻÕ.3Ŧ―ēí5ÏķýrGp†ëĖjcŠâŦvHPĩC2T;„ČĻÕĒZT‹jk@>Þrs§Ũ~J;TmėLēQĩĘmQÃY­s­ÖŸÕ:ŨjĮÎjýÛĒ8ŒjQ-ŠEĩĻvákĩÓɖûĮŠvąČ\ŦEĩĻÕĒZTŧN՞ôzËÍ]XîCķĻÖŋŲųąsöØQ­rēĢZî@FĩĻÕĒZTŧ~ÕöWlŊ ^“ÏCæiQĻÕĒZT‹jQ­EĩýŲãÓ]R]LBĩĻÕĒZT‹jQ­QĩŨ.ÅÚĨ$…jQ-ŠEĩĻÕĒZËČÁ;-ĸz�ÕĒZT‹jQ-ŠEĩIÕ^ÉôŽÃ-A“vđ@ĩĻÕĒZT‹jQí(ÕA1cøŠ���˜T ��PT ��PT ��PT ��PT ��PT ��PT ��P”)Š―ûâęŊϟ� ‰>ZÎŪÚė…Ŧ?hRĩĩû�° +–WíķÏa„j_JŅvÔQíĻamtGAĩAĶ@ĩ0TK1&P-ŒÕAŒ‰uĐvxYŊ*™ʁj ‚ ÆĊTëØS—)Š­Š%‚kQmRŽÃĐŪþv˜čÔėįæņÓ!Š%‚PmЀþBėÓdN=øĖĨÚŋēĶOÉ9W ~î4ĩåVjų EÄ 6 Ú`6ĢjóíýiTŧ~Õ:• Z‚ĻÛP­ŧ”öØ2ÍHŸfUë=ĮcæšŨ\!AbŠĩŸ@6QŠûmÁgyÕÆœ **LÖĢJÏĶwĀøiÆęûų‰›tlĢAÄc-Š•øČĨŊÕúĒZyUCÉæ|ĪÔĶ7ûHïíAÕĨ}-ôIv[Đ0–’ą)ėĐVâŋŦ&öŊþ9dŋˆx†urúVÅģI–T­?˜Į>IÁ^n ’‚Ŧ“ývÔJéýQގę˜Ō·āF "ëRm ÆŠÕ&Yōō1B,įôz”Ūú–Ņ―3ķ{–RĢš7ą'úf\|°"ˆíÆ>UŦÏ[!FģŠÕ§+ĖRĘŊ!Ļ?åí”~ú.>dÄcŸŠ•ČYåd‘rýŲËŦÖRÃXƒXzâdĒT’Ũ=c·蝙ēĄô?“ūÝ‚ļ3ŠĐVýõ°v–ŸÕ*oí9-õÄúĢ0oŒĨœ>ÛߎÝʧúv#âFÔQíķÏ2Š=„LĖég *#Y―ŸĢ:`ųtÔę››ēI362AĄĻĢZØ‹Đöp9ÂĮröËÁœözėýÕã§ŦŦvJJĘņ’ĨF*‚Øt ZČdšjįŪW&―ÕŧGD―@ĩ ŠՁęÝ#Ē^ÔTíí·ß~Ûm·uŊýBũšĪ2 T;ŠÕŧGD―ĻĐژRŊlLgFž*PíĻTïAõĒōŽķ_N*øpãÖåYuųŽMĩAkĩĖjc +v28Š= ~:Ī'ö)ÉD§!%C^ýŧÕAØĒþŽÖųĩæ14ŦõMŨ/Ļ'ú5Ä32Øëß Ļ– ÂۘÕ*Šõ—óŽĖ™Ė —BĩĻ– b ģڎ˜‚ûO™Ŋ_Ę2 Öā$ÆÎ�įĐ6Øč>@ĩAķXËŽvˆ3Ŧõ%•wZØohÔüwbýûÃŽZ�€ÖŅGËĒŠþÖųípH?ĻŠ=xē‹%‹į­jXT[ŧ��kĄ–jčŠ=Îwōð՘ÁY66š’Š�€<Võ`Æ`mŧôÚ +T �PT ‚j�ʀjĄCP-�@VĨZĻˆ Z�€2 ZčT �PT ‚j�ʀjĄCP-�@P-tŠ�(CĄ§E9ŒŠæ0#Ļ�  ŦzēeŠ4… Z�€2úÏ>Cüg ûO;œßĻVGP-�@jÍjíOķ<ų?X§ó +”·Á^ĩ†ĖĄÚÀ‰U ëtęŸŦ6=Ņøétúú3šRÖXóŒÅ36~^ĢĨĸd~‹zžá~kïÛbk 0ûŽöpÉ14Ŧ=ÚjItė9ŠHŽx›ČdÕ:#ÃÚĸėJSíÂe‹ÖŒjcPm›TžVtŸ’-YÖXORčm"sŦÖIũ'ĪÁųŊŸ8,Þ/+Æ>– 6aé@dÕ­ĨôÖõnø‰Ę6É^…d‘XåÉu‘Ð+ĢĄXN―õQ;{Ēūaƒ cߔ?ŪÞtr}Ą +UŪÕ:ËNJž-V[Ž―ČÕÎwYIŒ 8–D=[0Eí― +fÐ[Œ5di}öc_cWó:kzĘZdt8ļâŲŦ™ąaĮö-ckÄę„ZÔ―ųpéPĸĢ`ķd=1YĪMÄðŊáb9A5o4S>ÍĢÆz!X[,ƒÞtFë­dīŽ0˜2ËJYšÎ3Îō­O)>Ģj‰CüĢōÐGKŸBŋŦu~c;ŌĐuÃēĸ‘Ÿ-øvļ€j§ ÕúE,ßÉ{üœJ=I%-ŊZ}]æR­ŌĘÄļŊ<˜­ŠėæÚĪ~=þZûÆîœÉ y}ģŽėĻ:k -;ĪŪjøE—îëðÓõ"Ézú·Î§ą^ĩ†ØTŦdpmûŦ!YO0ŋóГ392ë―ēgČHĖč†q4NŪÂ,ý·ũĮū^3ķ$ŊKzÎ`†‰}ówx{'av6ĄÚrŽŠ3›CJŠvŠ2TŦ*Ģ ĨxēÎ`ý–ąw.MgŽÂÄ>č+ýEe%ĒÖ?Kߜ”Œ:aT큙éLČdÕʍÃßTûQÂwą%18ŒøoýžØ—ýĖR<Ömį5đ)ŒÝˆĩ„óV!YDé˜ū.ąĶ- ŨqTëĘÞbÜÔÁœÉ ëwÉÞ7Ĩ-lĨįPˆU{  † dÕ)tÔŊ|0Ij`AÕBÚT-Ė‚lJĩëgP-Ėˆŋį°/UÕB6ēÕnbAĩ0ėKkcŧŠõH #ÅT �°'ķŦZĻŽ Z��ÛU-ģÚęŠ�0°]ÕBuÕ�ØŪj•Y­ßÄÁð4EūŒEP-�€íŠVAQíĻR #Ļ�ĀĀvU;}V;|Š…óP ĸ‡Ëg#+mĩƒ Z��ÛU­‚Eĩ–'QÏÐ ‚j� lWĩúŽÖ§ĸČY–ō?JęÕÎŧw�ėíŠöxÃķþkÆ d%1ąAÕ�ØŪjįšŲ~Ų/…jģþgŸŽ>ÝYHÂsį�`lWĩ +…ŪÕúĒÚ㊝˜!#'�Ā’lWĩóށėžÝŽ·ŌRRĩÁY­3óuōũ9E† ~ņ`ąV��2ØŪjŦģ›ÉF–UmP z'ŅXį”“Ø��>ÛUmÝg ãŲc™kĩÃô؂äŠ6#�`:ÛUmEv° +ģ ‹ÏjƒR֋JÖÉ d�˜‘튖ĸėSĐw9Y•rŅÖ^'ķ€YØŪjĄ:ēÖkĩQmöĩZ�€)lWĩĖjŦ#kšYžģūNķ^ū~z,1ŲI�� ÛU-TGÖýīĻ j�–gŧŠeV[Yąj}ąĒZ�ĻÅvU ՑĩŠ6y%�`IķŦÚQO‹‚ČZU �°*ķŦZTŧ ‚j� lWĩģÚþ^S'§“8L9DžŽÔ,žĖđEÕ�ØŪj‚M]94]pAW­žh/ūQÛĘ4Õ^€-Ģþú™ŧ'o0 ēÕ^Ÿp­ö0A ąú'ÖđEdēj+ �0ÉÃ_îTmåAjAú͒1Y‰j7lëŋƚî'}ĘðÓą‰Ģęôs/gū›#yŽYT[{%� ‡äá/7TkQÃÖé'J†ą›b%Š;ŦhՍ^?‚jZ%yøË@ĩ‡ÁƒRwųšcÕ*ĖĨÚā\Õ>)•ÓūvëAP-@Ŧ$aV{™aėĶX‰jõY­rķö0ļ78hĀãĀ’ÆD'=™ÓŊs‹ČÜŠŧ)‚Å“_īŒĩ€BōðoVŧWšÕÎČÄÞnkeĮ"Ļ U’‡ŋ0Ŧ―Ė0vSŽDĩĘŽv"ąĐî2Å7„ĖŠZgÖïŋ6íŸĩpbUųį†uΚy�öLōð—øŽÖWŌôiï!ÄÄ:íMïXĩE žė]ŽøVbģÚ •'Q/âļ8fs�PHþŸÕúVšQ‹‹vȎU[nV FdYÕ―Kۖü �$yøKjV;Lt–‡ÚRēō―uę ?c:ĖŽŠ"%U;d˜ÕŽäá/ęŽVT &ģÉdÕú-Z*ąNՎjNĐj–z` +úÎ3ËŽVųÕÔ"yø‹áZ­Ņwz6ŋŅØ[c+zýÁwŽZXúÎ3ã ä`NåĢX…Ļ`’‡ŋĪfĩÃegūéœČEĩÉŲq°i#;V-ģÚ5 ï<ŠŠÏyëäôóø9ÚŽĻ`&’‡ŋØî@öUŽ'økT)ë€^§ģZ(ūóðī(€―’<üÅ6Ŧ•Č•Sãrēr‰ĻVŸ)3ŦVû(ķĐíų§3ĨÎ)ßēĶC…ūó Z€―’<ü%ũwĩÁSļSTë@°'Q7rŸēcÕ*TWmō‡Ĩøōe3ÐwT °W’‡ŋÄgĩ˓týDvŽÚėYmō{‹ýŦNl]‚Ÿ+W“Ýö‡o-ŦŦ0ļRAôÕė•äá/‘Yí!Ž}äÅØÉWFý;V­‚ēauĢ9ÚŌ‹čž .mŅØížēÆ":ú΃jöJōð—uĖjƒĢŲėÚąjõYmėû’QOĢýÖíËšÔ-īR1ôÕė•äá/ņkĩ;cũģÚÎķþŦ>ŦUüŦL�eûmųų•Ę•Äds–uą·ÛW[5}įAĩ�{%yøË:fĩË°cÕæ]Ŧ ķž1ŨSܗ]ųXÕf”MŠVi.ˆūó Z€―’<üśÕîøuĮŠUČö>=Œ%ڛÛâėš[6‰ūó Z€―’<üå†jŊ·Á^U{}w j:Xđ’˜ėķ“čTe\å`ÎāŠŅw}j6Kōð—Š=īDÞ`d%Š-AŅū+_óÖ° ï<Ļ`Ŋ$|Éo‡žÁ0ČJTŦĖjģ™Ŧoöʋķļ�ú΃jöJōð‡!ÛUm PíXôÕė•äáCķŦÚģZ‹ūó Z€―’<üaČvU k@ßyP-Ā^Iþ0ĪŠjgųCw=‡ŠŠh•äáßQŧ›ËĄÏ"·ŦZĻŽ Z€VIþ–<; yÂvŧŠeV[Aĩ�­’<ü;,yvĀŽU ÕT Ð*ÉÃŋÒgėXĩúŽvø›âYš Öãüxy–†ŒMŊAĩ�­’<ü;,yvĀŽUŦā41K‹1ÕÎÞІT Ð*ÉÃŋÒgėXĩĘŽ6ÖÄáÆ9ƒŲüÉiŸ?6oĐÖohXÜoÂ/Kũ?Ķ,l.Aĩ�­’<ü;,yŒÜęĖ[(ʎUŦ3Ģc+]1?ú9}!*ŸŒŸ.ƒ Z€VIþ–<F,Ōôó Ú‰Xî@Ö§‡Į”@cNtęM‡•e˂ą?ÉN–CP-@Ŧ$ĸK#Š4ûIŪ3™UæŋóēcÕoØÖu0z͗ĶEĩzCąeKOŒÕĒZ�XžäáßaÉc$fĖĄ^9<ėÏ,hûĩÚąsÉÅTëŋŧ=Š“åT Ð*ÉÃŋÒĮHėZíPĶĻv؟ŌûĀúUkYÛIg.ž�‚jZ%yøwXōIÎjÕ^ög–?tÆïj'ûtåĪŪߊâe?ƒ_đŸ_évŽoĻ�–!yøwXōAĩk›Õ6 Š€eHþ–<FļVŧÂYm;p­�–'yøwXōQ~Wŧ9ųŅ\}ÛąjĄ'x‚zÕīJōðï°äŲ;V-ģÚęŠh•äáßaÉcÁŸŌ.óƒY#;V-TGP-@Ŧ$ĸKž°cÕ2Ŧ­Ž Z€VIþ–<;`ĮŠ…ęŠh•äáßaÉģvŽZfĩÕT Ð*ÉÃŋÒgėXĩPAĩ�­’<ü;š<Ũ`ŊŠ―>þĸÕZ>Í#VgðYR īŧ ‚jZ%yøw―§ęí˜ėÁ0ČJTŦ 7QĒÁ:ÄÅÚ] Aĩ�­’<üaČvUk™Õn<x˜Ēž 7Vât#ØÃdĩN7ô Uœ%Ļ U’‡? ŲŪj7ų‰Î‚RÄ^*Ö]ÁĢ:cÏ° ‚jZ%yøÐíŠÖ>Ŧ%ڕ7ŠT°?ÉjíýæLöĄ‚jZ%yøÐíŠöxÃķþŦ]ĩC”"ĢJÅÐkpŌõÎč=\ Aĩ�­’<üaČvU;ïŽÖϖ,+KĖhÕĀ:Iþĩŧđ‡†ï@Ū{ŲĒڝY Aĩ�­’<ü;,yv@ãŋŦUÎ�—“Fó—ƒį~ƒ=ņ3kp‡ŊzŧÁåeT Ð*ÉÃŋÒgėXĩPAĩ�­’<ü;,yvĀŽUŦĖjaÕīJōðï°äŲ;V-TGP-@Ŧ$ĸKž°cÕ2Ŧ­Ž Z€VIþ–<·^2ķxvŽZĻŽ Z€VIþ–<Ž^7aÛŦ–YmuÕīJōðï°äqPTëOuŧå>Å/ĖoĐy;V-TGP-@Ŧ$ĸK‡˜jƒ–ėý8\ÐóGącÕ2Ŧ­Ž Z€VIþ–<ąkĩš%•…žÄQėXĩPAĩ�­’<ü;,y’įx‡ +ŦÚ~9Yó(vŽÚØŽö"V‰åŠF’O‹*§•ZÂT Ð*ÉÃŋÒĮÁrYų4Oĩc;é°cÕ&ą4ī€j§ŨžZÕīJōðï°äq{­6đ Ô™ĖidĮŠM^ŦõŠ=Cؒ,>Ė6JĩN§æäSŽcOBÖ{ëd6‚jZ%yøwXō8čŒ]Ā6xN8˜ÂČy(3Ę ģ’‰Áâ~KtąęŠUúĶũ|ö“Ø‚jZ%yøwXōė€Ŧ6cVëĪ 4/ŅihH0sRâJĢģt2Aĩ�­’<ü;,y†ÜaT%ËģcÕoØÖí*ÉrŠV™ĸZŠ;-ßNQmß{ÏõNf#Ļ U’‡‡%ÏØ·jubš;fđ)iŌŠõ_õÚP-�,Cōðï°äŲĻ6ø6xų2™,îąôaÔÉdKëS:™ Z€VIþ–<;�Õ:)―nœW_Rū˜œģĮÃÄ`sÃ"ąSūzÍz~ĸSÅÎJ'ģT Ð*ÉÃŋÒgīŽZðAĩ�0 ÉÃŋĢËs―Pmãp­�f'yøw―“{;&{0 ‚j7Gŋ'Ė[­ Z€VIþ0ÕB6‚jZ%yøÃT ŲŠh•äáCP-d#Ļ U’‡? Aĩ Z€VIþ0ÕB6‚jZ%yøКŠ―ýöÛoŧíķîĩ_č^kí?`GķĢÚn%‚˜Wî%Íä`ĪkkÕƔze[?qøóĨ2ã1ŒC6ĨÚe€}Óđo”4“ƒaU;TŠŪ`gLÆķk@ķĶÚę_† ‚ØzlQĩCĨÆ|L‰ÕŸę.ŸũüČww,qT[M!Ļ– ˆÆb‹Ší”ę<ÛęčÍj•Ų·Þņōéúūv}Į*1fkÓģĮÍŠöÚŽ<ö’Į]ōxÛ/yÂ%OôxŌ%Oūä)O―äi—<Ýã—<ó’gy<û’į\ō\į]ōüK^āá<Wö…—žČãŽK^|ÉK<^zÉË.yđĮ+.yå%Ŋōxõ%ŊđäĩŊŧä;.ųNïšäŧ/ųï―äû.ų~ļä/ų!ūäG.ųQŧäĮ/ų Ÿžä§.ųiŸđäg/ų9Ÿŋä.ųÅKķŦÚéģÚą–ÔóĮGekŲĢj·ÜŒjQ-ŠEĩ{R­ņZmÕCĸŦΙ}ë}Û=ēGÕ^ŧv@ĩĻÕĒÚ=ĐÖxr-Õ*Ų,}Û=ē;Õ^MiŊš4ĘķĻÕĒZTkqŸ>ZúĖ;Ŧu~NÛĸÆÖ*ýۓütĢjgŋV›æw‹ėNĩW’=ÚTÛŨÓKö*eĒjƒũ` ZT‹jQíDՎÂ?yëĪSôK%ÆlĻ6{ïZĄjOýđóïkQmWՌŠígĩWU1ŦEĩĻÕVQí,īlÆŲ‘ÝĐöڝŠ―éĶ›ŒģÚNŊūjû9i§Ũ~Ą[î={ĩlQípn{ĩÜIķ[čZŠķoÕĒZT‹jkjgDöĶÚģgïTmbbŦĻöjĄŸÕv’-ĪÚ^ēÅ~>Û-ĢZT‹jQíō Ú‘-ŦöŽÃ-[‡Ņyötđķ?“|úŨUíÐķŠj‡ķíUÛ-LœÕĒZT‹jQmÝŅJ#[Vm?“―æŲķ_>œŊÛfļÃÛĒ:ÉU;ŒUÛ{VQí0P-ŠEĩĻķŽėAĩ§øtzí§īCÕÆÎ$ëŠõo‹ęÏ$ũ’ĩŦķ·­EĩÜ…jQ-ŠEĩ{BvĄÚ~z;4lō>äŨ_þاŦY9ÜÛv8ĨĻZŪÕĒZT‹jŦŪPŲ‘jO=đåæ.,ũ!ŋ^ý]­söxšj{Û:ģÚĄpđÕĒZTŧüč +Ĩ‘Đķŋb{mðjyōbO‹ +Š–ßÕĒZT‹j“ĢŦó„ĻáÛeF`˜‚ėGĩ7<{íFŽZFĩýQĻÕĒZTkin8šN|ē>P[žč?*ŲģōŲ‘jŊđb=ĨXĩ€j_?øąŠEĩĻÕZšsfĩýēĒā “– ÖLåbTÛ#ŧPmė_ ĸõ�ĸn�ÕĒZTkqŸ>ZúšÕÆ|īĐVy:ņDÕ:”F•ląéSœJœ"–šõúK ŧPí•Lï|œE€î1ĻÕĒZTŧiÕvJ=\rŒüŋZ_1šãf<œ4xŌČzĮ_ŨKĐA)2#ēMÕAdĮUkŸÕSjóë1Îj-ŠMVkÉæ7d7Đ―]―Åy‘mŠvÔÞ�Ðą]ÕÚŊÕb~qÎĩęÆ+î`ë–FýN*•Į“”Råt&Ļ�šaŧŠ{rōLlōS?›’'XģĨZĸUYKbv)}í&"Ļ�šaŧŠþÖųípœœhËtÕĒZ'gēWöŽŠ6VĘ8ģžAĩ�Ð ÛU­ĢČzÝXĶŸN‘X6}†čÔ ũðx)D'%֍XÁRJΊ€fØ―j[`âfĐēUÕ@3 ÚĒ_`ÍŪj1Õ@3 Úí<?œWÏ,ý… Z�hT UT �̀jĄ +‚j P-TAP-Lā:@môĖÕBĪÕ.UÖބåÓr­;5jȧÛ�j!ĐĖÕBĪ Õ*o h‹ÁĘ[GFĻ‹4ĢZį Q÷ĩ6>ؑöTëĪ ŋ;‰~ŠSÐyūĶôoõvýēÁu‰UĖãŨŊ4ŽMÕB]ĪÕڟ<$XdácV鉓Į’3ŧÎÂÂHÛŠULdÉĖiĐĮ^alEŒ9GõÜXųT u‘fT;ö?ûß.ÅqKöÕ&Y^ĩJ –ēŠØâØþŒj=ˆģX–3RÃ<_†õĖÕG'°#ÍĻvÔĸŦõßRO<VNUþŅk7Ö=OðĢėžøŦ<,héüŒHóŠ2Ė0]|~âDŲ%KYšVę n +<Õúŧšĸöh8H“5äj7„4ĢÚNĐÎqz4Ïj‡n +Ys%úøŪ4æ™Þ=e•QmŒŌģZĨāvUÛ/[TëŨ“dFÕڋ'ӏņï―NÓý[įðÄķ[AšQ­}VëļØ/bŨM0§^g0ņ€Ûg{NTk§ÄČģ›ąÛUfŽ0Ųó<Õŧ”Äßô]úĻîácU{ųe8Ø·d‡aÍH3ŠÍŧVL}&:ēÎąĨ!―TðkÃėŠ]æx—6T;$öПĻgSÄįįŒų.Yaē·Áœzž`'핉ĐÖu2øËĘGgßpį:aýH3Šĩ߁ĖĶ\ÉO“ÕZÍȖ<í}V—9ÞĨÕ.IŌMUŠvōTŦK3XÄē‡ØPTŧĪÕHëüÆvļAÆŠVŦ)Į”­ü/ĖÉlÉFõÄa+Ļ6<ÕúĒ{%Ģš+Qíü.UíqĖAËPúË0ŠÝ ŌŒjLWíqð}øčY,y+UéÝ Ö?6ņh8š•MQŲŧjfmŠ ögÍŠ5Ķ蕏ēŠŸÕnAĩĩŲD'c ZŸMĻķ5S­CðĢ`―WýŨ`ŋNo„5"Ļķ*ëïĄÂ’T ØÄh °éÎÃÕVeåÝÓYļó‚jaë t6Ýy8ĒZØ‚ja[ 6Ýy8ĒZØ‚jaŒPAĩ°Õš v/ iôĖÕBÕšݠ.ö=ÕBÕ@3lWĩÎĒ†o—a +‚j ķŦZã3{ô‘đî|đÁŲš Z�h†íŠÖøŸ}†”ÁÕ.Œ Z�h†íŠÖøĸj‡b^;zL .Ÿ·fy2›žėØîT ļP}sØŪj;ĨúO(õgĩ–į‘ęŠĩ—UÜŊ§ĪÕ<útga.fĐp?Ēév�€ZH3?öąÏj)Õ ģZcN―ČĻ†öīĄÚ‰Æ2{…ŦeÉ�ĀGšQ­ýZ­óm$XĘ_vdŋ†QŠ5oiXĩ‡ÐŽvøm9Vj˜áāýŨu?ƒSa·ė·Ė6ķ’…AĩPiFĩÆ;ýã1);_ĩöiirVŦŨŲ‚jãÎÕŦRŠëM=o%‹jĄ.ŌŒj‡?Īu~c;Ü Õ'›ÁRyŠ5&ú­·€īĄZē)óĐVžŲeŌ’zbv%˃jĄ.ŌŒj(Š=Æï–r2+ÓÞ ŧc‰ÁævīĄZ=ݙ*úR‰Y;&D?9_/Š…šŠ…- ĻvĖ X}ŠkŽP·Ī^ɚUûëzhûTĖˆ ZØ‚j§@vē9‰ģÔíŠöč]—ŅUs4€Aĩ°ÕÎ}rŸ'VáØČöJ–wŪŋÄ&ģĘ@6‚ja HŠ…rLQ­Ÿ`,‚ja Š―Á!D‰†ö„~ųxyŪØ?Ŧėd‹ ZØ‚jaúmQ~šîe€ąŠ…- Ļ&0EĩGN ÃdÕÂT `4€šŠ…- Ļ&Āh�uTbxÃIðĢaž>=ûŊāWnéXė<X°”ĨÝ5Ÿ%T @ĩPAĩŠÂô_LÄR§]Ŋölyu.Œ Z˜�Š…šŠ―$XęÆ'€ĘŊ‚wVX4:j~ŧĐCĸ† Ũ9L7Ūˆ=1Aĩ0nĻÝ h}shYĩö}ōŦ›tÔ tTßÆķk_{b6‚jaÝîPû‹jí ÉÄ`+3Šv˜Įē)bsáXŊė“eT �`ÕÚœÄ!zŧŠs-Š=†ĪißÉŊþŠÄšŠŊō(Õ@3 ZûB,ŅŌŪ>óÕûûČXįÄsÅÉUČCP-�4ÃîU{T­Wîēq:cߒuį­yþeV �`§ÕCįHûtû‚ŋŽŸJxVV‘ĩEô~ý\ØoĻOtžŽäœˆ Z˜Āu€Úč#˜C#Š…ãÜg€'" ĻöõŊác9ėÍí’n�Ļ…ðcˆ°Š­'mĻöāéo˜xļ4Đ%§ÞÜĻîmFĻ‹ Zˆ°Š­'ĻvVÕŋl3;5ø nFĻ‹ ZØŌ†j%$ū j9“Íë‘ļâõâŦ…Ņ�ę"Ļķ€ Ú‘Šõ/› Ö3*qĖŧÔ{˕X°"zŸ·ļFcT [@šQ­Ī ;*§―9‰›4fðëV›BŠ]ļė\5Žý­‘ ZØ‚j‹ĐÖŊ'ķž-―ņw€þ Ã0åųĄ\0ņú…ÞĘð­^6Øî0ÝOŒĨÄz[)ûz)kętÕŲbąmēcՐ–T[*/ۉIÕÚÛ]?ΠØĮ˜[°'&ģ­gˆūē―kôíđcÕÂT;áLoP‹Nš“§—ŊŸŪ\'Ę0ŧkŒ­Li·Ŧī;VĘŲÝH֜QáþT [@Pm]‚ŠÝ Ę äĒŠUZ™Wĩ 9ųû ąl~šßC§{yëĩKՐ―ŦöÂ^U~ýûVmžÆŠ6Ģėtĸ:üŨX=~6ĨrKPíAĩ°dHЊmŠ6čA‹%įŌī’ĻP·­}Y;ŨęŋĻė Aĩ°ÕÂô;Ũ æ,6qēÅZ Š3քÓ=ĸSĸ­R‰ŌąXUĘzéŲ”-æįÜýX-Ļķ€ Z˜€ef` ™—f·§ ZØ‚jaĻv%4ŧ=ÕÂT @ĩ+ĄŲí)Ļķ€ Z˜�ĢÔEP-lAĩ0nĻÝ h}s@ĩPAĩ0nũ�Ļ‹}EĩPAĩ�Ð ĻŠ Ļ�šÕBÕ@3 ZĻ‚ Z�hT UT ļĩŅ_đó�ß+wŋĢZĻ‚īĪÚ)?K9„þ§íeƒõŽ‡n€Zˆá§.É åzÖÍP-TAšQíáÆĸdÏ(;ĨāÄē%ę™FƒšŠ Š…*HÛŠí‡éJĒSÃprKūÕËÛĩT[ŲX‡•jĮÂhPAĩ#AĩPiCĩõ8óc öÄdķ`c+ÉõÍX…$ŒuT;T UæUë/gxJotŠĶõ +“9õ'ëIēæŅ@ïØjŧ= +Aĩ#AĩPiFĩC†éþōDÕú ­Dĩ}߂]ݟju6Úm™OĩÉdm ZØŌ€j•ŲÜėŠëĖm!ÕZVaÃ`ļ'—û‘\ÏĖŲ'ú)~%ÃŨá[Ĩ'EfR­ģ'Ėļ‡”Õ†æUô Å’sišĻjëŦ'‰]ĩ1ųŽMLf æԋo™CĩʟūûhļõéĢ“Ų2@ĩ°!ĪyÕJčīj,Q<=é#‰S•^Ö"PĮĄú k4Ö[ĨéÎ`4šŅŠz=zÍn)ŊZÏ·É―] Ļ6„4 Z…˜ŅæŠũŒRía€S$–ÍOũÛ‚j}’tÕúËy‰Jķ<P-lAĩķDcm>Ó:ļv‚Šõ_ßųŲŽ) įËÉĶũ1ˆÉšU+îÄëAĩ°!ÕÚ!ˆŋčJõ—õ·Ę4y”UõâÛEVŊZ%ÛDP-li[ĩ0ŧj—ũýęÓØaN'QÏĶøŨÏđƒqLžyJĒŅČĢ@ĩ°!ÕÂ61Žŋ‡ŲȂŋŦ žÖā'ęŲt#Į@ĩ°!ÕÂ61Žŋ‡ŲO‹ Š…*Š… lb4Xģ‘ÉŠ=ęsG)�Š… !Ļ&ĀhPaV;T UT Čî`FôãŨ’aĢ ZØ‚jaÝîuŅĸFÉ Õ†T °kô|ŧ ZØ‚jvMwü^ß#Ļķ‚ Z€]sô+―'Æn T UT �̀jĄ +‚j P-TAP-�4Š…*Š€f@ĩPAĩ�Ð ĻŠ Ļ�šÕBÕ@3 ZĻ‚ Z�hT UT �̀jĄ +‚j P-TAP-�4Š…*Š€f@ĩPAĩ�Ð ĻŠ Ļ�šÕBÕ@3 ZĻ‚ Z�hT UT �̀jĄ +2‡jGí{Ų Z�˜Š…*ČdÕ.ÖUT �AĩP™ĶÚ%Aĩ�0T UT �̀jĄ +‚j P-TAP-ėšCÔÞÆ[ÕBÕÂŪŲũ`eQmí>$ãkŠ…*ČŠĩ͞ō ÕBÝ`UŧEč†b‹j—éÏÂäýŌÕBd&Õw<T ƒjũ―úcKĄZĻ‚S­“čÏyý)p·ė] +Š… PíūWl)T U’ģÚĄUc NĒ’ÕBĻvßŦ?ķŠ…*HákĩÁyŦÄUŦ$ĒZČ�Õî{õĮ–BĩP)|­VQmð”r°NN C6EUüz)ĄŦ'%Z/­ÚØÚÍN^ýĻ6„Žār°?Š… ĘĐVņĐū'ÏEQÕ.ómaJåĻ6„,x[”DTË d(G!Õęûžþ•r.ĘĐVŊ3xĻOŨs*ÅĮ‚jaCHąkĩ1ÕG!åˆs–œ@†,*ŠķôyŨ*Š}ÖŋfØí ZØÂÓĒ`ŨÔR­E‚Đ5ŦõģŲŠjQm›Š…]à äŒÕ7ž@ÎS­^ÜŠ… !ĻvM]ÕÆrΊN ë‰zÍĻ6ÖŠÝ ‚jaŨR­˜ï@ößÎE•;óTËĩZTÛ8‚jaŨ”S­˜WL™N­ßÕ‡Ŋý§ÁœJ"Š5‡jwƒ ZØ5EU[ž…ja+Š…]ƒjũ―úcKĄZĻ‚ ZØ5ĻvßŦ?ķŠ…*HĨ3*9ú<Ļ2@ĩû^ýąĨP-TAæ{Z”’č˜Ô’ÓÕBĻvßŦ?ķŠ…*Š…]ƒjũ―úcKĄZĻ‚ĖwŲŋ{?vŲ’ÓÕB―jŊïŧjkũīĻķ‚ŽOĩ\Ŧ…é+ŋÚúØũęÝP-TAf―-ę vTNT T2ĀĒÔÞÆ[ÕBÕ@3 ZĻ‚ĖýcŸārÐĪzNT �AĩPYŸjc'ĮP-�LÕB„§E@3 ZĻ‚ Z�hT UT �̀jĄ +‚j P-TAP-�4Š…*Š€f@ĩPAĩ�Ð ĻŠ Ļ�šÕBĪĖŋ†Ÿø\Öā#/P-�LÕBd›Š%‚ČT #åUë?bąĸ_NÁ>ÕQ.P-,ŒV­ō ãXÎاÝ �0T K"3ĐÖō?4“þUŊî�0ú°–7: ZčO OT­ąĨJ‹��:Ļē‘J'Į&ÚMjÉā\�H‚j!YŸjõ+đÉ"N7”P-�ØAĩ,{ēï8?§Ä ë+Õ/âw#(bŋ} qP-d#ÛyZÔžāV�Š…lĪIÕâY� Š…lĪ=ÕâY�Č�ÕB6Ōžj�2@ĩ Z��ĻēT �`�ÕB6‚j�  ZČFP-�€T ŲˆMĩŨ�šG-Q-Ä0Š��ŽĻēHŠ��ō@ĩÐ!Ļ�  Ļ:Õ�”ÕB‡ Z�€2 ZčT �PT ‚j�ʀjĄCP-�@P-tŠ�(Š…Aĩ��e@ĩÐ!Ļ�  Ļ:Õ�”ÕB‡ Z�€2 Z萙T{0―ķaĩÓköjÞî�( Zč9Tëøk=:ó{ēžūĀîAĩÐ!“U”—3‹ôgŧþ8˜ÓXO°Ã&‚ģÚā4|ö‰9�4 Š…)ŊZ_s1™*9íŸÆšaėƒēR��Ģ@ĩÐ!† ïād0:nbĒ―ˆÞ {…>þĶ�€ĶÐGKT bP­_dHžj‡č9-ŸÚŧĄũĄOũŦ’;7�4 Š…lÄĶZ%ÃÄYm°ž…gĩzg��Ä0ú ZčÉŠõäQŨj•Ää§\Ŧ€Ē ZČFæP­ÄW{yēģœœĀö•ŒUm°ÁŪ�Š… ČLŠą˜ķð#�ÕB6ēeÕ&ŊÕ�ĖŠ…ldËŠ•ČI`�€ŲAĩV-�Ā>@ĩ Z��ĻēT �`�ÕB6‚j�  ZČFP-�€T ŲŠ�0€j!Aĩ��P-d#Ļ�Ā�Š…lÕ�@ĩ Z��Ļē‘’ĸŲg–ëüãžÃ%ɎYpúĐĸ“ ‰MŽgŦVïs­ėėQŸ{Z—š ZČFJþŋZã1>VĩöēFP­„zļþ>—`k=ûÕī +Ēo+T ŲČdÕ*;§ņŋÄęjķŦÖøĸgýđ[ĸ6ĶZĨHlÅcëĻũÓ/ĒÐļaÅۀJëÆŋš}­G­ŽÞįØ7Ø1ĨÎ؟2ų‡Ö‹Ze=Ņ_žcg +ú€°]:ĩéÆŪ;Š…YVĩú@jŲýüņ$Yģ=›ĨÝ` ąftĀÆĮÖ?―ZcŸ―ēo―ÆO.ŦēŊĩĨøÄ?šĸПÍÞblãLAķ Š…rH=ÕģŲGƒÃ%Án(Í-ŽÚ)ÅĮJ-#QowÕΒh/’ŨĨéflóė]qJ?gAķ Š…rČU[Ž)8™maÕ*ýīôŠÄ°Ė ôYïm2qlq{åÁ5RJ)=ąô3c;čÅût?ŋ_ĘūšąÚōЄí‚jĄēÕęõ(Íé5ģYšÎá3:`Y#‹2R§ū 0ąĩTŦ”ēŨ9ŠQ―øÄĘQíP-”CđŲ8,ŒŌ3j+5cCąNąÆŒŠM‚‚Ý6ö9V<ŲnÆ°ŊÓ%ûšLôûÄŋŊņXČŦg…Š=\2KŊĶŨƒjĄēøïj•lb8^bŠ Ö,ĄĄ&ØKŧÎðĨIŪĢÞŦáŦŌDēŅa·õ1<˜!ŲįdúĶ-{O”ĩóŨHiČŌ“‰Å•œzĒŋ:~Ýíg +–AĮ_å‰ÎR Š…rO‹Ú&ģŸ%XŽ“ŠjavĶŠj_?œlÁRcAĩPAĩd+)ÚOeēđ@ë-3}@ˆĐÖxrCϖ Š…rŠÝ2HéŪęs™ mĻm1}@8\2Lũ—ýŋ#Š…Í!Ļ�Æ0}@H^ŅöœĖ†jaÍŠ€1L,'•R…Ū Z(‡”ü]ít2*Ÿ~NŋŋĒÓ;6û\�ZC,p­ÖޟŠ~€ŲT;đÅ Ą_ö° bŠ•Â?ŲÓAĩP™Iĩ–cÁ/˜<Ķbßc•‚Šj“ÔßëÉ^Gûæ +æt6ČĻí0l"cÃtčÂvAĩP™CĩþļīƒSĘ_Ž-Äj æ5gėdōÓéë8Ĩ­ŒOƒ]šē5 qôaŧ Z(‡ĖzŲŪĄ` ą‰ØôæėĨŒŸjīPũ,õ$+čЄí‚jĄRLĩCbý úÛXÍS&˜ąŠ,.ÓŨq”@+UTĩ–ŋ€> lT åōģZ{ĐX=y&ÍëäD—jÔؓ`Ί5Ū 4Ž> lT å-\ŦMÖėLÍĶt2ÏeĢÖqJ[Ó·Cv…~mÐ&ú€°]P-”CÖqrĖŠ­‚͉j=K'eåÓąë8ą'ą…`ŸýŪëQ6ŽŸÚĪŪïT …žĩ,‹Đ +'B!Ū„Ã~QVÕB6‚j—E?–gŽžhC� ‚j!AĩËRڀ–/į�Š…lÕ�@ĩ Z��ĻēT �`�ÕB6‚j�  ZČFP-�€T ŲŠ�0€j!Aĩ��P-d#6ÕN}Þ�ĀöŅGKT 1ŒŠ�€#Š…,’Š�€<P-tŠ�(Š…Aĩ��e˜ŪÚŌ=„Å@ĩ��%˜ĻÚš1˜Ōû�@ƒLQ-���$Aĩ�0;‡Ļ―aK Z�˜ÃŪo˜4Šķv7 Âę="P-�ĖN§ÚÚ―(Bw;ĻŅ5 ôgyŒ7Ä6ūúĻ�fÕJóŪi|õP-�ĖŠ•æ]Óøę; Z�˜T+ÍŧĶņÕw@ĩ�0;ĻVšwMãŦï€j`vŠŠ6ö‹ýí\, ÚÅ~R”WĸŠõÛŌ[/―ŅP-�Ž„rŠU|[ž—ŌŠ]æ ÔĘQ-Š€5PHĩÁ!ŪOôJPTĩI‰8MwËÁ ū%qŠUV*ķq&‚j`%TTí2“šåUģ‰þMÞhg=ŠÕW*ļqĶƒj`%ÔRíŨ7+ÎjýlvnZĩ>ýGÃląAĩ�°G*ÎjcŲæb 'óTŦ·ģŠY­ēRĻ�öM]ÕÆrÎÂÚN ë‰zÍ;P­’ÕĀū)ĪZ1߁ėŋ‹Zw įĐ6CĘIÖĐÚāŽķĉT �+Ąœj%tĩOũsÎÞzÅßÕ‡Ŋý§ÁœJâÖU+܁ � STĩuáiQ[yZTŅÓcKĄZ�˜T++pM!P-Š€5€jeŪ)ŠEĩ�°P­ŽĀ5…ØŠj j`% ZiÞ5ŊūŠ€ŲAĩŌžk_}T �ģÓŦöúĨÚڝ-Ŧ?öˆ@ĩ�0;jŧ&đö―XýQ Z�˜ÚáÔÞÆ°%P-��@QP-��@QP-��@QP-��@QP-��@QP-��@QP-��@QP-��@QP-��@QP-��@QP-��@QP-��@QbŠ%‚ bÆ@ĩAQ4zÕ^��€2Ü��� +óĸ�­Ö`Oü � \ No newline at end of file diff -Naur wfdb-10.2.5/doc/wug-src/wave/scripts/fixwug.sh wfdb-10.2.6/doc/wug-src/wave/scripts/fixwug.sh --- wfdb-10.2.5/doc/wug-src/wave/scripts/fixwug.sh Wed Dec 31 19:00:00 1969 +++ wfdb-10.2.6/doc/wug-src/wave/scripts/fixwug.sh Mon Jun 24 22:00:55 2002 @@ -0,0 +1,9 @@ +#!/bin/sh + +# file: fixwug.sh G. Moody 24 June 2002 + +cd $1 +R=`grep -l "<TITLE>Frequently Asked Questions" *.htm` +if [ "x$R" != "x" ]; then ln -s $R wave-faq.htm +else echo "Can't find wave-faq.htm" +fi diff -Naur wfdb-10.2.5/doc/wug-src/wave/scripts/wugfigures wfdb-10.2.6/doc/wug-src/wave/scripts/wugfigures --- wfdb-10.2.5/doc/wug-src/wave/scripts/wugfigures Thu Dec 20 17:15:33 2001 +++ wfdb-10.2.6/doc/wug-src/wave/scripts/wugfigures Thu Jun 20 11:40:02 2002 @@ -1,8 +1,8 @@ #! /bin/sh # file: wugfigures # -# Get or remove a set of WAVE User's Guide figures in the doc directory. The -# doc directory must be the current directory when this script is run. +# Get or remove a set of WAVE User's Guide figures in the wug-src directory. +# The wug-src directory must be the current directory when this script is run. if [ $# -eq 1 ]; then OPT=$1 else OPT=-grey @@ -17,32 +17,56 @@ do rm -f `basename $i .ppm.gz`.p* done ;; - -color) cp -f wave/ps/*.ps . + -color) for i in wave/ps/*.ps + do + OUT=`basename $i` + if [ ! -s $OUT ]; then + cp -f $i $OUT + echo $i '-->' $OUT + fi + done for i in wave/ppm/*.ppm.gz do OUT=`basename $i .ppm.gz`.ps - gzip -d <$i | pnmdepth 255 | pnmtops -noturn -scale .5 >$OUT - echo $i '-->' $OUT + if [ ! -s $OUT ]; then + gzip -d <$i | pnmdepth 255 | \ + pnmtops -noturn -scale .5 >$OUT 2>/dev/null + echo $i '-->' $OUT + fi done ;; - -grey) cp -f wave/ps/*.ps . + -grey) for i in wave/ps/*.ps + do + OUT=`basename $i` + if [ ! -s $OUT ]; then + cp -f $i $OUT + echo $i '-->' $OUT + fi + done for i in wave/ppm/*.ppm.gz do OUT=`basename $i .ppm.gz`.ps - gzip -d <$i | pnmdepth 255 | ppmtopgm | \ - pnmtops -noturn -scale .5 >$OUT - echo $i '-->' $OUT + if [ ! -s $OUT ]; then + gzip -d <$i | pnmdepth 255 | ppmtopgm | \ + pnmtops -noturn -scale .5 >$OUT 2>/dev/null + echo $i '-->' $OUT + fi done ;; -pdf) for i in wave/ps/*.ps do OUT=`basename $i .ps`.pdf - epstopdf --filter <$i >$OUT - echo $i '-->' $OUT + if [ ! -s $OUT ]; then + epstopdf --filter <$i >$OUT + echo $i '-->' $OUT + fi done for i in wave/ppm/*.ppm.gz do OUT=`basename $i .ppm.gz`.pdf - gzip -d <$i | pnmdepth 255 | pnmtops -noturn -scale .5 | \ - epstopdf --filter --outfile=$OUT - echo $i '-->' $OUT + if [ ! -s $OUT ]; then + gzip -d <$i | pnmdepth 255 | \ + pnmtops -noturn -scale .5 2>/dev/null | \ + epstopdf --filter --outfile=$OUT + echo $i '-->' $OUT + fi done ;; esac diff -Naur wfdb-10.2.5/doc/wug-src/wug.cover wfdb-10.2.6/doc/wug-src/wug.cover --- wfdb-10.2.5/doc/wug-src/wug.cover Sun Mar 10 11:15:28 2002 +++ wfdb-10.2.6/doc/wug-src/wug.cover Tue Jun 18 07:21:45 2002 @@ -45,7 +45,7 @@ -MARCH 2002 +JUNE 2002 .bp diff -Naur wfdb-10.2.5/doc/wug-src/wug.tex wfdb-10.2.6/doc/wug-src/wug.tex --- wfdb-10.2.5/doc/wug-src/wug.tex Sun Mar 10 11:31:47 2002 +++ wfdb-10.2.6/doc/wug-src/wug.tex Mon Jun 24 14:44:05 2002 @@ -3,7 +3,7 @@ % Recent LaTeX distributions include html.sty (written for latex2html). % If yours doesn't, get a copy from CTAN (http://www.ctan.org/), from % the current latex2html package (also available from CTAN), or from -% the wave/misc sudirectory of the directory where you found this +% the wave/misc subdirectory of the directory where you found this % file, and put the copy into this directory (or into the directory % that contains the other .sty files referenced below) before attempting % to process this file using LaTeX. @@ -34,7 +34,7 @@ \title{\WAVE{} User's Guide} \author{Fifth Edition\\ (revised and with corrections for \WAVE{} version 6.5)\\ -10 March 2002\\ +24 June 2002\\ \\ \\ \\ @@ -221,8 +221,8 @@ expanded over previous editions. In part, this reflects more complete coverage of the original material, but \WAVE{} itself has also grown. \WAVE{} 6.5 is freely available from -\hyperref{downloading from the Internet} -{Physionet (see section~} +\hyperref{PhysioNet} +{PhysioNet (see section~} {, page~\pageref{sec:getting-wave})} {sec:getting-wave}. @@ -253,13 +253,10 @@ {http://www-dsed.llnl.gov/files/programs/unix/latex2html/} from the same \LaTeX{} sources used for the printed manual. You can print your own copy from the PostScript version -\htmladdnormallink{here}{wug.ps}. The most recent \LaTeX{}, HTML, and +\htmladdnormallink{here}{wug.ps}. The most recent \LaTeX{}, HTML, PDF, and PostScript versions can be obtained from \htmladdnormallink{PhysioNet} -{http://www.physionet.org/}. If you wish to obtain a printed copy of -this guide, an -\htmladdnormallink{order form}{http://ecg.mit.edu/order-form.html} -is available on-line. +{http://www.physionet.org/}. I would be grateful for reports of any typographic or other problems in the HTML version, since the translation to HTML is automated and may be less than perfect. Note that the distributed HTML version uses @@ -307,6 +304,62 @@ Cambridge, Massachusetts\\ May, 1999 +\vfill + +\section*{Notes on the fifth edition} + +This edition contains updated figures, additional tutorial material, +and revisions to reflect recent changes in \WAVE{}. + +\index{GTKWave} Since version 1, \WAVE{} has used the XView toolkit, +an open source implementation of the Open Look GUI. Open Look is an +elegant and easy-to-use GUI, but it is no longer being actively +developed or supported, and as a result, it is unfamiliar to many +first-time \WAVE{} users. Newer user interface toolkits, such as the +open source GTK+ toolkit, have converged on a common set of graphical +elements and behaviors resembling those of the Motif GUI. GTK+ has a +very active developer community and has been ported from Linux to many +other Unix variants, and to MS Windows. A version of \WAVE{} that +uses the GTK+ toolkit is now available from PhysioNet. Sources and +precompiled versions of GTKWave for Linux and for MS-Windows are +available at +\htmladdnormallink{http://www\-.physio\-net\-.org/physio\-tools/\-beta/\-gtkwave/} +{http://www.physionet.org/physiotools/beta/gtkwave/}. Although +GTKWave is still in development, it is quite usable and contains +nearly all of the functionality of the XView-based \WAVE{} described +in this Guide. +\index{Open Look} + +\begin{figure}[h] +\centerline{\epsfig{file=GTKWave}} +\caption{GTKWave (beta).} +\index{GTKWave} +\label{fig:GTKWave} +\end{figure} + +This guide serves as the primary documentation for both \WAVE{} and +GTKWave, but the current edition does not contain any information +specific to GTKWave. + +If you find a difference between GTKWave and what is described in the +Wave User's Guide (other than a cosmetic difference in the user +interface elements), please check the GTKWave Beta Notes +page on PhysioNet +(\htmladdnormallink{http://www\-.physio\-net.org/\-physio\-tools/\-beta/\-gtkwave/\-notes\-.shtml} +{http://www.physionet.org/physiotools/beta/gtkwave/notes.shtml}) to see +if this difference has already been reported. If not, please send me a +note, citing the page number in the printed Wave User's Guide, or the +exact URL in the online version. Indicate what is different in +GTKWave, the name and version of the operating system you are using, +and suggest how the text should be changed. Your reports will help us +to prepare an accurate and up-to-date guide for GTKWave. + +\vspace{2em} +\noindent +GBM\\ +Cambridge, Massachusetts\\ +June, 2002 + \chapter{Introducing \WAVE{}} \pagenumbering{arabic} @@ -446,6 +499,8 @@ \subsubsection*{Notes:} +\index{olwm@{\tt olwm} (Open Look Window Manager)} +\index{olvwm@{\tt olvwm} (Open Look Virtual Window Manager)} \begin{description} \item[1. Starting the X server.] On some computers, the X server and the window manager @@ -454,10 +509,7 @@ before you can run \WAVE{}. This command may be `{\tt startx}' or `{\tt openwin}'; for details, check your X server manual (on a UNIX system, type `{\tt man X}'). If you have a choice of window managers, -use {\tt olwm} or {\tt olvwm} -\index{olwm@{\tt olwm} (Open Look Window Manager)} -\index{olvwm@{\tt olvwm} (Open Look Virtual Window Manager)} -if possible +use {\tt olwm} or {\tt olvwm} if possible \hyperref{(click here for details).} {(see Appendix~} {, page~\pageref{app:system-requirements}).} @@ -478,101 +530,107 @@ \index{terminal window}\index{window!terminal} \item[2. Initializing the environment.] -The form of this command depends on what shell (command -interpreter) +If you are using a recent version of \WAVE{}, you probably will not +need to do anything to initialize the environment (the WFDB path +and the name of the WFDB calibration file). Unless you keep input files +in non-standard places, or if you have created your own calibration +file in a non-standard location, you can skip this step. \index{shell}\index{command interpreter} -you use on the \WAVE{} host. To identify your -shell, log onto the \WAVE{} host \index{WAVE host@\WAVE{} host} -and type `{\tt echo -\$SHELL}'. \index{environment variables!SHELL}\index{SHELL environment variable} -If the response contains the characters `{\tt csh}', \index{csh@{\tt csh}}\index{C-shell} -you are using the C-shell (or a variant of it); in this case, use -`{\tt source /usr/bin/cshsetwfdb}' \index{cshsetwfdb@{\tt cshsetwfdb} command} -to initialize the environment. Otherwise, use `{\tt .~setwfdb}' \index{setwfdb@{\tt setwfdb} command} -to do so (don't omit the -`{\tt .}' in this case). Usually, the appropriate command is included in -your `{\tt .profile}' \index{profile@{\tt .profile}} \index{login@{\tt .login}} -or `{\tt .login}' -script on the \WAVE{} host, -so that it need not be entered each time you log onto the \WAVE{} -host. See -\htmladdnormallink{{\tt setwfdb(1)}}{../dbag/setwfd-1.htm} -(type `{\tt man setwfdb}' on the \WAVE{} host) for further -information. + +If you do need to initialize your environment, this is typically done +using a command at login time. The form of this command depends on +what shell (command interpreter) you use on the \WAVE{} host. To +identify your shell, log onto the \WAVE{} host \index{WAVE +host@\WAVE{} host} and type `{\tt echo \$SHELL}'. If the response +contains the characters `{\tt csh}', you are using the C-shell (or a +variant of it); in this case, use `{\tt source /usr/bin/cshsetwfdb}' +to initialize the environment. Otherwise, use `{\tt .~setwfdb}' to do +so (don't omit the `{\tt .}' in this case). Usually, the appropriate +command is included in your `{\tt .profile}' or `{\tt .login}' script +on the \WAVE{} host, so that it need not be entered each time you log +onto the \WAVE{} host. See \htmladdnormallink{{\tt +setwfdb(1)}}{../wag/setwfd-1.htm} (type `{\tt man setwfdb}' on the +\WAVE{} host) for further information. \item[3. Simulating a middle button click.] -\index{mouse!middle button!simulating} -\index{middle mouse button!simulating} -\index{chording (mouse technique)} On a two-button mouse, this is often done by clicking both buttons simultaneously; on a one-button mouse, this is usually performed by pressing and holding a keyboard key such as \keycap{Shift} while clicking the mouse button. Refer to your X server documentation. +\index{mouse!middle button!simulating} +\index{middle mouse button!simulating} +\index{chording (mouse technique)} \item[4. Simulating a right button click.] +This is usually done by pressing and holding a keyboard key while +clicking the mouse button. Refer to your X server documentation. \index{mouse!right button!simulating} \index{right mouse button!simulating} \index{chording (mouse technique)} -This is usually done by pressing and holding a keyboard key while -clicking the mouse button. Refer to your X server documentation. \item[5. Your computer's name.] +If you don't know your computer's name, you may be able to discover it +by typing the command `{\tt hostname}' (on a UNIX system), or by +logging in to the \WAVE{} host and typing the command `{\tt who am I}' +(your computer's name should appear at the end of the output). If the +\WAVE{} host doesn't recognize your computer by name, use your +computer's IP address (in the form {\tt a.b.c.d}, where {\tt a}, {\tt +b}, {\tt c}, and {\tt d} are decimal numbers between 0 and 255). \index{hostname@{\tt hostname}} \index{names of computers} -If you don't know your computer's name, you may be able to discover -it by typing the command `{\tt hostname}' (on a UNIX system), or by -logging in to the \WAVE{} host \index{WAVE host@\WAVE{} host} -and typing the command `{\tt who am I}' \index{who am I command@{\tt who am I} command} -(your computer's name should appear at the end of the output). If the -\WAVE{} host doesn't recognize your computer by name, use -your computer's IP address \index{IP address} \index{address, IP (Internet Protocol)} -(in the form {\tt a.b.c.d}, where {\tt a}, -{\tt b}, {\tt c}, and {\tt d} are decimal numbers between 0 and 255). \item[6. The \WAVE{} host's name.] If your computer doesn't recognize the \WAVE{} host by name, use the \WAVE{} host's IP address. \item[7. Permitting access to your display.] -This command is usually needed if your computer is running UNIX. -For example, if the name of the \WAVE{} host is {\tt atlantic}, this -command would be `{\tt xhost +atlantic}'. +If you use {\tt ssh} (see the next item) to login to the \WAVE{} host, +skip this step. Otherwise, this command is usually +needed if your computer is running UNIX. For example, if the name of +the \WAVE{} host is {\tt atlantic}, this command would be `{\tt xhost ++atlantic}'. If your computer is not running UNIX, there may not be +any command required; if in doubt, see your X server manual. \index{xhost command@{\tt xhost} command} -If your computer is not running -UNIX, there may not be any command required; if in doubt, see your X server -manual. +\index{ssh command@{\tt ssh} command} \item[8. Logging onto the \WAVE{} host.] -This is probably a command of the form `{\tt telnet atlantic}' or (a safer -alternative) `{\tt ssh atlantic}'. + +This is probably a command of the form `{\tt ssh atlantic}'. You will +probably be prompted to enter your password when you execute this +command. If you don't have {\tt ssh} on your computer, and an {\tt +ssh} server on the \WAVE{} host, it is very strongly recommended that you +obtain and install them (both are freely available from +\htmladdnormallink{http://www.openssh.org/}{http://www.openssh.org/}). +Use {\tt telnet} only as a last resort, and never on a public network. +\index{ssh command@{\tt ssh} command} \index{telnet command@{\tt telnet} command} -You will -probably be prompted to enter your password when you execute this command. \item[9. Redirecting \WAVE{} output to your display.] -\index{environment variables!DISPLAY}\index{SHELL environment variable} \label{sec:setting-display} -Assume that the name of your computer is {\tt arctic}. -If you use the C-shell on the \WAVE{} host (see note 2 above), the -command would be `{\tt setenv DISPLAY arctic:0}'. -Otherwise, it would +If you use {\tt ssh} (see above), skip this step. Otherwise, you will +need to set the {\tt DISPLAY} environment variable to point to your +computer. Assume that the name of your computer is {\tt arctic}. If +you use the C-shell on the \WAVE{} host (see note 2 above), the +command would be `{\tt setenv DISPLAY arctic:0}'. Otherwise, it would be `{\tt DISPLAY=arctic:0; export DISPLAY}'. It is possible to set up -\index{profile@{\tt .profile}} -\index{login@{\tt .login}} your {\tt .profile} or {\tt .login} script so that this command can be executed automatically each time you log onto the \WAVE{} host. Consult your system administrator for details. +\index{environment variables!DISPLAY} +\index{SHELL environment variable} +\index{profile@{\tt .profile}} +\index{login@{\tt .login}} \end{description} @@ -595,7 +653,6 @@ window outline to the desired location on your screen in order to make the window appear. -\index{moving windows}\index{window!moving}\index{dragging} Before going any further, find out how to move windows on your screen if you don't already know how to do so. (You will need to do this occasionally while using \WAVE{}, since its windows may sometimes @@ -607,51 +664,48 @@ the desired location before releasing the mouse button. (This common action is called \emph{dragging}, as in the expression `drag the window using the left button'.) Try moving the terminal window now. +\index{moving windows}\index{window!moving}\index{dragging} -For this exercise, all commands should be typed into the same terminal window. -Once again, however, differences in window managers may affect how you do -this. Some window managers use a \emph{focus-follows-mouse} +For this exercise, all commands should be typed into the same terminal +window. Once again, however, differences in window managers may +affect how you do this. Some window managers use a +\emph{focus-follows-mouse} policy: you can type into a window whenever +the mouse pointer is in the window. Others use a \emph{click-to-type} +policy: you must click the left mouse button within a window before +you can type into it, but the mouse pointer need not remain in the +window while you type (this policy will be familiar to Macintosh and +Microsoft Windows users). If you use {\tt olwm} or {\tt olvwm} as +your window manager, as recommended, you may choose the policy you +prefer using the {\sf Properties} menu (click right on the background +or root window, and select {\sf Properties} from the pop-up menu that +appears). \index{focus-follows-mouse policy} -policy: you can -type into a window whenever the mouse pointer is in the window. Others use -a \emph{click-to-type} \index{click-to-type policy} -policy: you must click the left mouse button within -a window before you can type into it, but the mouse pointer need not remain -in the window while you type (this policy will be familiar to Macintosh and -Microsoft Windows users). If you use {\tt olwm} or {\tt olvwm} \index{olwm@{\tt olwm} (Open Look Window Manager)} \index{olvwm@{\tt olvwm} (Open Look Virtual Window Manager)} -as your -window manager, as recommended, you may choose the policy you prefer using -the {\sf Properties} menu (click right on the background or root window, -and select {\sf Properties} from the pop-up menu that appears). If you have previous experience with X Window System and Open Look user interface applications, much of what you see will be familiar. This exercise does not assume that you have any such experience, but you may find it helpful to read through an introductory book on the -Open Look user interface -\index{Open Look} -such as Sun's {\it OpenWindows User's Guide}, +Open Look user interface such as Sun's {\it OpenWindows User's Guide}, or a more general introduction such as O'Reilly's {\it X Window System in a Nutshell}. Please note that, although \WAVE{} uses many Open Look controls, it is not fully Open Look compliant; in particular, -actions within its signal window (see chapter 2) do not comply with Open -Look style guidelines.} - +actions within its signal window (see chapter 2) do not comply with +Open Look style guidelines.} +\index{Open Look} \subsection*{If you need to run \WAVE{} remotely} -If your computer is also the \WAVE{} host, -\index{WAVE host@\WAVE{} host} -skip ahead to the next +If your computer is also the \WAVE{} host, skip ahead to the next paragraph. Otherwise, type the command(s) from items 7, 8, and 9 of -the worksheet, in that order (entering your password if prompted -to do so by the \WAVE{} host). These commands are the only -differences in the procedures for running \WAVE{} remotely (with -different desktop and \WAVE{} host systems) and locally (with your -own computer serving as the \WAVE{} host). +the worksheet, in that order (entering your password if prompted to do +so by the \WAVE{} host). These commands are the only differences in +the procedures for running \WAVE{} remotely (with different desktop +and \WAVE{} host systems) and locally (with your own computer serving +as the \WAVE{} host). +\index{WAVE host@\WAVE{} host} \subsection*{Checking the environment and the sample record} @@ -660,10 +714,11 @@ input files in any of the directories specified by the {\em WFDB path} (the value of the {\tt WFDB} environment variable, if set, or a compiled-in default path as given in the WFDB library source file {\tt wfdblib.h} -otherwise; see the discussion of the database path in the -\htmladdnormallink{{\it WFDB Programmer's Guide}}{../dbpg/dbpg.htm} +otherwise; see the discussion of the +\htmladdnormallink{database path}{../wpg/database-path.htm} +in the \htmladdnormallink{{\it WFDB Programmer's Guide}}{../wpg/wpg.htm} for details). Verify that the sample record is accessible on the WFDB -path using the command ``{\\tt wfdbwhich 100s.hea}''. If the response +path using the command ``{\tt wfdbwhich 100s.hea}''. If the response begins with \begin{verbatim} `100s.hea': not found @@ -696,31 +751,31 @@ \index{starting WAVE@starting \WAVE{}}\index{wave command@{\tt wave} command} \index{terminal window} +\index{WAVE host@\WAVE{} host} +\index{environment variables!PATH}\index{PATH environment variable} + \WAVE{} is usually started by typing a command in a terminal window. Type: \begin{verbatim} wave \end{verbatim} -(Be sure to type this using lower-case letters.) -If you see a response similar to `{\tt wave: Command not found.}', you will -need to find the executable copy of \WAVE{} on the \WAVE{} host -\index{WAVE host@\WAVE{} host} -system. -(It may be in a directory that is not part of your {\tt PATH}; -\index{environment variables!PATH}\index{PATH environment variable} -if so, you may -wish to add that directory to your {\tt PATH} by editing {\tt .cshrc} or {\tt -.profile} in your home directory. If the previous sentence makes no sense to -you, refer to any introductory book on UNIX for guidance.) If the response is -`{\tt wave:~permission denied}', see your system administrator about obtaining -permission to run \WAVE{}. +(Be sure to type this using lower-case letters.) If you see a +response similar to `{\tt wave:~Command not found.}', you will need to +find the executable copy of \WAVE{} on the \WAVE{} host system. (It +may be in a directory that is not part of your {\tt PATH}; if so, you +may wish to add that directory to your {\tt PATH} by editing {\tt +.cshrc} or {\tt .profile} in your home directory. If the previous +sentence makes no sense to you, refer to any introductory book on UNIX +for guidance.) If the response is `{\tt wave:~permission denied}', +see your system administrator about obtaining permission to run +\WAVE{}. If all goes as it should, \WAVE{} prints a concise summary of its command format, which should appear (approximately) as: \begin{verbatim} WAVE version XXX (MMM DD YYYY) WFDB library version XXXXXX (MMM DD YYYY). -usage: wave -r record-name [ options ] +usage: wave -r RECORD[+RECORD] [ options ] Options are: -a annotator-name Open an annotation file @@ -730,6 +785,8 @@ -H Use high-resolution mode -m Use black and white only -O Use overlay graphics + -p PATH Search for input files in PATH + (if not found in the WFDB path) -s SIGNAL [SIGNAL ...] Initialize the signal list -S Use a shared colormap -Vx Set initial display option x @@ -745,15 +802,13 @@ or open `http://www.physionet.org/physiotools/wug/' using your web browser. \end{verbatim} -\index{environment variables!WFDB}\index{WFDB environment variable} -\index{environment variables!DISPLAY}\index{DISPLAY environment variable} \noindent The comments about setting the {\tt DISPLAY} and {\tt WFDB} variables will not -appear if these variables have been set (as they should have been earlier). +appear if you have already set these variables. +\index{environment variables!WFDB}\index{WFDB environment variable} +\index{environment variables!DISPLAY}\index{DISPLAY environment variable} Now try using \WAVE{} to view record {\tt 100s}, together with its -\index{atr (reference) annotations@{\tt atr} (reference) annotations} -\index{annotation!reference}\index{reference annotations} {\tt atr} (reference) annotations. Type: \begin{verbatim} wave -r 100s -a atr & @@ -762,6 +817,8 @@ commands in the terminal emulator window without interrupting or exiting from \WAVE{}. After a few seconds, \WAVE{}'s \emph{main window} (figure~\ref{fig:main-window}) opens. +\index{atr (reference) annotations@{\tt atr} (reference) annotations} +\index{annotation!reference}\index{reference annotations} \begin{htmlonly} \index{main window} \end{htmlonly} @@ -1040,18 +1097,18 @@ upper left corner of the window), and then clicking left on the {\sf Quit} item in the window menu. -\index{Netscape}\index{web browsers} +\index{Mozilla}\index{web browsers} \index{on-line manual}\index{User's Guide (on-line)} \index{WAVE User's Guide (on-line)@\WAVE{} User's Guide (on-line)} The third (and most comprehensive) form of on-line help can be used if a suitable web browser is available on the \WAVE{} host system. -(\WAVE{} uses Netscape 1.1 or any later version by default. See +(\WAVE{} uses Mozilla by default. Set the environment variable {\tt URLV} +to the name of your browser if you prefer a different browser. See \hyperref{\WAVE{} and the Web} {section~} {, page~\pageref{sec:web},} {sec:web} -for details on obtaining Netscape, or on configuring \WAVE{} to use a -different web browser.) +for details on configuring \WAVE{} and your browser to work together. Click left on the \button{WAVE User's Guide} button in the {\sf Help Topics} window to open this manual using your web browser. If your browser is not running already, this may take a few moments while @@ -1144,7 +1201,7 @@ figure~\ref{fig:analysis-commands}. Below the command, its error output appears. When the command has run to completion (which will take only a few seconds unless the \WAVE{} host is heavily loaded), an annotation file -named `{\tt qrs.100s}' is written into the current directory. +named `{\tt 100s.qrs}' is written into the current directory. If you wish, the {\sf Analyze} window or the {\sf Analysis Commands} window, or both, may be dismissed (by selecting {\sf Quit} from the @@ -1167,7 +1224,7 @@ \end{wrapfigure} To load annotations \index{annotation file!loading}\index{loading an annotation file} -from `{\tt qrs.100s}' into \WAVE{}, click right on +from `{\tt 100s.qrs}' into \WAVE{}, click right on \menubutton{File}, and click left on the {\sf Load...} selection in the File menu. \begin{figure} @@ -1185,7 +1242,7 @@ contains text items that specify a record and and an annotator name. Click left next to the {\sf Annotator} field, type `{\tt qrs}', and, as always, press \keycap{ -Enter}. The contents of `{\tt qrs.100s}' are loaded into \WAVE{}, and +Enter}. The contents of `{\tt 100s.qrs}' are loaded into \WAVE{}, and annotations appear in the signal window. The title bar changes to indicate the annotator name. The {\sf Load} window also contains items that specify the name of the @@ -1527,7 +1584,7 @@ these, there are several {\sf Search for} strings that \WAVE{} interprets in special ways: -\begin{tabular*}{\textwidth}{l p{3.5 in}} +\begin{tabular*}{5.5 in}{l p{4.75 in}} {\tt *v} & {matches any ventricular ectopic beat} \\ {\tt *s} & {matches any supraventricular ectopic beat} \\ {\tt *n} & {matches any other beat type} \\ @@ -1589,8 +1646,9 @@ \index{Quit button@{\sf Quit} button} on the main control panel, or from the window menu). You will find two new files in the -current directory. The file called `{\tt qrs.100s}' is the edited version of -the annotation file that you have just created, and `{\tt \_qrs.100s}' is the +current directory. The file called `{\tt 100s.qrs}' is the edited version of +the annotation file that you have just created, and `\verb+100s.qrs~+' +is the \index{backup}\index{annotation file!backup} previous version (in this case, containing the unedited annotations as produced by {\tt sqrs}). At most one previous version is saved as a backup; if the @@ -1697,12 +1755,12 @@ and then press \keycap{Return} (or \keycap{Enter}). \WAVE{} then directs your web browser to display the data specified by the URL. (If your web browser is not running, \WAVE{} starts it.) By default, -\WAVE{} uses Netscape 1.1 or any later version available on the -\WAVE{} host. To configure \WAVE{} to use a different browser, see +\WAVE{} uses Mozilla. To configure \WAVE{} to use a different browser, see \hyperref{\WAVE{} and the Web} {section~} {, page~\pageref{sec:web}} {sec:web}. +\index{Mozilla}\index{web browser} If the URL string does not contain a {\it protocol}{\tt ://} prefix (where {\it protocol} is typically {\tt http} or {\tt ftp}), \WAVE{} @@ -1711,17 +1769,18 @@ the necessary path information to the beginning of the URL before directing your web browser to display the associated data. -\WAVE{} does not include built-in facilities for editing external data. -You may insert and edit link annotations themselves, however, using -the normal annotation editing facilities of \WAVE{}. To create a link -annotation, select `{\tt @}' from the {\sf Type} menu of the {\sf -Annotation Template}, and enter the URL in the {\sf aux} field. If -you wish to supply a description to be displayed by \WAVE{} in place of -the URL, enter it after the URL, separating it from the URL with a -space character. The current URL (i.e., the one associated with the -most recently selected link annotation) can be passed by \WAVE{} to an external -program such as a web browser or an HTML editor via the {\tt \$URL} -menu variable (see the comments in \WAVE{}'s menu file for details). +\WAVE{} does not include built-in facilities for editing external +data. You may insert and edit link annotations themselves, however, +using the normal annotation editing facilities of \WAVE{}. To create +a link annotation, select `{\tt @}' from the {\sf Type} menu of the +{\sf Annotation Template}, and enter the URL in the {\sf Text} ({\tt +aux}) field. If you wish to supply a description to be displayed by +\WAVE{} in place of the URL, enter it after the URL, separating it +from the URL with a space character. The current URL (i.e., the one +associated with the most recently selected link annotation) can be +passed by \WAVE{} to an external program such as a web browser or an +HTML editor via the {\tt \$URL} menu variable (see the comments in +\WAVE{}'s menu file for details). \section{Creating and using new annotation types} @@ -1798,10 +1857,10 @@ \index{sqrs command@{\tt sqrs} command} If you refer to the {\tt man} page for {\tt sqrs}, -\htmladdnormallink{{\tt sqrs(1)}}{../dbag/sqrs-1.htm} +\htmladdnormallink{{\tt sqrs(1)}}{../wag/sqrs-1.htm} (either by typing `{\tt man sqrs}' in a terminal emulator window, or by looking it up in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}), +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}), you will see that the second command-line argument ({\tt 100s}) is (not surprisingly) the record name, `{\tt -f 0}' instructs {\tt sqrs} to start at the beginning of the @@ -1813,17 +1872,29 @@ \label{sec:menu-file} \index{menu file} To understand where the command comes from, we need to inspect \WAVE{}'s +\emph{menu file}. +\WAVE{} allows you to edit its menu file using any editor of your +choice. By default, \WAVE{} uses a simple Open Look text editor +called {\tt textedit}, which is included with the XView package used +by \WAVE{}. If you prefer to use another editor such as {\tt emacs}, +set and export the {\tt EDITOR} environment variable before starting +\WAVE{} (you may wish to include this step in your {\tt .login} or +{\tt .cshrc}). Most other UNIX applications that invoke an external +text editor use the {\tt EDITOR} environment variable in the same way. +\index{EDITOR environment variable} +\index{environment variables!EDITOR} +\index{textedit command@{\tt textedit} command} + +Click left on the \button{Edit menu} button in the {\sf Analyze} \begin{wrapfigure}[12]{r}{7.25cm} \mbox{\epsfig{file=system-menu}} \end{wrapfigure} -\emph{menu file}. Click left on the \button{Edit menu} button in the -{\sf Analyze} window. Unless your -\WAVE{} menu has already been customized, \WAVE{} pops up a -notice as shown at right. -Click left on \button{Copy} to continue with this exercise. After a few -seconds, the \WAVE{} menu file appears (in an OpenWindows {\tt textedit} -window as in figure~\ref{fig:wave-menu}, unless you have specified a -different editor by setting the {\tt EDITOR} environment variable). +window. Unless your \WAVE{} menu has already been customized, \WAVE{} +pops up a notice as shown at right. Click left on \button{Copy} to +continue with this exercise. After a few seconds, the \WAVE{} menu +file appears (in an OpenWindows {\tt textedit} window as in +figure~\ref{fig:wave-menu}, unless you have specified a different +editor by setting the {\tt EDITOR} environment variable). \index{EDITOR environment variable} \index{environment variables!EDITOR} \index{textedit command@{\tt textedit} command} @@ -1835,10 +1906,6 @@ \label{fig:wave-menu} \end{figure} -\index{Analyze window@{\sf Analyze} window} -\index{analysis commands window@{\sf Analysis Commands} window} -\index{menu variables} -\index{signal!list} The comments at the beginning of the \WAVE{} menu file describe how it works. Each of the buttons in the {\sf Analyze} window (except for those in the first three rows) corresponds to an entry in the menu @@ -1863,9 +1930,9 @@ been defined, the {\sf End} field is `{\sf end of record}', and `{\tt \$END}' is determined by the record length as encoded in the header file for the record (see -\htmladdnormallink{{\tt header(5)}}{../dbag/header-5.htm}, +\htmladdnormallink{{\tt header(5)}}{../wag/header-5.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}). +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}). Finally, `{\tt \$SIGNAL}' is taken from the {\sf Signal} field of the {\sf Analyze} window; it specifies which signal is to be analyzed. @@ -1873,6 +1940,10 @@ the string `{\tt \$SIGNALS}' is taken from the {\sf Signal list} field.) Examine the commands defined in the default \WAVE{} menu; they should give you an idea of what is possible. +\index{Analyze window@{\sf Analyze} window} +\index{analysis commands window@{\sf Analysis Commands} window} +\index{menu variables} +\index{signal!list} \section{Defining a region of interest} @@ -1905,15 +1976,15 @@ \index{tach command@{\tt tach} command} Generating a heart rate signal is simple enough, given a beat annotation file and -\htmladdnormallink{{\tt tach}}{../dbag/tach-1.htm}, +\htmladdnormallink{{\tt tach}}{../wag/tach-1.htm}, a program supplied as part of the WFDB Software Package. {\tt tach} reads an annotation file, calculates an instantaneous heart rate for each cardiac cycle from the reciprocal of the interval between successive beat annotations, and then uniformily resamples this signal (by default, at 2 Hz). Referring to the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}, +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}, we find the command we need to generate a heart rate signal from -`{\tt qrs.100s'}: +`{\tt 100s.qrs'}: \begin{verbatim} tach -r 100s -a qrs -f 0 -t 1:0 \end{verbatim} @@ -1994,12 +2065,12 @@ Although you can type into the {\sf Signal list} field directly to change it, you can also do so using the mouse. Pointing to a signal, hold down the \keycap{Control} key while clicking left to add it to the signal list, or hold -down the {\sf Meta} key while clicking left to delete its first -\index{Meta key@{\sf Meta} key} +down the \keycap{Meta} key while clicking left to delete its first occurrence from the signal list. (Most keyboards do not have a key labelled {\sf Meta}. On most Sun keyboards, the {\sf Meta} keys look like this: \keycap{$\Diamond$}; they flank the space bar. On most other keyboards, the \keycap{Alt} key is equivalent to {\sf Meta}.) +\index{Meta key@{\sf Meta} key} \section{Using a customized menu file} @@ -2197,7 +2268,7 @@ \htmladdnormallink{Here}{stdev.c} is the C source for the program. If this looks unfamiliar, read about how to write WFDB applications in the -\htmladdnormallink{{\it WFDB Programmer's Guide}}{../dbpg/dbpg.htm}. +\htmladdnormallink{{\it WFDB Programmer's Guide}}{../wpg/wpg.htm}. \begin{latexonly} {\small @@ -2258,8 +2329,8 @@ \index{plt command@{\tt plt} command} If {\tt plt} has been installed on your system, you can use it to plot this output (see -\htmladdnormallink{{\tt plt(1)}}{../dbag/plt-1.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}, +\htmladdnormallink{{\tt plt(1)}}{../wag/plt-1.htm}, in the +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}, for details on {\tt plt}). To do so, modify the entry in the menu file, so that it becomes: \begin{verbatim} @@ -2326,7 +2397,7 @@ \item You may wish to examine using beat averaging (or median filtering) to reduce noise in the measurements further; the -\htmladdnormallink{{\it WFDB Programmer's Guide}}{../dbpg/dbpg.htm} +\htmladdnormallink{{\it WFDB Programmer's Guide}}{../wpg/wpg.htm} describes a beat averager that may be a useful starting point. \item @@ -2395,13 +2466,15 @@ specified. {\tt wave-remote} exits immediately once it has delivered its instructions to \WAVE{}. -As an alternative to the command-line interface offered by {\tt -wave-remote}, the {\tt wavescript} application provides the same -services, but is controlled by a script file (named on the {\tt -wavescript} command line). Scripts for {\tt wavescript} should contain -on each non-comment line a single option/argument pair as described -above for {\tt wave-remote}. Any line that does not begin with a -`{\tt -}' is treated as a comment line. For example, if the file {\tt example.xws} contains +As an alternative to the command-line interface offered by {\tt wave-remote}, +the {\tt wavescript} application provides the same services, but is controlled +by a script file (named on the {\tt wavescript} command line). Scripts for +{\tt wavescript} should contain on each non-comment line a single +option/argument pair as described above for {\tt wave-remote}. In addition to +{\tt wave-remote}'s options, {\tt wavescript} also accepts a {\tt -p {\em +path}} option; the {\tt \em path} argument is appended to the WFDB path. Any +line in the script that does not begin with a `{\tt -}' is treated as a comment +line. For example, if the file {\tt example.xws} contains \begin{verbatim} # Here is a comment -r 100s @@ -2443,13 +2516,14 @@ \subsection*{Controlling \WAVE{} from a web browser} -Most web browsers, such as Netscape, can use so-called \emph{helper} -or \emph{viewer} applications. These are external applications that -are invoked by the browser to present data in formats that (usually) -are not supported by the browser directly. For example, browsers -often use {\tt ghostscript} to display PostScript data. It is -possible to configure Netscape and other web browsers so that \WAVE{} -can be used indirectly as a helper application. +Most web browsers, such as Mozilla or Netscape, can use so-called \emph{helper} +or \emph{viewer} applications. These are external applications that are +invoked by the browser to present data in formats that (usually) are not +supported by the browser directly. For example, browsers often use {\tt +ghostscript} to display PostScript data. It is possible to configure Mozilla +and other web browsers so that \WAVE{} can be used indirectly as a helper +application. +\index{Mozilla}\index{Netscape}\index{web browser} By using \hyperref{{\tt wavescript}} @@ -2461,33 +2535,71 @@ to move to a specified location in the record. With this approach, it is not necessary to start a new \WAVE{} process each time. -You can set up your browser to view files with the suffix {\tt .xws} (or -the MIME type {\tt application/x-wavescript}) using {\tt wavescript}. To -do so, add the line -\begin{verbatim} - type=application/x-wavescript exts=xws -\end{verbatim} -\noindent -to the file named {\tt .mime.types} in your home directory, and add the line -\begin{verbatim} - application/x-wavescript; wavescript %s -\end{verbatim} -\noindent -to the file named {\tt .mailcap} (also in your home directory). If -your browser is Netscape 4.x, you can make these additions to {\tt -.mime.types} and {\tt .mailcap} by choosing {\sf Preferences} -from the Edit menu, opening the {\sf Navigator} category in the -{\sf Preferences} window, selecting {\sf Applications}, then -clicking on the {\sf New...} button. Fill in the dialog box as shown in -figure~\ref{fig:netscape-new-helper}, then save your settings. (Other -versions of Netscape have similar dialog boxes, and similar operations -may be possible with other browsers; consult your browser's documentation.) +You can set up your browser to view files with the MIME type +{\tt appli\-cation/\-x-wavescript} using {\tt wavescript}. Some browsers, +including Mozilla and Netscape, also allow you to specify that any URL with the +{\tt .xws} suffix should be handled by {\tt wavescript}. + +If you use Mozilla, choose {\sf Preferences} from the {\sf Edit} menu, +then open the {\sf Navigator} category and choose {\sf Helper Applications}. +Click on {\sf New Type...} to pop up a dialog, where you should enter +'{\tt WAVEScript}' as the {\sf Description of type}, '{\tt xws}' as the +{\sf File extension}, '{\tt application/x-wavescript}' as the {\sf MIME type}, +and '{\tt wavescript}' as the {\sf Application to use}' (omitting the +quotation marks in each case). Click {\sf OK} to close the {\sf New Type} +dialog, and click {\sf OK} in the {\sf Preferences} dialog to save your +changes. +\index{Mozilla} + +\begin{figure} +\centerline{\epsfig{file=mozilla-new-helper}} +\caption{Adding {\tt wavescript} as a Mozilla helper.} +\label{fig:mozilla-new-helper} +\end{figure} + +If your browser is Netscape 4.x, do this by choosing {\sf Preferences} from the +{\sf Edit} menu, opening the {\sf Navigator} category in the {\sf Preferences} +window, selecting {\sf Applications}, then clicking on the {\sf New...} button. +Fill in the dialog box as shown in figure~\ref{fig:netscape-new-helper} (enter +'{\tt WAVEScript}' as the {\sf Description}, '{\tt application/x-wavescript}' +as the {\sf MIMEType}, '{\tt xws}' as the {\sf Suffixes}, click on the radio +button next to {\sf Application} and enter '{\tt wavescript \%s}' (note the +'{\tt \%s}') as the {\sf Application}, then save your settings by clicking on +{\sf OK} in each of the dialogs. (Other versions of Netscape have similar +dialog boxes.) +\index{Netscape} + \begin{figure} \centerline{\epsfig{file=netscape-new-helper}} \caption{Adding {\tt wavescript} as a Netscape helper.} \label{fig:netscape-new-helper} \end{figure} +If you use Galeon, choose {\sf Preferences} from the {\sf Settings} menu, then +select {\sf Handlers}, then {\sf MIME Types}, then click on {\sf New}. Enter +'{\tt application/x-wavescript}' as the MIME type and '{\tt wavescript}' as the +Helper (note that the quotation marks are not part of either entry). Select +{\sf Run with helper} and {\sf Always use this helper}; do not select {\sf Run +in terminal} or {\sf Processes URL}. Save your changes by clicking on {\sf +Close}. Note that Galeon does not support using the file suffix to select +a helper application, so Galeon will only be able to control \WAVE{} if the +web server is properly configured to transmit the +{\tt applica\-tion/\-x-wave\-script} MIME type for {\tt .xws} files (see +\hyperref{Serving .xws files} +{Serving .xws files, section~} +{, page~\pageref{sec:serving-xws}} +{sec:serving-xws}). +\index{Galeon} + +\begin{figure} +\centerline{\epsfig{file=galeon-new-helper}} +\caption{Adding {\tt wavescript} as a Galeon helper.} +\label{fig:galeon-new-helper} +\end{figure} + +Similar operations may be possible with other browsers; consult your browser's +documentation. + \begin{latexonly} \begin{wrapfigure}[3]{l}{1.5cm} \mbox{\epsfig{file=wave-icon}} @@ -2520,6 +2632,7 @@ \end{latexonly} \subsection*{Serving {\tt .xws} files} +\label{sec:serving-xws} If you plan to make {\tt .xws} files available from a Web server, you will also need to configure your Web server so that it sends the @@ -2559,14 +2672,17 @@ happens, simply delete any {\tt .xws} files from your browser's cache. \subsection*{Controlling a web browser from \WAVE{}} +\index{Galeon}\index{Konqueror}\index{Mozilla}\index{Netscape}\index{Opera} +\index{web browser} -\WAVE{} uses a web browser to display external data associated -with link annotations, and to display the on-line version of this -guide. A suitable web browser must be installed on the \WAVE{} host -in order for this to work. By default, \WAVE{} uses Netscape version -1.1 (or any later version; Netscape may be obtained freely by -anonymous FTP from -\htmladdnormallink{{\tt ftp.netscape.com}}{ftp://ftp.netscape.com/}). +\WAVE{} uses a web browser to display external data associated with link +annotations, and to display the on-line version of this guide. A suitable web +browser must be installed on the \WAVE{} host in order for this to work. By +default, \WAVE{} uses Mozilla (\htmladdnormallink{{\tt +http://www.mozilla.org/}}{http://www.mozilla.org/}); several other browsers, +including Galeon, Konqueror, Netscape, and Opera, can also be controlled by +\WAVE{}. If you prefer to use one of these rather than Mozilla, set the +environment variable {\tt URLV} to the name of your browser. \WAVE{} controls the web browser in the same way it controls other external programs: by running commands in the {\sf Analysis Commands} @@ -2577,43 +2693,56 @@ url_view $URL \end{verbatim} % $ (this comment is here only to keep Emacs's LaTeX fontification happy) +\noindent +As this example illustrates, the menu variable {\tt \$URL} can be used +to pass the selected URL from \WAVE{} to your browser. (\WAVE{} +expands any incomplete URLs from annotation files as needed before +evaluating {\tt \$URL}.) The program {\tt url\_view} is a shell script (normally installed at the same time as \WAVE{}, and in the same directory) that handles starting the browser if necessary and instructing it to display the specified -URL. The standard version of {\tt url\_view} does so using the command: +URL. If {\tt URLV} is not set, or if you have set it to {\tt mozilla}, +{\tt url\_view} does so using the command: \begin{verbatim} - ( netscape -remote 'openURL($URL)' || netscape $URL ) & + ( mozilla -remote 'openURL($URL)' || mozilla $URL ) & \end{verbatim} - -As this example illustrates, the menu variable {\tt \$URL} can be used -to pass the selected URL from \WAVE{} to your browser. (\WAVE{} -expands any incomplete URLs from annotation files as needed before -evaluating {\tt \$URL}.) In this case, \WAVE{} first uses Netscape's -{\tt -remote} option to instruct an already-running copy of Netscape -to open the desired URL. This is a very fast operation if Netscape is -already running (since Netscape is already in RAM, it is not necessary -to load another in order to run the {\tt netscape -remote ...} +\noindent +In this case, \WAVE{} (via {\tt url\_view}) first uses Mozilla's +{\tt -remote} option to instruct an already-running copy of Mozilla +to open the desired URL. This is a very fast operation if Mozilla is +already running (since Mozilla is already in RAM, it is not necessary +to load another in order to run the {\tt mozilla -remote ...} process, and the remote process efficiently delivers its message and -exits immediately). If Netscape was not running, the {\tt -netscape -remote} command fails, and (in this case only) \WAVE{} -starts a new Netscape browser process. - -To configure \WAVE{} to use a different web browser, edit the {\tt -url\_view} script appropriately. (You may also do this by editing the -action associated with {\tt }, but it's better to modify -{\tt url\_view}, since \WAVE{} also uses {\tt url\_view} to display some -of its on-line help. If you decide to modify the action in the -\WAVE{} menu file, be careful not to change the {\tt } tag -at the beginning of the line, since \WAVE{} uses this tag to identify -the browser interface command within the menu file.) Consult the -documentation for your browser to see what commands will be needed. -(The {\tt -remote} option is unique to Netscape; other browsers will -probably require different methods.) Note that early versions of -Mosaic (prior to 2.5) used a different method for remote control than -current versions do. Browsers that do not support any means of remote -control are best avoided (since the only way to use them is to start a +exits immediately). If Mozilla was not running, the {\tt +mozilla -remote} command fails, and (in this case only) {\tt url\_view} +starts a new Mozilla browser process. +/index{Mozilla} + +The {\tt url\_view} script includes analogous commands for each of the other +supported browsers. If {\tt url\_view} does not recognize the browser named by +{\tt URLV}, it simply runs: +\begin{verbatim} + ( $URLV $URL ) & +\end{verbatim} +\noindent +but this is (in general) much slower, since launching a new instance of the +browser for each URL will take much more time than reusing an already-open +window, as for the supported browsers. + +To configure \WAVE{} to use a different web browser, edit the {\tt url\_view} +script appropriately. (You may also do this by editing the action associated +with {\tt }, but it's better to modify {\tt url\_view}, since \WAVE{} +also uses {\tt url\_view} to display some of its on-line help. If you decide +to modify the action in the \WAVE{} menu file, be careful not to change the +{\tt } tag at the beginning of the line, since \WAVE{} uses this tag +to identify the browser interface command within the menu file.) Consult the +documentation for your browser to see what commands will be needed. (The {\tt +-remote} option is used by Mozilla, Netscape, and Opera; other browsers will +probably require different methods.) Browsers that do not support any means of +remote control are best avoided (since the only way to use them is to start a new browser for each new URL, a very inefficient solution). +\index{Mozilla}\index{Netscape}\index{Opera}\index{web browser} \chapter{Printing from \WAVE{}} @@ -2716,9 +2845,9 @@ Since \WAVE{}'s printing facilities are implemented through its menu file, you have complete control over the format of the output, simply by editing the menu file as in the previous chapter. Both -\htmladdnormallink{{\tt pschart}}{../dbag/pschar-1.htm} +\htmladdnormallink{{\tt pschart}}{../wag/pschar-1.htm} (used to produce ``chart recorder'' output) and -\htmladdnormallink{{\tt psfd}}{../dbag/psfd-1.htm} +\htmladdnormallink{{\tt psfd}}{../wag/psfd-1.htm} (used to produce ``full disclosure'' output) are highly flexible and can be configured to produce almost any reasonable format by inserting the appropriate options in the commands given in \WAVE{}'s menu file. @@ -2733,10 +2862,10 @@ A few of the most commonly-used options (usable with either {\tt pschart} or {\tt psfd}) are listed below. For further details on these and other options, see -\htmladdnormallink{{\tt pschart(1)}}{../dbag/pschar-1.htm} and -\htmladdnormallink{{\tt psfd(1)}}{../dbag/psfd-1.htm}, +\htmladdnormallink{{\tt pschart(1)}}{../wag/pschar-1.htm} and +\htmladdnormallink{{\tt psfd(1)}}{../wag/psfd-1.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}. +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}. (You can also get a brief summary of the many available options by typing {\tt pschart~-h} and {\tt psfd~-h}.) @@ -2965,9 +3094,9 @@ measurements, but they can be used in a pinch.) For further information on signal calibration, see -\htmladdnormallink{{\tt calsig(1)}}{../dbag/calibr-1.htm}, +\htmladdnormallink{{\tt calsig(1)}}{../wag/calibr-1.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}. +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}. \section{Display calibration} @@ -3016,9 +3145,9 @@ restart \WAVE{}; instead, give the copy a different name, then change the {\sf Calibration file} item in the {\sf Load} window to match. Any changes are effective only when the signal window is redrawn.) See -\htmladdnormallink{{\tt wfdbcal(5)}}{../dbag/wfdbca-5.htm}, +\htmladdnormallink{{\tt wfdbcal(5)}}{../wag/wfdbca-5.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}, +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}, for details. If the display calibration appears incorrect for all signals, the X @@ -3221,25 +3350,37 @@ \index{WFDB environment variable}\index{environment variables!WFDB} \item[{\tt WFDB}] The database path (see -\htmladdnormallink{{\tt setwfdb(1)}}{../dbag/setwfd-1.htm}, +\htmladdnormallink{{\tt setwfdb(1)}}{../wag/setwfd-1.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}. -If not set, \WAVE{} can find database files only in the current -directory (on the \WAVE{} host). +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}. +If not set, \WAVE{} can find database files only in the locations +specified by the compiled-in default database path, which normally +includes the current directory and the {\tt /usr/database} directory +(on the \WAVE{} host), and PhysioBank's archives at +\begin{htmlonly} +\htmladdnormallink{\tt http://www.\-physio\-net.\-org/\-physio\-bank/\-data\-base}{http://www.physionet.org/physiobank/database/} +\end{htmlonly} +\begin{latexonly} +{\tt http://www.\-physio\-net.\-org/\-physio\-bank/\-data\-base} +\end{latexonly} +(if the Internet is accessible from the \WAVE{} host). + \index{WFDBCAL environment variable}\index{environment variables!WFDBCAL} \item[{\tt WFDBCAL}] The WFDB calibration file (see -\htmladdnormallink{{\tt setwfdb(1)}}{../dbag/setwfd-1.htm} and -\htmladdnormallink{{\tt wfdbcal(5)}}{../dbag/wfdbca-5.htm}, +\htmladdnormallink{{\tt setwfdb(1)}}{../wag/setwfd-1.htm} and +\htmladdnormallink{{\tt wfdbcal(5)}}{../wag/wfdbca-5.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}, +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}, and \hyperref{Calibration} {chapter~} {, page~\pageref{ch:calibration}} {ch:calibration}). -If not set, \WAVE{} may not scale signals other than ECGs correctly. +If not set, \WAVE{} reads a default calibration file specified when +the WFDB library was compiled. If the calibration file cannot be +read, \WAVE{} may not scale signals other than ECGs correctly. \index{WAVEMENU environment variable}\index{environment variables!WAVEMENU} \item[{\tt WAVEMENU}] @@ -3266,6 +3407,20 @@ The name of the text editor to be used for modifying \WAVE{}'s menu file. If not set, \WAVE{} uses {\tt textedit}. +\index{URLV environment variable}\index{environment variables!URLV} +\item[{\tt URLV}] +The name of the web browser to be used for viewing LINK annotation +attachments and some of \WAVE{}'s on-line help; normally, {\tt URLV} +should be one of {\tt galeon}, {\tt konqueror}, {\tt mozilla}, {\tt netscape}, +or {\tt opera}. If not set, \WAVE{} uses Mozilla. See +\hyperref{\WAVE{} and the Web} +{section~} +{, page~\pageref{sec:web},} +{sec:web} +for details. +\index{Galeon}\index{Konqueror}\index{Mozilla}\index{Netscape}\index{Opera} +\index{web browser} + \index{PRINTER environment variable}\index{environment variables!PRINTER} \index{PostScript} \item[{\tt PRINTER}] @@ -3345,7 +3500,7 @@ can be used with \WAVE{} (type `{\tt man xview}' for details). If your system doesn't have an XView {\tt man} page, refer to the copy provided with the \WAVE{} distribution -(\htmladdnormallink{{\tt xview.7}}{../dbag/xview-7.htm}). +(\htmladdnormallink{{\tt xview.7}}{../wag/xview-7.htm}). In addition, the \WAVE{}-specific resources listed below may also be set. The standard way to change default values of X11 resources is to @@ -3750,7 +3905,7 @@ and to record in that file the current record name, the time of the samples at the center of the signal window, and (optionally) a one-line comment. Log files may be used as scripts for -\htmladdnormallink{{\tt pschart}}{../dbag/pschar-1.htm}. +\htmladdnormallink{{\tt pschart}}{../wag/pschar-1.htm}. You may write to as many log files in a single session as you choose, and you may accumulate entries from multiple sessions in a single log file. @@ -4200,13 +4355,13 @@ \item[{\sf Signals...}] This selection pops up a window containing information about the signals of the current record, obtained by running -\htmladdnormallink{{\tt wfdbdesc}}{../dbag/wfdbde-1.htm}. +\htmladdnormallink{{\tt wfdbdesc}}{../wag/wfdbde-1.htm}. \index{sumann command@{\tt sumann} command} \item[{\sf Annotations...}] This selection pops up a window containing a summary of the contents of the annotation buffer, obtained by running -\htmladdnormallink{{\tt sumann}}{../dbag/sumann-1.htm} +\htmladdnormallink{{\tt sumann}}{../wag/sumann-1.htm} (after saving any edits). \index{WAVE version number@\WAVE{} version number} @@ -4318,13 +4473,13 @@ \item[\button{User's Guide}] Click on this button to begin reading this guide in a web browser -window. By default, \WAVE{} uses Netscape 1.1 or any later version -available on the \WAVE{} host. To configure \WAVE{} to use a +window. By default, \WAVE{} uses Mozilla. To configure \WAVE{} to use a different browser, see \hyperref{\WAVE{} and the web} {section~} {, page~\pageref{sec:web}} {sec:web}. +\index{Mozilla}\index{web browser} \item[\button{Quit from Help}] Press this button to dismiss the {\sf Help Topics} window. @@ -4548,27 +4703,37 @@ \index{resolution!of display} \index{X Window System!XFree86 server} \item [A computer capable of acting as a \WAVE{} host] -(one for which a binary version of \WAVE{} is available). Virtually any PC -with a 386 or better CPU can run Linux, and such systems are likely to be the -least expensive choice. Ideally, a Linux PC to be used as a \WAVE{} host -should have at least 8 Mb of RAM, at least 200 Mb of available disk space, a -three-button mouse (or trackball), and a graphics card and monitor (17-inch or -larger, with a dot pitch of .26 mm or less) capable of non-interlaced display -at 65 Hz or faster with a resolution of at least 1024x768 with 256 colors. In -most cases, you will also want the system to be equipped with a CD-ROM drive -(for loading software and digitized signals) and an Ethernet adapter or a -modem. Check the Linux Hardware-HOWTO to be sure that your chosen hardware is -supported. Most graphics cards, including the popular accelerated cards, are -fully supported by the standard XFree86 X server, but a few high-end models are -supported only in SVGA compatibility mode. Most PCs manufactured since 1995 -will easily meet these requirements; new PCs will exceed most of them by large -factors. In late 2001, it was possible to assemble a suitable Linux PC for -about US\$500 (not including the monitor). It is not unreasonable to budget an -equal amount for a good monitor, since \WAVE{}'s usability depends to a -significant extent on being able to see its output clearly. If your budget -permits, a flat-panel (LCD) monitor is an excellent choice, particularly if you -plan to do much annotation editing, because these monitors typically present -very stable images that do not tire the eye. +(one for which a binary version of \WAVE{} is available). Virtually +any PC with a 386 or better CPU can run Linux, and such systems are +likely to be the least expensive choice. Ideally, a Linux PC to be +used as a \WAVE{} host should have at least 8 Mb of RAM, at least 200 +Mb of available disk space, a three-button mouse (or trackball), and a +graphics card and monitor (17-inch or larger, with a dot pitch of .26 +mm or less) capable of non-interlaced display at 65 Hz or faster with +a resolution of at least 1024x768 with 256 colors. In most cases, you +will also want the system to be equipped with a CD-ROM drive (for +loading software and digitized signals) and an Ethernet adapter or a +modem. Check the Linux Hardware-HOWTO to be sure that your chosen +hardware is supported. Most graphics cards, including the popular +accelerated cards, are fully supported by the standard XFree86 X +server, but a few high-end models are supported only in SVGA +compatibility mode. Most PCs manufactured since 1995 will easily meet +these requirements; new PCs will exceed most of them by large factors. +In mid-2002, it was possible to assemble a suitable Linux PC for about +US\$300 (not including the monitor). It is not unreasonable to budget +an equal or greater amount for a good monitor, since \WAVE{}'s +usability depends to a significant extent on being able to see its +output clearly. If your budget permits, a flat-panel (LCD) monitor is +an excellent choice, particularly if you plan to do much annotation +editing, because these monitors typically present very stable images +that do not tire the eye. + +Inexpensive three-button mice, trackballs, and touchpads manufactured +by Logitech and many others are widely available for PCs, and are +highly recommended if you do much annotation editing. Most are fully +compatible with Microsoft two-button mice. Some users prefer +trackballs for precision editing since there is no tendency for the +pointer to move when clicking the buttons, as with a mouse. For those on a tight budget, suitable used PCs are often available for next to nothing. If you use an older PC and can afford to upgrade components, get a @@ -4823,16 +4988,17 @@ user-written applications that read and write signal and annotation files in the formats supported by \WAVE{}. -\index{Netscape}\index{web browser} A web browser, though not a necessity for everyone who uses \WAVE{}, should be part of your software toolbox. If you use link annotations, you will need a browser in order to follow the links to the external data. Even if you don't anticipate using link annotations, you can still use a web browser to view the on-line version of this guide. Netscape is an attractive choice because of its simple remote-control -interface, among other reasons. As noted earlier, Netscape may be -obtained freely by anonymous FTP from -\htmladdnormallink{{\tt ftp.netscape.com}}{ftp://ftp.netscape.com/}). +interface, among other reasons. Mozilla may be obtained freely from +\htmladdnormallink{{\tt http://\-www\-.mozilla\-.org}} +{http://www.mozilla.org/}). +\index{Galeon}\index{Konqueror}\index{Mozilla}\index{Netscape}\index{Opera} +\index{web browser} \index{gnuplot command@{\tt gnuplot} command} \index{plot2d command@{\tt plot2d} command} @@ -4846,16 +5012,16 @@ plots for publication, avoid packages that only provide screen dumps; any decent plotting program should be able to generate plots at the resolution of your printer. -\htmladdnormallink{{\tt plot2d}}{../dbag/plot2d-1.htm} +\htmladdnormallink{{\tt plt}}{../wag/plt-1.htm} is a highly capable +plotting package freely available from +\htmladdnormallink{{\tt www.physionet.org};}{http://www.physionet.org/}. +\htmladdnormallink{{\tt plot2d}}{../wag/plot2d-1.htm} (included in the WFDB Software Package) is a bare-bones command-line front end to {\tt gnuplot}, a fairly capable interactive plotting program that is included in most Linux distributions, and is also available from \htmladdnormallink{{\tt www.gnuplot.vt.edu}}{http://www.gnuplot.vt.edu/} and numerous other sites. -\htmladdnormallink{{\tt plt}}{../dbag/plt-1.htm} is a highly capable -plotting package freely available from -\htmladdnormallink{{\tt www.physionet.org};}{http://www.physionet.org/} {\tt plot2d} uses {\tt plt} rather than {\tt gnuplot} if {\tt plt} is installed. @@ -5182,10 +5348,9 @@ Inexpensive three-button mice, trackballs, and touchpads manufactured by Logitech and many others are widely available for PCs, and are highly recommended if you do much annotation editing. Most are fully -compatible with Microsoft two-button mice and with X server software -for PCs. Some users prefer trackballs for precision editing since -there is no tendency for the pointer to move when clicking the -buttons, as with a mouse. +compatible with Microsoft two-button mice. Some users prefer +trackballs for precision editing since there is no tendency for the +pointer to move when clicking the buttons, as with a mouse. \subsection{How do I get spot help if I don't have a {\sf Help} key?} @@ -5417,7 +5582,7 @@ WFDB calibration file, for example, if the {\tt WFDBCAL} environment \index{WFDBCAL environment variable}\index{environment variables!WFDBCAL} variable does not name an accessible WFDB calibration file (see -\htmladdnormallink{{\tt wfdbcal(5)}}{../dbag/wfdbca-5.htm} +\htmladdnormallink{{\tt wfdbcal(5)}}{../wag/wfdbca-5.htm} for details), if any of the signals in the record are of types not listed in the WFDB calibration file, or if the WFDB calibration file does not contain appropriate default display scales for all of @@ -5478,8 +5643,8 @@ waveforms in the scope window when reading records via HTTP. For now, the only workarounds are to restart \WAVE{}, or to copy the record to local disk files (this can be done easily using -\htmladdnormallink{{\tt xform}}{../dbag/xform-1.htm}, -\htmladdnormallink{{\tt snip}}{../dbag/snip-1.htm}, or a web browser). Check +\htmladdnormallink{{\tt xform}}{../wag/xform-1.htm}, +\htmladdnormallink{{\tt snip}}{../wag/snip-1.htm}, or a web browser). Check \htmladdnormallink{PhysioNet}{http://www.physionet.org/} for updates to \WAVE{} or to the WFDB library that may correct this bug. @@ -5546,7 +5711,7 @@ {sec:wfdb-path}). Instructions for adding additional signal names and scales to the calibration file are located within the file itself, and may also be found in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}. +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}. \item \index{header file} @@ -5557,7 +5722,7 @@ correspond to at least two levels represented in the signal (for example, the top and bottom of a calibration pulse), you can use the `{\tt calsig}' application to determine the gain and to rewrite the header file. See the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm} +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm} for details. `{\tt calsig}' can be most conveniently run from \WAVE{}'s {\sf Analysis} window. @@ -5627,10 +5792,10 @@ names only. For example, three files belong to record 100s: {\tt 100s.hea}, {\tt 100s.dat}, and {\tt 100s.atr}. There is no \emph{file} named `{\tt 100s}' belonging to \emph{record} 100s. See -\htmladdnormallink{{\tt annot(5)}}{../dbag/annot-5.htm}, -\htmladdnormallink{{\tt header(5)}}{../dbag/header-5.htm}, and -\htmladdnormallink{{\tt signal(5)}}{../dbag/signal-5.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}, +\htmladdnormallink{{\tt annot(5)}}{../wag/annot-5.htm}, +\htmladdnormallink{{\tt header(5)}}{../wag/header-5.htm}, and +\htmladdnormallink{{\tt signal(5)}}{../wag/signal-5.htm}, in the +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}, for information about file types and formats. \subsection{Why does \WAVE{} tell me `Record ... is unavailable'?} @@ -5638,8 +5803,9 @@ \index{WFDB environment variable}\index{environment variables!WFDB} In common with other WFDB applications, \WAVE{} searches for its input signals and annotations in directories named by the {\tt WFDB} -environment variable (see the discussion of the WFDB path in the -\htmladdnormallink{{\it WFDB Programmer's Guide}}{../dbpg/dbpg.htm}). +environment variable (see the discussion of the +\htmladdnormallink{WFDB path}{../wpg/database-path.htm} in the +\htmladdnormallink{{\it WFDB Programmer's Guide}}{../wpg/wpg.htm}). If \WAVE{} is running remotely, remember to set {\tt WFDB} \emph{on the \WAVE{} host} \index{WAVE host@\WAVE{} host} @@ -5657,7 +5823,7 @@ \index{wfdbwhich command@{\tt wfdbwhich} command} To get the pathname of a WFDB file, use `{\tt wfdbwhich}' (see -\htmladdnormallink{{\tt wfdbwhich(1)}}{../dbag/wfdbwh-1.htm} +\htmladdnormallink{{\tt wfdbwhich(1)}}{../wag/wfdbwh-1.htm} for details). For example, the output of `{\tt wfdbwhich header 100s}' is the pathname of the header file for record 100s (usually `{\tt /usr/database/100s.hea}'). If `{\tt wfdbwhich}' @@ -5806,8 +5972,8 @@ to text form to edit them, and then convert the edited text back to binary form in order to use them further with \WAVE{}. You can do this using {\tt rdann} and {\tt wrann} (see -\htmladdnormallink{{\tt rdann(1)}}{../dbag/rdann-1.htm} and -\htmladdnormallink{{\tt wrann(1)}}{../dbag/wrann-1.htm}, +\htmladdnormallink{{\tt rdann(1)}}{../wag/rdann-1.htm} and +\htmladdnormallink{{\tt wrann(1)}}{../wag/wrann-1.htm}, in the {\it WFDB Applications Guide}, for details). \subsection{What are `link' annotations?} @@ -5831,13 +5997,13 @@ moments while \WAVE{} starts it. If nothing happens after a minute or so, check \WAVE{}'s {\sf Analysis Commands} window for errors that may have occurred when \WAVE{} attempted to start your web browser. -(\WAVE{} uses Netscape 1.1 or any later version by default. See +(\WAVE{} uses Mozilla by default. See \hyperref{\WAVE{} and the Web} {section~} {, page~\pageref{sec:web},} {sec:web} -for details on obtaining Netscape, or on configuring \WAVE{} to use a -different web browser.) +for details on configuring \WAVE{} to use a different web browser.) +\index{Mozilla}\index{web browser} Link annotations may be moved, copied, attached to specific signals, inserted, changed, and deleted just as for any other annotation. @@ -5863,8 +6029,8 @@ wish to copy a set of annotations as well as data from signal files, be sure to load the annotation file for the original record into \WAVE{} before extracting the segment. (See -\htmladdnormallink{{\tt snip(1)}}{../dbag/snip-1.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}, +\htmladdnormallink{{\tt snip(1)}}{../wag/snip-1.htm}, in the +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}, if you need to copy two or more sets of annotations.) \index{wfdbcollate command@{\tt wfdbcollate} command} @@ -5876,10 +6042,10 @@ new annotation files on request, since the WFDB library does not support multi-segment annotation sets. The records to be joined must be ordinary (not multi-segment) records. If necessary, -\htmladdnormallink{{\tt xform}}{../dbag/xform-1.htm} +\htmladdnormallink{{\tt xform}}{../wag/xform-1.htm} can be used to rewrite a multi-segment record as an ordinary record. See -\htmladdnormallink{{\tt wfdbcollate(1)}}{../dbag/wfdbco-1.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}, +\htmladdnormallink{{\tt wfdbcollate(1)}}{../wag/wfdbco-1.htm}, in the +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}, for further information. \index{rdsamp command@{\tt rdsamp} command} @@ -5887,13 +6053,13 @@ More complex editing of signal files, such as splicing segments or modifying individual samples, can be done by converting the signals to text form using -\htmladdnormallink{{\tt rdsamp}}{../dbag/rdsamp-1.htm} +\htmladdnormallink{{\tt rdsamp}}{../wag/rdsamp-1.htm} (accessible from \WAVE{} via the \button{List samples} button in the {\sf Analyze} window), editing the text as required, and converting the edited text to a signal file using {\tt wrsamp} (see -\htmladdnormallink{{\tt wrsamp(1)}}{../dbag/wrsamp-1.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}, +\htmladdnormallink{{\tt wrsamp(1)}}{../wag/wrsamp-1.htm}, in the +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}, for details). \section{What else can \WAVE{} do?} @@ -5917,8 +6083,8 @@ {\sf Print} from \WAVE{}'s \menubutton{File} menu to print the current contents of the signal window; use \button{Print chart} in the {\sf Analyze} window if you wish to specify start and stop times. See -\htmladdnormallink{{\tt pschart(1)}}{../dbag/pschar-1.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm} +\htmladdnormallink{{\tt pschart(1)}}{../wag/pschar-1.htm}, in the +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm} for information about {\tt pschart}'s numerous formatting options. If you don't like the defaults, change them by editing \WAVE{}'s menu file. Doing so also allows you to change the @@ -5927,7 +6093,7 @@ \index{psfd command@{\tt psfd} command} If you are plotting a great deal of data, you may wish to use -\htmladdnormallink{{\tt psfd}}{../dbag/psfd-1.htm} +\htmladdnormallink{{\tt psfd}}{../wag/psfd-1.htm} rather than {\tt pschart}; to do so, select \button{Print full disclosure} rather than \button{Print chart} in \WAVE{}'s {\sf Analyze} window. Most of {\tt pschart}'s options are accepted by {\tt psfd}. @@ -5954,9 +6120,9 @@ applications can also read your signals. Writing a header file can be most easily done by copying an existing header file and modifying it using a text editor. See -\htmladdnormallink{{\tt signal(5)}}{../dbag/signal-5.htm} and -\htmladdnormallink{{\tt header(5)}}{../dbag/header-5.htm} in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}, +\htmladdnormallink{{\tt signal(5)}}{../wag/signal-5.htm} and +\htmladdnormallink{{\tt header(5)}}{../wag/header-5.htm} in the +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}, for details on supported signal formats and how to write a header file. \index{multiplexed signal file} @@ -5986,9 +6152,9 @@ \item Write a header file describing the layout of the block-interleaved signal file (see -\htmladdnormallink{{\tt header(5)}}{../dbag/header-5.htm}, +\htmladdnormallink{{\tt header(5)}}{../wag/header-5.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}, +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}, for details). The sampling frequency in the first line of the header should be given as the frame rate (i.e., the basic sampling rate divided by the number of samples per block), and @@ -6015,9 +6181,9 @@ the signal file is properly readable, then using {\tt xform} with its \index{xform command@{\tt xform} command} own {\tt -H} option; see -\htmladdnormallink{{\tt xform(1)}}{../dbag/xform-1.htm} +\htmladdnormallink{{\tt xform(1)}}{../wag/xform-1.htm} in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}. +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}. \index{embedded header data in signal files} \index{preamble in signal files} @@ -6031,15 +6197,15 @@ If the signal file format is documented, it is usually not difficult to write a program to generate a header file based on embedded header data. See -\htmladdnormallink{{\tt header(5)}}{../dbag/header-5.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}, +\htmladdnormallink{{\tt header(5)}}{../wag/header-5.htm}, in the +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}, for details on byte offsets. \WAVE{} does not support directly reading signals stored in text files, because there is no general method for computing the position within such files of samples occuring at arbitrarily-chosen times. It is usually simple to convert such text files into \WAVE{}-compatible binary files using -\htmladdnormallink{{\tt wrsamp}}{../dbag/wrsamp-1.htm}, +\htmladdnormallink{{\tt wrsamp}}{../wag/wrsamp-1.htm}, \index{wrsamp command@{\tt wrsamp} command} an application supplied with \WAVE{}. @@ -6070,7 +6236,7 @@ It may not be much more difficult than writing a conversion utility, provided that your format permits computing file position as a function of time. See the appendix titled `{\sf Extensions}' in the -\htmladdnormallink{{\it WFDB Programmer's Guide}}{../dbpg/dbpg.html} +\htmladdnormallink{{\it WFDB Programmer's Guide}}{../wpg/wpg.htm} for hints on how to proceed. \end{itemize} @@ -6104,7 +6270,7 @@ \index{resolution!of multi-frequency records} Briefly, it is an alternative display mode for multi-frequency records only. See the -\htmladdnormallink{{\it WFDB Programmer's Guide}}{../dbpg/dbpg.htm} +\htmladdnormallink{{\it WFDB Programmer's Guide}}{../wpg/wpg.htm} for details on multi-frequency records. \index{H option for WAVE@{\tt -H} option for \WAVE{}} @@ -6211,8 +6377,8 @@ same data in order to study their differences, use {\tt bxb} with the `{\tt -o}' option to prepare a comparison annotation file, and then use \WAVE{} to open that file. (See -\htmladdnormallink{{\tt bxb(1)}}{../dbag/bxb-1.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}, +\htmladdnormallink{{\tt bxb(1)}}{../wag/bxb-1.htm}, in the +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}, for details.) If your goal is to find discrepancies, this is by far the best way to do so; `{\tt bxb}' produces a statistical summary of them, and you can search for {\sf @@ -6235,12 +6401,12 @@ for disjoint segments of the record), you can use {\tt mrgann} to merge them into a single file, preserving information about which file each annotation came from if you wish (see -\htmladdnormallink{{\tt mrgann}}{../dbag/mrgann-1.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}, +\htmladdnormallink{{\tt mrgann}}{../wag/mrgann-1.htm}, in the +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}, for details). \index{wfdbcollate command@{\tt wfdbcollate} command} -\htmladdnormallink{{\tt wfdbcollate}}{../dbag/wfdbco-1.htm} +\htmladdnormallink{{\tt wfdbcollate}}{../wag/wfdbco-1.htm} can also be used for this purpose if you have separate annotation files for each segment of a multi-segment record. @@ -6338,18 +6504,19 @@ Guide} (this book) and working through the tutorial examples it contains. If you need to use existing WFDB applications under \WAVE{}'s control, refer to the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}. +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}. If you need to develop your own applications for use with \WAVE{}, read the -\htmladdnormallink{{\it WFDB Programmer's Guide}}{../dbpg/dbpg.htm}. +\htmladdnormallink{{\it WFDB Programmer's Guide}}{../wpg/wpg.htm}. You may read these guides on-line on-line or print your own copies (visit \htmladdnormallink{PhysioNet}{http://www.physionet.org/}). -\index{on-line help}\index{help}\index{Netscape} +\index{on-line help}\index{help}\index{Mozilla}\index{web browser} \item The on-line version of the \WAVE{} ~{\it User's Guide} can be opened for browsing by clicking left on \button{User's Guide} in \WAVE{}'s {\sf Help Topics} window (this -requires \WAVE{} 6.0 or later, and Netscape 1.1 or later on the +requires \WAVE{} 6.0 or later, and Mozilla (or another browser, if named by +the {\tt URLV} environment variable) on the \WAVE{} host). This guide may also be read with any Web browser independently of \WAVE{} (point your browser to @@ -6393,14 +6560,14 @@ \item The {\tt man} page for \WAVE{} -(\htmladdnormallink{{\tt wave(1)}}{../dbag/wave-1.htm}) +(\htmladdnormallink{{\tt wave(1)}}{../wag/wave-1.htm}) contains a concise description of its command-line options, the environment variables and X resources it uses, and the \WAVE{} menu file. (This information is also included in this Guide; the {\tt man} page is intended as a compact reference. The {\tt man} page for \WAVE{} can be found in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}, +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}, or on-line by typing `{\tt man wave}', or by using {\tt xman} or {\tt tkman}, etc.) @@ -6412,12 +6579,12 @@ \item For information about the data formats supported by \WAVE{} and the other WFDB applications, see -\htmladdnormallink{{\tt annot(5)}}{../dbag/annot-5.htm}, -\htmladdnormallink{{\tt header(5)}}{../dbag/header-5.htm}, -\htmladdnormallink{{\tt signal(5)}}{../dbag/signal-5.htm}, and -\htmladdnormallink{{\tt wfdbcal(5)}}{../dbag/wfdbca-5.htm}, +\htmladdnormallink{{\tt annot(5)}}{../wag/annot-5.htm}, +\htmladdnormallink{{\tt header(5)}}{../wag/header-5.htm}, +\htmladdnormallink{{\tt signal(5)}}{../wag/signal-5.htm}, and +\htmladdnormallink{{\tt wfdbcal(5)}}{../wag/wfdbca-5.htm}, in the -\htmladdnormallink{{\it WFDB Applications Guide}}{../dbag/dbag.htm}. +\htmladdnormallink{{\it WFDB Applications Guide}}{../wag/wag.htm}. \end{itemize} \chapter{Command-line Options} @@ -6634,7 +6801,7 @@ display. (For this to work, your colleagues must first allow your computer to open windows on their displays, typically using {\tt xhost}. See -\htmladdnormallink{{\tt xview(7)}}{../dbag/xview-7.htm} +\htmladdnormallink{{\tt xview(7)}}{../wag/xview-7.htm} for information about the {\tt -display} option. Notice that the `{\tt +}{\it n}{\tt /}' prefix must be attached to both the {\tt -display} option and to its argument in order to diff -Naur wfdb-10.2.5/examples/Makefile wfdb-10.2.6/examples/Makefile --- wfdb-10.2.5/examples/Makefile Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/examples/Makefile Mon Jun 24 22:43:07 2002 @@ -34,12 +34,12 @@ # `make clean' to remove them. # _____________________________________________________________________________ # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables @@ -47,7 +47,7 @@ VDEFS = -DWFDB_MAJOR=$(MAJOR) -DWFDB_MINOR=$(MINOR) -DWFDB_RELEASE=$(RELEASE) # _____________________________________________________________________________ -PACKAGE=wfdb-10.2.5 +PACKAGE=wfdb-10.2.6 # file: linux.def G. Moody 31 May 2000 # Last revised: 17 December 2001 # 'make' definitions for compiling the WFDB Software Package under Linux @@ -170,14 +170,14 @@ echo "Nothing to be done for lib-post-uninstall" # _____________________________________________________________________________ # file: Makefile.tpl G. Moody 23 May 2000 -# Last revised: 5 June 2000 +# Last revised: 30 May 2002 # This section of the Makefile should not need to be changed. -CFILES = psamples.c exgetvec.c exputvec.c exannstr.c example1.c example2.c \ - example3.c example4.c example5.c example6.c example7.c example8.c example9.c \ - example10.c refhr.c -XFILES = psamples exgetvec exputvec exannstr example1 example2 example3 \ - example4 example5 example6 example7 example8 example9 example10 refhr +CFILES = psamples.c psamplex.c exgetvec.c exputvec.c exannstr.c example1.c \ + example2.c example3.c example4.c example5.c example6.c example7.c example8.c \ + example9.c example10.c refhr.c +XFILES = psamples psamplex exgetvec exputvec exannstr example1 example2 \ + example3 example4 example5 example6 example7 example8 example9 example10 refhr MFILES = Makefile makefile.dos # General rule for compiling C sources into executable files. This is @@ -202,7 +202,3 @@ # `make clean': remove executable, intermediate and backup files clean: rm -f $(XFILES) *.o *~ core - -# Odds and ends. -example10.c: - mv exampl10.c example10.c diff -Naur wfdb-10.2.5/examples/Makefile.tpl wfdb-10.2.6/examples/Makefile.tpl --- wfdb-10.2.5/examples/Makefile.tpl Mon Jun 5 06:21:41 2000 +++ wfdb-10.2.6/examples/Makefile.tpl Thu May 30 11:39:49 2002 @@ -1,12 +1,12 @@ # file: Makefile.tpl G. Moody 23 May 2000 -# Last revised: 5 June 2000 +# Last revised: 30 May 2002 # This section of the Makefile should not need to be changed. -CFILES = psamples.c exgetvec.c exputvec.c exannstr.c example1.c example2.c \ - example3.c example4.c example5.c example6.c example7.c example8.c example9.c \ - example10.c refhr.c -XFILES = psamples exgetvec exputvec exannstr example1 example2 example3 \ - example4 example5 example6 example7 example8 example9 example10 refhr +CFILES = psamples.c psamplex.c exgetvec.c exputvec.c exannstr.c example1.c \ + example2.c example3.c example4.c example5.c example6.c example7.c example8.c \ + example9.c example10.c refhr.c +XFILES = psamples psamplex exgetvec exputvec exannstr example1 example2 \ + example3 example4 example5 example6 example7 example8 example9 example10 refhr MFILES = Makefile makefile.dos # General rule for compiling C sources into executable files. This is @@ -31,7 +31,3 @@ # `make clean': remove executable, intermediate and backup files clean: rm -f $(XFILES) *.o *~ core - -# Odds and ends. -example10.c: - mv exampl10.c example10.c diff -Naur wfdb-10.2.5/examples/example10.c wfdb-10.2.6/examples/example10.c --- wfdb-10.2.5/examples/example10.c Mon Oct 15 12:17:27 2001 +++ wfdb-10.2.6/examples/example10.c Tue May 28 20:57:19 2002 @@ -30,9 +30,9 @@ exit(2); } if (wfdbinit(argv[1], &a, 1, s, nsig) != nsig) exit(2); - if (sampfreq(NULL) != 250.) - fprintf(stderr, "warning: %s is designed for 250 Hz input\n", - argv[0]); + if (sampfreq((char *)NULL) < 240. || + sampfreq((char *)NULL) > 260.) + setifreq(250.); if (argc > 2) scmin = muvadu(0, atoi(argv[2])); if (scmin < 1) scmin = muvadu(0, 1000); slopecrit = scmax = 10 * scmin; diff -Naur wfdb-10.2.5/examples/psamplex.c wfdb-10.2.6/examples/psamplex.c --- wfdb-10.2.5/examples/psamplex.c Wed Dec 31 19:00:00 1969 +++ wfdb-10.2.6/examples/psamplex.c Thu May 30 11:57:14 2002 @@ -0,0 +1,26 @@ +#include + +main(int argc, char **argv) +{ + int i; + WFDB_Sample v[2]; + WFDB_Siginfo s[2]; + WFDB_Frequency f; + WFDB_Time t, t0, t1; + + if (argc > 1) sscanf(argv[1], "%lf", &f); + if (f <= (WFDB_Frequency)0) f = sampfreq("100s"); + + if (isigopen("100s", s, 2) < 1) + exit(1); + setifreq(f); + t0 = strtim("1"); + isigsettime(t); + t1 = strtim("2"); + for (t = t0; t <= t1; t++) { + if (getvec(v) < 0) + break; + printf("%d\t%d\n", v[0], v[1]); + } + exit(0); +} diff -Naur wfdb-10.2.5/fortran/wfdbf.c wfdb-10.2.6/fortran/wfdbf.c --- wfdb-10.2.5/fortran/wfdbf.c Wed Feb 6 14:06:52 2002 +++ wfdb-10.2.6/fortran/wfdbf.c Thu May 23 11:23:49 2002 @@ -1,5 +1,5 @@ /* file: wfdbf.c G. Moody 23 August 1995 - Last revised: 6 February 2002 + Last revised: 23 May 2002 _______________________________________________________________________________ wfdbf: Fortran wrappers for the WFDB library functions @@ -213,7 +213,7 @@ return (osigopen(record, sinfo, (unsigned int)(*nsig))); } -/* Before using osigfopen_, use setsiginfo to set the contents of the signal +/* Before using osigfopen_, use setsiginfo_ to set the contents of the signal information structures. */ long osigfopen_(nsig) long *nsig; @@ -221,8 +221,8 @@ return (osigfopen(sinfo, (unsigned int)(*nsig))); } -/* Before using wfdbinit_, use setanninfo and setsiginfo to set the contents of - the annotation and signal information structures. */ +/* Before using wfdbinit_, use setanninfo_ and setsiginfo_ to set the contents + of the annotation and signal information structures. */ long wfdbinit_(record, nann, nsig) char *record; long *nann, *nsig; @@ -239,9 +239,22 @@ return (0L); } -long getspf_(void) +long getspf_(dummy) +long *dummy; { return (getspf()); +} + +long setifreq_(freq) +double *freq; +{ + return (setifreq(*freq)); +} + +double getifreq_(dummy) +long *dummy; +{ + return (getifreq()); } long getvec_(long_vector) diff -Naur wfdb-10.2.5/lib/Makefile wfdb-10.2.6/lib/Makefile --- wfdb-10.2.5/lib/Makefile Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/lib/Makefile Mon Jun 24 22:43:07 2002 @@ -33,12 +33,12 @@ # type `make slib'. # _____________________________________________________________________________ # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables diff -Naur wfdb-10.2.5/lib/annot.c wfdb-10.2.6/lib/annot.c --- wfdb-10.2.5/lib/annot.c Wed Nov 7 13:19:17 2001 +++ wfdb-10.2.6/lib/annot.c Tue May 28 11:17:19 2002 @@ -1,10 +1,10 @@ /* file: annot.c G. Moody 13 April 1989 - Last revised: 7 November 2001 wfdblib 10.2.1 + Last revised: 28 May 2002 wfdblib 10.2.6 WFDB library functions for annotations _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 2001 George B. Moody +Copyright (C) 2002 George B. Moody This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free @@ -127,13 +127,13 @@ WFDB_Anninfo info; /* output annotator information */ WFDB_Annotation ann; /* most recent annotation written by putann */ int seqno; /* annotation serial number (AHA format only)*/ - char rname[WFDB_MAXRNL+1]; /* record with which annotator is associated */ + char *rname; /* record with which annotator is associated */ char out_of_order; /* if >0, one or more annotations written by putann are not in the canonical (time, chan) order */ } **oad; -static int tmul; /* `time' fields in annotations are +static double tmul; /* `time' fields in annotations are tmul * times in annotation files */ /* Local functions (for the use of other functions in this module only). */ @@ -267,7 +267,7 @@ record++; /* discard the '+' prefix */ else { wfdb_anclose(); /* close previously opened annotation files */ - tmul = getspf(); + tmul = 0.0; } /* Prescan aiarray to see how large maxiann and maxoann must be. */ @@ -370,7 +370,13 @@ return (-4); } (void)strcpy(oa->info.name, aiarray[i].name); - (void)strncpy(oa->rname, record, WFDB_MAXRNL); + if ((oa->rname = + (char *)malloc((unsigned)(strlen(record)+1))) + == NULL) { + wfdb_error("annopen: insufficient memory\n"); + return (-4); + } + (void)strcpy(oa->rname, record); oa->ann.time = 0L; oa->info.stat = aiarray[i].stat; oa->out_of_order = 0; @@ -416,7 +422,14 @@ return (0); } ia->tt += ia->word & DATA; /* annotation time */ - ia->ann.time = ia->tt * tmul; + if (ia->tt > 0L && tmul <= 0.0) { + WFDB_Frequency f = sampfreq(NULL); + + tmul = getspf(); + if (f != (WFDB_Frequency)0) + tmul = tmul * getifreq() / f; + } + ia->ann.time = (WFDB_Time)(ia->tt * tmul + 0.5); ia->ann.anntyp = (ia->word & CODE) >> CS; /* set annotation type */ ia->ann.subtyp = 0; /* reset subtype field */ ia->ann.aux = NULL; /* reset aux field */ @@ -451,7 +464,15 @@ } a = ia->word >> 8; /* AHA annotation code */ ia->ann.anntyp = ammap(a); /* convert to MIT annotation code */ - ia->ann.time = wfdb_g32(ia->file) * tmul; /* time of annotation */ + if (tmul <= 0.0) { + WFDB_Frequency f = sampfreq(NULL); + + tmul = getspf(); + if (f != (WFDB_Frequency)0) + tmul = tmul * getifreq() / f; + } + ia->ann.time = (WFDB_Time)(wfdb_g32(ia->file) * tmul + 0.5); + /* time of annotation */ if (wfdb_g16(ia->file) <= 0) /* serial number (starts at 1) */ wfdb_error("getann: unexpected annot number in annotator %s\n", ia->info.name); @@ -508,17 +529,29 @@ unsigned annwd; char *ap; int i, len; - long delta, t; + long delta; + WFDB_Time t; struct oadata *oa; if (n >= noaf || (oa = oad[n]) == NULL || oa->file == NULL) { wfdb_error("putann: can't write annotation file %d\n", n); return (-2); } - t = annot->time / tmul; + if (annot->time == 0L) + t = 0L; + else { + if (tmul <= 0.0) { + WFDB_Frequency f = sampfreq(NULL); + + tmul = getspf(); + if (f != (WFDB_Frequency)0) + tmul = tmul * getifreq() / f; + } + t = (WFDB_Time)(annot->time / tmul + 0.5); + } if (((delta = t - oa->ann.time) < 0L || (delta == 0L && annot->chan <= oa->ann.chan)) && - (annot->time != 0L || oa->ann.time != 0L)) { + (t != 0L || oa->ann.time != 0L)) { oa->out_of_order = 1; } switch (oa->info.stat) { @@ -559,7 +592,7 @@ case WFDB_AHA_WRITE: /* AHA-format output file */ (void)wfdb_putc('\0', oa->file); (void)wfdb_putc(mamap(annot->anntyp, annot->subtyp), oa->file); - wfdb_p32(annot->time, oa->file); + wfdb_p32(t, oa->file); wfdb_p16((unsigned int)(++(oa->seqno)), oa->file); (void)wfdb_putc(annot->subtyp, oa->file); (void)wfdb_putc(annot->anntyp, oa->file); @@ -870,6 +903,7 @@ wfdb_error("to rearrange annotations in the correct order.\n"); } (void)free(oa->info.name); + (void)free(oa->rname); (void)free(oa); while (n < noaf-1) { oad[n] = oad[n+1]; diff -Naur wfdb-10.2.5/lib/calib.c wfdb-10.2.6/lib/calib.c --- wfdb-10.2.5/lib/calib.c Wed Nov 7 13:20:27 2001 +++ wfdb-10.2.6/lib/calib.c Sun Jun 2 08:51:36 2002 @@ -1,10 +1,10 @@ /* file: calib.c G. Moody 4 July 1991 - Last revised: 7 November 2001 wfdblib 10.2.1 + Last revised: 2 June 2002 wfdblib 10.2.6 WFDB library functions for signal calibration _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 2001 George B. Moody +Copyright (C) 2002 George B. Moody This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free @@ -71,7 +71,7 @@ char *cfname; { WFDB_FILE *cfile; - char buf[128], *p1, *p2, *p3, *p4, *p5, *p6, *getenv(); + char buf[128], *p1, *p2, *p3, *p4, *p5, *p6; /* If no calibration file is specified, return immediately. */ if (cfname == NULL && (cfname = getenv("WFDBCAL")) == NULL && diff -Naur wfdb-10.2.5/lib/signal.c wfdb-10.2.6/lib/signal.c --- wfdb-10.2.5/lib/signal.c Wed Nov 7 13:46:44 2001 +++ wfdb-10.2.6/lib/signal.c Mon Jun 17 18:43:03 2002 @@ -1,10 +1,10 @@ /* file: signal.c G. Moody 13 April 1989 - Last revised: 7 November 2001 wfdblib 10.2.1 + Last revised: 17 June 2002 wfdblib 10.2.6 WFDB library functions for signals _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 2001 George B. Moody +Copyright (C) 2002 George B. Moody This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free @@ -39,6 +39,7 @@ osigclose (closes output signals) isgsetframe (skips to a specified frame number in a specified signal group) getskewedframe (reads an input frame, without skew correction) + rgetvec (reads a sample from each input signal without resampling) This file also contains low-level I/O routines for signals in various formats; typically, the input routine for format N signals is named rN(), and the output @@ -51,7 +52,9 @@ osigfopen (opens output signals by name) getspf [9.6] (returns number of samples returned by getvec per frame) setgvmode [9.0](sets getvec operating mode) - getvec (reads a sample from each input signal) + setifreq [10.2.6](sets the getvec sampling frequency) + getifreq [10.2.6](returns the getvec sampling frequency) + getvec (reads a (possibly resampled) sample from each input signal) getframe [9.0] (reads an input frame) putvec (writes a sample to each output signal) isigsettime (skips to a specified time in each signal) @@ -68,8 +71,8 @@ wfdbsetstart [9.4](sets byte offset to be written by setheader) getinfo [4.0] (reads a line of info for a record) putinfo [4.0] (writes a line of info for a record) - sampfreq (gets the sampling frequency of a record) - setsampfreq (sets the sampling frequency) + sampfreq (returns the sampling frequency of the specified record) + setsampfreq (sets the putvec sampling frequency) setbasetime (sets the base time and date) timstr (converts sample intervals to time strings) mstimstr (converts sample intervals to time strings with milliseconds) @@ -191,9 +194,10 @@ for use by the strtim, timstr, etc., conversion functions. */ static WFDB_Frequency ffreq; /* frame rate (frames/second) */ -static WFDB_Frequency sfreq; /* sampling frequency (samples/second) */ +static WFDB_Frequency ifreq; /* samples/second/signal returned by getvec */ +static WFDB_Frequency sfreq; /* samples/second/signal read by getvec */ static WFDB_Frequency cfreq; /* counter frequency (ticks/second) */ -static WFDB_Time btime; /* base time (seconds since midnight) */ +static long btime; /* base time (milliseconds since midnight) */ static WFDB_Date bdate; /* base date (Julian date) */ static WFDB_Time nsamples; /* duration of signals (in samples) */ static double bcount; /* base count (counter value at sample 0) */ @@ -222,7 +226,7 @@ static int segments; /* number of segments found by readheader() */ static int in_msrec; /* current input record is: 0: a single-segment record; 1: a multi-segment record */ -static WFDB_Time msbtime; /* base time for multi-segment record */ +static long msbtime; /* base time for multi-segment record */ static WFDB_Date msbdate; /* base date for multi-segment record */ static WFDB_Time msnsamples; /* duration of multi-segment record */ static struct segrec { @@ -595,7 +599,7 @@ /* Determine the base time and date, if present and not set already. */ if ((p = strtok((char *)NULL,"\n\r")) != NULL && - btime == (WFDB_Time)0L && setbasetime(p) < 0) + btime == 0L && setbasetime(p) < 0) return (-2); /* error message will come from setbasetime */ /* Special processing for master header of a multi-segment record. */ @@ -850,15 +854,17 @@ { struct hsdata *hs; - while (maxhsig) - if (hs = hsd[--maxhsig]) { - if (hs->info.fname) (void)free(hs->info.fname); - if (hs->info.units) (void)free(hs->info.units); - if (hs->info.desc) (void)free(hs->info.desc); - (void)free(hs); - } - (void)free(hsd); - hsd = NULL; + if (hsd) { + while (maxhsig) + if (hs = hsd[--maxhsig]) { + if (hs->info.fname) (void)free(hs->info.fname); + if (hs->info.units) (void)free(hs->info.units); + if (hs->info.desc) (void)free(hs->info.desc); + (void)free(hs); + } + (void)free(hsd); + hsd = NULL; + } maxhsig = 0; } @@ -868,25 +874,33 @@ struct igdata *ig; if (nisig == 0) return; - while (nisig) - if (is = isd[--nisig]) { - if (is->info.fname) (void)free(is->info.fname); - if (is->info.units) (void)free(is->info.units); - if (is->info.desc) (void)free(is->info.desc); - (void)free(is); - } - (void)free(isd); - isd = NULL; + if (isd) { + while (nisig) + if (is = isd[--nisig]) { + if (is->info.fname) (void)free(is->info.fname); + if (is->info.units) (void)free(is->info.units); + if (is->info.desc) (void)free(is->info.desc); + (void)free(is); + } + (void)free(isd); + isd = NULL; + } + else + nisig = 0; maxisig = 0; - while (nigroups) - if (ig = igd[--nigroups]) { - if (ig->fp) wfdb_fclose(ig->fp); - if (ig->buf) (void)free(ig->buf); - (void)free(ig); - } - (void)free(igd); - igd = NULL; + if (igd) { + while (nigroups) + if (ig = igd[--nigroups]) { + if (ig->fp) (void)wfdb_fclose(ig->fp); + if (ig->buf) (void)free(ig->buf); + (void)free(ig); + } + (void)free(igd); + igd = NULL; + } + else + nigroups = 0; maxigroup = 0; istime = 0L; @@ -905,39 +919,46 @@ struct ogdata *og; if (nosig == 0) return; - while (nosig) - if (os = osd[--nosig]) { - if (os->info.fname) (void)free(os->info.fname); - if (os->info.units) (void)free(os->info.units); - if (os->info.desc) (void)free(os->info.desc); - (void)free(os); - } - (void)free(osd); - osd = NULL; + if (osd) { + while (nosig) + if (os = osd[--nosig]) { + if (os->info.fname) (void)free(os->info.fname); + if (os->info.units) (void)free(os->info.units); + if (os->info.desc) (void)free(os->info.desc); + (void)free(os); + } + (void)free(osd); + osd = NULL; + } + else + nosig = 0; maxosig = 0; - while (nogroups) - if (og = ogd[--nogroups]) { - if (og->fp) { - /* If a block size has been defined, null-pad the buffer. */ - if (og->bsize) - while (og->bp != og->be) - *(og->bp++) = '\0'; - /* Flush the last block unless it's empty. */ - if (og->bp != og->buf) - (void)wfdb_fwrite(og->buf, 1, og->bp - og->buf, - og->fp); - /* Close file (except stdout, which will be closed on exit). */ - if (og->fp->fp != stdout) { - (void)wfdb_fclose(og->fp); - og->fp = NULL; + if (ogd) { + while (nogroups) + if (og = ogd[--nogroups]) { + if (og->fp) { + /* If a block size has been defined, null-pad the buffer */ + if (og->bsize) + while (og->bp != og->be) + *(og->bp++) = '\0'; + /* Flush the last block unless it's empty. */ + if (og->bp != og->buf) + (void)wfdb_fwrite(og->buf, 1, og->bp-og->buf, og->fp); + /* Close file (except stdout, which is closed on exit). */ + if (og->fp->fp != stdout) { + (void)wfdb_fclose(og->fp); + og->fp = NULL; + } } + if (og->buf) (void)free(og->buf); + (void)free(og); } - if (og->buf) (void)free(og->buf); - (void)free(og); - } - (void)free(ogd); - ogd = NULL; + (void)free(ogd); + ogd = NULL; + } + else + nogroups = 0; maxogroup = 0; ostime = 0L; @@ -1407,6 +1428,47 @@ return (stat); } +static int rgetvec(vector) +WFDB_Sample *vector; +{ + WFDB_Sample *tp; + WFDB_Signal s; + static int stat; + + if (ispfmax < 2) /* all signals at the same frequency */ + return (getframe(vector)); + + if (gvmode == WFDB_LOWRES) {/* return one sample per frame, decimating + (by averaging) if necessary */ + unsigned c; + long v; + + stat = getframe(tvector); + for (s = 0, tp = tvector; s < nisig; s++) { + int sf = isd[s]->info.spf; + + for (c = v = 0; c < sf; c++) + v += *tp++; + *vector++ = v/sf; + } + } + else { /* return ispfmax samples per frame, using + zero-order interpolation if necessary */ + if (gvc >= ispfmax) { + stat = getframe(tvector); + gvc = 0; + } + for (s = 0, tp = tvector; s < nisig; s++) { + int sf = isd[s]->info.spf; + + *vector++ = tp[(sf*gvc)/ispfmax]; + tp += sf; + } + gvc++; + } + return (stat); +} + /* WFDB library functions. */ FINT isigopen(record, siarray, nsig) @@ -1435,7 +1497,7 @@ /* Open the first segment to get signal information. */ if ((navail = readheader(segp->recname)) >= 0) { if (msbtime == 0L) msbtime = btime; - if (msbdate == 0L) msbdate = bdate; + if (msbdate == (WFDB_Date)0) msbdate = bdate; } } if (navail == 0 && nsig) @@ -1513,6 +1575,7 @@ /* Skip this group if the signal file can't be opened. */ if (ig->fp == NULL) { (void)free(ig->buf); + ig->buf = NULL; continue; } } @@ -1847,45 +1910,91 @@ } } -FINT getvec(vector) -WFDB_Sample *vector; -{ - WFDB_Sample *tp; - WFDB_Signal s; - static int stat; +/* An application can specify the input sampling frequency it prefers by + calling setifreq after opening the input record. */ - if (ispfmax < 2) /* all signals at the same frequency */ - return (getframe(vector)); +static long mticks, nticks, mnticks; +static int rgvstat; +static WFDB_Time rgvtime, gvtime; +static WFDB_Sample *gv0, *gv1; + +FINT setifreq(f) +WFDB_Frequency f; +{ + if (f > 0.0) { + WFDB_Frequency error, g = sfreq; + + gv0 = realloc(gv0, nisig*sizeof(WFDB_Sample)); + gv1 = realloc(gv1, nisig*sizeof(WFDB_Sample)); + if (gv0 == NULL || gv1 == NULL) { + wfdb_error("setifreq: too many (%d) input signals\n", nisig); + if (gv0) (void)free(gv0); + ifreq = 0.0; + return (-2); + } + ifreq = f; + /* The 0.005 below is the maximum tolerable error in the resampling + frequency (in Hz). The code in the while loop implements Euclid's + algorithm for finding the greatest common divisor of two integers, + but in this case the integers are (implicit) multiples of 0.005. */ + while ((error = f - g) > 0.005 || error < -0.005) + if (f > g) f -= g; + else g -= f; + /* f is now the GCD of sfreq and ifreq in the sense described above. + We divide each raw sampling interval into mticks subintervals. */ + mticks = (long)(sfreq/f + 0.5); + /* We divide each resampled interval into nticks subintervals. */ + nticks = (long)(ifreq/f + 0.5); + /* Raw and resampled intervals begin simultaneously once every mnticks + subintervals; we say an epoch begins at these times. */ + mnticks = mticks * nticks; + /* gvtime is the number of subintervals from the beginning of the + current epoch to the next sample to be returned by getvec(). */ + gvtime = 0; + rgvstat = rgetvec(gv0); + rgvstat = rgetvec(gv1); + /* rgvtime is the number of subintervals from the beginning of the + current epoch to the most recent sample returned by rgetvec(). */ + rgvtime = nticks; + return (0); + } + else { + ifreq = 0.0; + wfdb_error("setifreq: improper frequency %g (must be > 0)\n", f); + return (-1); + } +} - if (gvmode == WFDB_LOWRES) {/* return one sample per frame, decimating - (by averaging) if necessary */ - unsigned c; - long v; +FFREQUENCY getifreq(void) +{ + return (ifreq > (WFDB_Frequency)0 ? ifreq : sfreq); +} - stat = getframe(tvector); - for (s = 0, tp = tvector; s < nisig; s++) { - int sf = isd[s]->info.spf; +FINT getvec(vector) +WFDB_Sample *vector; +{ + int i; - for (c = v = 0; c < sf; c++) - v += *tp++; - *vector++ = v/sf; - } - } - else { /* return ispfmax samples per frame, using - zero-order interpolation if necessary */ - if (gvc >= ispfmax) { - stat = getframe(tvector); - gvc = 0; - } - for (s = 0, tp = tvector; s < nisig; s++) { - int sf = isd[s]->info.spf; + if (ifreq == 0.0 || ifreq == sfreq) /* no resampling necessary */ + return (rgetvec(vector)); - *vector++ = tp[(sf*gvc)/ispfmax]; - tp += sf; - } - gvc++; + /* Resample the input. */ + if (rgvtime > mnticks) { + rgvtime -= mnticks; + gvtime -= mnticks; + } + while (gvtime > rgvtime) { + for (i = 0; i < nisig; i++) + gv0[i] = gv1[i]; + rgvstat = rgetvec(gv1); + rgvtime += nticks; + } + for (i = 0; i < nisig; i++) { + vector[i] = gv0[i] + (gvtime%nticks)*(gv1[i]-gv0[i])/nticks; + gv0[i] = gv1[i]; } - return (stat); + gvtime += mticks; + return (rgvstat); } FINT getframe(vector) @@ -1898,7 +2007,7 @@ /* First, obtain the samples needed. */ if (dsbi < 0) { /* dsbuf contents are invalid -- refill dsbuf */ - for (dsbi = 0; dsbi < dsblen; dsbi += framelen) + for (dsbi = i = 0; i < dsblen; dsbi = i += framelen) stat = getskewedframe(dsbuf + dsbi); dsbi = 0; } @@ -1995,11 +2104,17 @@ WFDB_Group g; WFDB_Time t; { - int spf, stat, trem = 0; + int spf, stat, tr, trem = 0; /* Handle negative arguments as equivalent positive arguments. */ if (t < 0L) t = -t; + tr = t; + + /* Convert t to raw sample intervals if we are resampling. */ + if (ifreq > (WFDB_Frequency)0) + t = (WFDB_Time)(t * sfreq/ifreq); + /* If we're in WFDB_HIGHRES mode, convert t from samples to frames, and save the remainder (if any) in trem. */ if (sfreq != ffreq) { @@ -2010,13 +2125,27 @@ if ((stat = isgsetframe(g, t)) == 0 && g == 0) { while (trem-- > 0) { - if (getvec(uvector) < 0) { + if (rgetvec(uvector) < 0) { wfdb_error("isigsettime: improper seek on signal group %d\n", g); return (-1); } } + if (ifreq > (WFDB_Frequency)0 && ifreq != sfreq) { + gvtime = 0; + rgvstat = rgetvec(gv0); + rgvstat = rgetvec(gv1); + rgvtime = nticks; + } + } + + if (tr != t) { + t = (WFDB_Time)(t * ifreq/sfreq); + + while (t++ < tr) + getvec(uvector); } + return (stat); } @@ -2108,8 +2237,14 @@ (void)wfdb_fprintf(oheader, "(%g)", bcount); } (void)wfdb_fprintf(oheader, " %ld", siarray[0].nsamp); - if (btime || bdate) - (void)wfdb_fprintf(oheader, " %s", timstr((WFDB_Time)(btime*sfreq))); + if (btime != 0L || bdate != (WFDB_Date)0) { + if (btime % 1000 == 0) + (void)wfdb_fprintf(oheader, " %s", + timstr((WFDB_Time)(btime*sfreq/1000.0))); + else + (void)wfdb_fprintf(oheader, " %s", + mstimstr((WFDB_Time)(btime*sfreq/1000.0))); + } if (bdate) (void)wfdb_fprintf(oheader, "%s", datstr(bdate)); (void)wfdb_fprintf(oheader, "\r\n"); @@ -2239,8 +2374,14 @@ (void)wfdb_fprintf(oheader, "(%g)", msbcount); } (void)wfdb_fprintf(oheader, " %ld", msnsamples); - if (msbtime || msbdate) - (void)wfdb_fprintf(oheader, " %s", timstr((WFDB_Time)(msbtime*sfreq))); + if (msbtime != 0L || msbdate != (WFDB_Date)0) { + if (msbtime % 1000 == 0) + (void)wfdb_fprintf(oheader, " %s", + timstr((WFDB_Time)(msbtime*sfreq/1000.0))); + else + (void)wfdb_fprintf(oheader, " %s", + mstimstr((WFDB_Time)(msbtime*sfreq/1000.0))); + } if (msbdate) (void)wfdb_fprintf(oheader, "%s", datstr(msbdate)); (void)wfdb_fprintf(oheader, "\r\n"); @@ -2392,7 +2533,7 @@ if (string == NULL || *string == '\0') { #ifndef NOTIME struct tm *now; - time_t t, time(); + time_t t; t = time((time_t *)NULL); /* get current time from system clock */ now = localtime(&t); @@ -2401,20 +2542,20 @@ bdate = strdat(date_string); (void)sprintf(time_string, "%d:%d:%d", now->tm_hour, now->tm_min, now->tm_sec); - btime = (WFDB_Time)(strtim(time_string)/sfreq); + btime = (long)(strtim(time_string)*1000.0/sfreq); #endif return (0); } while (*string == ' ') string++; if (p = strchr(string, ' ')) *p++ = '\0'; /* split time and date components */ - if ((btime = strtim(string)) == 0L || - (p && (bdate = strdat(p)) == 0L)) { + if ((btime = strtim(string)) == 0L) { if (p) *(--p) = ' '; wfdb_error("setbasetime: incorrect time format, '%s'\n", string); return (-1); } - btime = (WFDB_Time)(btime/sfreq); + if (p) bdate = strdat(p); + btime *= 1000.0/sfreq; return (0); } @@ -2424,7 +2565,7 @@ char *p; p = strtok(mstimstr(t), "."); /* discard msec field */ - if (t <= 0L && (btime != 0L || bdate != 0L)) { /* time of day */ + if (t <= 0L && (btime != 0L || bdate != (WFDB_Date)0)) { /* time of day */ (void)strcat(p, date_string); /* append dd/mm/yyyy */ (void)strcat(p, "]"); } @@ -2436,12 +2577,16 @@ FSTRING mstimstr(t) WFDB_Time t; { - double f = (sfreq > 0.) ? sfreq : 1.; + double f; int hours, minutes, seconds, msec; WFDB_Date days; long s; - if (t > 0L || (btime == 0L && bdate == 0L)) { /* time interval */ + if (ifreq > 0.) f = ifreq; + else if (sfreq > 0.) f = sfreq; + else f = 1.0; + + if (t > 0L || (btime == 0L && bdate == (WFDB_Date)0)) { /* time interval */ if (t < 0L) t = -t; /* Convert from sample intervals to seconds. */ s = t / f; @@ -2460,7 +2605,7 @@ } else { /* time of day */ /* Convert to sample intervals since midnight. */ - t = (WFDB_Time)(btime*sfreq) - t; + t = (WFDB_Time)(btime*sfreq/1000.0) - t; /* Convert from sample intervals to seconds. */ s = t / f; msec = (t - s*f)*1000/f; @@ -2515,24 +2660,26 @@ WFDB_Date days = 0L; WFDB_Time t; - f = (sfreq > 0.) ? sfreq : 1.; + if (ifreq > 0.) f = ifreq; + else if (sfreq > 0.) f = sfreq; + else f = 1.0; while (*string==' ' || *string=='\t' || *string=='\n' || *string=='\r') string++; switch (*string) { case 'c': return (cfreq > 0. ? - (WFDB_Time)((atof(string+1)-bcount)*sfreq/cfreq) : + (WFDB_Time)((atof(string+1)-bcount)*f/cfreq) : (WFDB_Time)atol(string+1)); case 'e': return (in_msrec ? msnsamples : nsamples); - case 'f': return ((WFDB_Time)(atol(string+1)*sfreq/ffreq)); + case 'f': return ((WFDB_Time)(atol(string+1)*f/ffreq)); case 'i': return (istime * (gvmode==WFDB_LOWRES ? 1: ispfmax)); case 'o': return (ostime); case 's': return ((WFDB_Time)atol(string+1)); case '[': /* time of day, possibly with date or days since start */ if (p = strchr(string, ' ')) { if (strchr(p, '/')) days = strdat(p) - bdate; - else days = atol(p); + else days = atol(p+1); } - t = strtim(string+1) - (WFDB_Time)(btime*sfreq); + t = strtim(string+1) - (WFDB_Time)(btime*f/1000.0); if (days > 0L) t += (WFDB_Time)(days*24*60*60*f); return (-t); default: @@ -2602,20 +2749,30 @@ WFDB_Signal s; WFDB_Sample a; { + double x; WFDB_Gain g = (s < nisig) ? isd[s]->info.gain : WFDB_DEFGAIN; if (g == 0.) g = WFDB_DEFGAIN; - return ((int)(a*1000./g + 0.5)); + x = a*1000./g; + if (x >= 0.0) + return ((int)(x + 0.5)); + else + return ((int)(x - 0.5)); } FSAMPLE muvadu(s, v) WFDB_Signal s; int v; { + double x; WFDB_Gain g = (s < nisig) ? isd[s]->info.gain : WFDB_DEFGAIN; if (g == 0.) g = WFDB_DEFGAIN; - return ((int)(g*v*0.001 + 0.5)); + x = g*v*0.001; + if (x >= 0.0) + return ((int)(x + 0.5)); + else + return ((int)(x - 0.5)); } FDOUBLE aduphys(s, a) @@ -2653,7 +2810,11 @@ b = 0; g = WFDB_DEFGAIN; } - return ((int)(g*v + 0.5) + b); + v *= g; + if (v >= 0) + return ((int)(v + 0.5) + b); + else + return ((int)(v - 0.5) + b); } /* Private functions (for use by other WFDB library functions only). */ @@ -2663,7 +2824,7 @@ isigclose(); osigclose(); btime = bdate = nsamples = msbtime = msbdate = msnsamples = (WFDB_Time)0; - sfreq = ffreq = (WFDB_Frequency)0; + sfreq = ifreq = ffreq = (WFDB_Frequency)0; pdays = (WFDB_Date)-1; segments = in_msrec = skewmax = 0; if (dsbuf) { @@ -2687,6 +2848,9 @@ } } } + if (gv0) (void)free(gv0); + if (gv1) (void)free(gv1); + gv0 = gv1 = NULL; } void wfdb_osflush() diff -Naur wfdb-10.2.5/lib/wfdb.h wfdb-10.2.6/lib/wfdb.h --- wfdb-10.2.5/lib/wfdb.h Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/lib/wfdb.h Mon Jun 24 22:43:07 2002 @@ -1,5 +1,5 @@ /* file: wfdb.h G. Moody 13 June 1983 - Last revised: 15 January 2002 wfdblib 10.2.5 + Last revised: 23 May 2002 wfdblib 10.2.6 WFDB library type, constant, structure, and function interface definitions _______________________________________________________________________________ @@ -33,7 +33,7 @@ /* WFDB library version. */ #define WFDB_MAJOR 10 #define WFDB_MINOR 2 -#define WFDB_RELEASE 5 +#define WFDB_RELEASE 6 #define WFDB_NETFILES 1 /* if 1, library includes code for HTTP, FTP clients */ /* Determine what type of compiler is being used. */ @@ -234,6 +234,8 @@ WFDB_Siginfo *siarray, unsigned int nsig); extern FINT getspf(void); extern FVOID setgvmode(int mode); +extern FINT setifreq(WFDB_Frequency freq); +extern FFREQUENCY getifreq(void); extern FINT getvec(WFDB_Sample *vector); extern FINT getframe(WFDB_Sample *vector); extern FINT putvec(WFDB_Sample *vector); @@ -300,12 +302,12 @@ #endif #ifdef wfdb_KRC /* declare only function return types for K&R C compilers */ -extern FINT annopen(), isigopen(), osigopen(), wfdbinit(), getspf(), getvec(), - getframe(), putvec(), getann(), ungetann(), putann(), isigsettime(), - isgsettime(), iannsettime(), strecg(), setecgstr(), strann(), setannstr(), - setanndesc(), adumuv(), newheader(), setheader(), setmsheader(), - setsampfreq(), setbasetime(), putinfo(), setibsize(), setobsize(), - calopen(), getcal(), putcal(), newcal(), wfdbgetskew(); +extern FINT annopen(), isigopen(), osigopen(), wfdbinit(), getspf(), + setifreq(), getvec(), getframe(), putvec(), getann(), ungetann(), putann(), + isigsettime(), isgsettime(), iannsettime(), strecg(), setecgstr(), + strann(), setannstr(), setanndesc(), adumuv(), newheader(), setheader(), + setmsheader(), setsampfreq(), setbasetime(), putinfo(), setibsize(), + setobsize(), calopen(), getcal(), putcal(), newcal(), wfdbgetskew(); extern FLONGINT wfdbgetstart(); extern FSAMPLE muvadu(), physadu(); extern FSTRING ecgstr(), annstr(), anndesc(), timstr(), mstimstr(), @@ -315,7 +317,7 @@ extern FVOID setgvmode(), wfdbquit(), wfdbquiet(), dbverbose(), setdb(), wfdbflush(), setcfreq(), setbasecount(), flushcal(), wfdbsetskew(), wfdbsetstart(); -extern FFREQUENCY sampfreq(), getcfreq(); +extern FFREQUENCY getifreq(), sampfreq(), getcfreq(); extern FDOUBLE aduphys(), getbasecount(); #endif diff -Naur wfdb-10.2.5/lib/wfdbio.c wfdb-10.2.6/lib/wfdbio.c --- wfdb-10.2.5/lib/wfdbio.c Mon Dec 17 22:07:40 2001 +++ wfdb-10.2.6/lib/wfdbio.c Sun Jun 2 15:09:58 2002 @@ -1,10 +1,10 @@ /* file: wfdbio.c G. Moody 18 November 1988 - Last revised: 17 December 2001 wfdblib 10.2.4 + Last revised: 2 June 2002 wfdblib 10.2.6 Low-level I/O functions for the WFDB library _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 2001 George B. Moody +Copyright (C) 2002 George B. Moody This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free @@ -108,7 +108,6 @@ are not likely to change, since they are designed to emulate the similarly-named ANSI/ISO C standard I/O functions: wfdb_clearerr (emulates clearerr) - wfdb_fclose (emulates fclose) wfdb_feof (emulates feof) wfdb_ferror (emulates ferror) wfdb_fflush (emulates fflush, for local files only) @@ -119,13 +118,14 @@ wfdb_fwrite (emulates fwrite, for local files only) wfdb_getc (emulates getc) wfdb_putc (emulates putc, for local files only) + wfdb_fclose (emulates fclose) wfdb_fopen (emulates fopen, but returns a WFDB_FILE pointer) -(If WFDB_NETFILES is zero, wfdblib.h defines all but the last of these +(If WFDB_NETFILES is zero, wfdblib.h defines all but the last two of these functions as macros that invoke the standard I/O functions that they would -otherwise emulate. The implementation of wfdb_fopen is below; it includes -a small amount of code compiled only if WFDB_NETFILES is non-zero. All of -these functions are new in version 10.0.1.) +otherwise emulate. The implementations of wfdb_fclose and wfdb_fopen are +below; they include a small amount of code compiled only if WFDB_NETFILES +is non-zero. All of these functions are new in version 10.0.1.) Finally, this file includes several miscellaneous functions needed only in certain environments: @@ -160,7 +160,6 @@ FSTRING getwfdb() { - char *getenv(); void wfdb_getiwfdb(); if (wfdbpath == NULL) { @@ -416,7 +415,6 @@ /* Register the cleanup function so that it is invoked on exit. */ atexit(wfdb_free_path_list); - q = p; /* Now construct the wfdb_path_list from the contents of p. */ @@ -612,6 +610,15 @@ return (error_message); } +#if WFDB_NETFILES +static int nf_vfprintf(netfile *nf, const char *format, va_list ap) +{ + /* no support yet for writing to remote files */ + errno = EROFS; + return (0); +} +#endif + /* First version: for ANSI C compilers and Microsoft Windows */ #if defined(__STDC__) || defined(_WINDOWS) #include @@ -642,13 +649,12 @@ int wfdb_fprintf(WFDB_FILE *wp, const char *format, ...) { int ret; - static int nf_vfprintf(); va_list args; va_start(args, format); #if WFDB_NETFILES if (wp->type == WFDB_NET) - ret = nf_vfprintf(wp->fp, format, args); + ret = nf_vfprintf(wp->netfp, format, args); else #endif ret = vfprintf(wp->fp, format, args); @@ -911,6 +917,9 @@ { do { if (('0' <= *p && *p <= '9') || *p == '_' || *p == '~' || *p == DSEP || +#ifdef MSDOS + *p == ':' || +#endif ('a' <= *p && *p <= 'z') || ('A' <= *p && *p <= 'Z')) p++; else { @@ -1080,16 +1089,22 @@ } } if (chunk && (HTChunk_size(chunk) > len)) { - /* While we may have received something, we did not receive the - requested range (more precisely, a range of the same size as the - one we requested). Assume that we got the entire file instead. - This seems to happen both if the file was in the cache or if the - server does not support the range request. */ - /* What does this block of code do? */ -#define WWW_CHUNK_GROWBY 64 - extra_chunk = HTChunk_new(WWW_CHUNK_GROWBY); + /* While we may have received something, we did not receive the + requested range (more precisely, a range of the same size as the + one we requested). Assume that we got the entire file instead. + This seems to happen both if the file was in the cache or if + the server does not support the range request. Since the caller + expects only a chunk of len bytes (not necessarily at the + beginning of the file), we need to create a new chunk and return + it to the caller. HTChunk_new makes a new chunk, which grows as + needed in multiples of its argument (in bytes). */ + extra_chunk = HTChunk_new(64); + /* Copy the desired range out of the chunk we received into the new + chunk. */ HTChunk_putb(extra_chunk, &HTChunk_data(chunk)[startb], len); + /* Discard the chunk we received. */ HTChunk_delete(chunk); + /* Arrange for the new chunk to be returned. */ chunk = extra_chunk; } HTRequest_delete(request); @@ -1411,12 +1426,9 @@ return (EOF); } -static int nf_vfprintf(netfile *nf, const char *format, va_list ap) -{ - /* no support yet for writing to remote files */ - errno = EROFS; - return (0); -} +/* The definition of nf_vfprintf (which is a stub) has been moved; it is + now just before wfdb_fprintf, which refers to it. There is no completely + portable way to make a forward reference to a static (local) function. */ void wfdb_clearerr(wp) WFDB_FILE *wp; @@ -1426,13 +1438,6 @@ return (clearerr(wp->fp)); } -int wfdb_fclose(WFDB_FILE *wp) -{ - if (wp->type == WFDB_NET) - return (nf_fclose(wp->netfp)); - return (fclose(wp->fp)); -} - int wfdb_feof(wp) WFDB_FILE *wp; { @@ -1528,6 +1533,19 @@ #endif /* WFDB_NETFILES */ +int wfdb_fclose(WFDB_FILE *wp) +{ + int status; + +#if WFDB_NETFILES + status = (wp->type == WFDB_NET) ? nf_fclose(wp->netfp) : fclose(wp->fp); +#else + status = fclose(wp->fp); +#endif + (void)free(wp); + return (status); +} + WFDB_FILE *wfdb_fopen(fname, mode) char *fname; const char *mode; @@ -1581,6 +1599,8 @@ return (NULL); } +/* Miscellaneous OS-specific functions. */ + #ifdef NOSTRTOK char *strtok(p, sep) char *p, *sep; @@ -1676,4 +1696,3 @@ } #endif #endif - diff -Naur wfdb-10.2.5/lib/wfdblib.h wfdb-10.2.6/lib/wfdblib.h --- wfdb-10.2.5/lib/wfdblib.h Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/lib/wfdblib.h Mon Jun 24 22:43:07 2002 @@ -1,10 +1,10 @@ /* file: wfdblib.h G. Moody 13 April 1989 - Last revised: 7 November 2001 wfdblib 10.2.1 + Last revised: 17 June 2002 wfdblib 10.2.6 External definitions for WFDB library private functions _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 2001 George B. Moody +Copyright (C) 2002 George B. Moody This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free @@ -64,7 +64,11 @@ /* Define the symbol MSDOS if this library is to be used under MS-DOS or MS Windows. Note: MSDOS is predefined by some MS-DOS and MS Windows compilers. */ -/* #define MSDOS */ +#if defined(_WINDOWS) +# if !defined(MSDOS) +# define MSDOS +# endif +#endif /* Uncomment the next line if this software is to be compiled on a Macintosh.*/ /* #define MAC */ @@ -131,7 +135,7 @@ invoking setgvmode(), the value of the environment variable WFDBGVMODE determines the mode (0: WFDB_LOWRES, non-zero: WFDB_HIGHRES); if WFDBGVMODE is not set, the value of DEFWFDBMODE determines the mode. */ -#define DEFWFDBGVMODE 0 +#define DEFWFDBGVMODE WFDB_LOWRES /* putenv() is available in POSIX, SVID, and BSD Unices and in MS-DOS and 32-bit MS Windows, but not under 16-bit MS Windows or under MacOS. If it is @@ -229,24 +233,8 @@ #define NF_CHUNK_MODE 0 /* http range requests supported */ #define NF_FULL_MODE 1 /* http range requests not supported */ -/* Function prototypes */ -extern void wfdb_clearerr(WFDB_FILE *fp); -extern int wfdb_fclose(WFDB_FILE *fp); -extern int wfdb_feof(WFDB_FILE *fp); -extern int wfdb_ferror(WFDB_FILE *fp); -extern int wfdb_fflush(WFDB_FILE *fp); -extern char* wfdb_fgets(char *s, int size, WFDB_FILE *fp); -extern size_t wfdb_fread(void *ptr, size_t size, size_t nmemb, WFDB_FILE *fp); -extern int wfdb_fseek(WFDB_FILE *fp, long offset, int whence); -extern long wfdb_ftell(WFDB_FILE *fp); -extern size_t wfdb_fwrite(void *ptr, size_t size, size_t nmemb, WFDB_FILE *fp); -extern int wfdb_getc(WFDB_FILE *fp); -extern int wfdb_putc(int c, WFDB_FILE *fp); -extern void wfdb_wwwquit(void); - #else /* WFDB_NETFILES = 0 -- use standard I/O functions only */ -#define wfdb_fclose(wp) fclose(wp->fp) #define wfdb_feof(wp) feof(wp->fp) #define wfdb_ferror(wp) ferror(wp->fp) #define wfdb_fflush(wp) ((wp == NULL) ? fflush(NULL) : fflush(wp->fp)) @@ -261,11 +249,13 @@ #endif /* The following block is needed only to declare the values returned by - malloc() (either char * or void *) and sprintf() (either int or char *). - The object code should be correct even if these declarations are not. */ + getenv() (char * unless otherwise defined in stdlib.h), malloc() (either + char * or void *) and sprintf() (either int or char *). The object code + should be correct even if these declarations are not. */ #if defined(__STDC__) || defined(_WINDOWS) # include #else +extern char *getenv(); # ifndef NOMALLOC_H # include # else @@ -296,6 +286,7 @@ #endif #ifdef _WINDOWS +#include /* needed for mkdir() declaration */ #ifndef _WIN32 /* these definitions are needed for 16-bit MS Windows only */ #define strcat _fstrcat #define strchr _fstrchr @@ -314,6 +305,7 @@ #endif /* These functions are defined in wfdbio.c */ +extern int wfdb_fclose(WFDB_FILE *fp); extern WFDB_FILE *wfdb_open(char *file_type, char *record, int mode); extern int wfdb_checkname(char *name, char *description); extern int wfdb_g16(WFDB_FILE *fp); @@ -323,10 +315,25 @@ extern int wfdb_parse_path(char *wfdb_path); extern void wfdb_addtopath(char *pathname); extern void wfdb_error(char *format_string, ...); -extern WFDB_FILE* wfdb_fopen(char *fname, const char *mode); +extern WFDB_FILE *wfdb_fopen(char *fname, const char *mode); extern int wfdb_fprintf(WFDB_FILE *fp, const char *format, ...); extern void wfdb_setirec(char *record_name); +#if WFDB_NETFILES +extern void wfdb_clearerr(WFDB_FILE *fp); +extern int wfdb_feof(WFDB_FILE *fp); +extern int wfdb_ferror(WFDB_FILE *fp); +extern int wfdb_fflush(WFDB_FILE *fp); +extern char *wfdb_fgets(char *s, int size, WFDB_FILE *fp); +extern size_t wfdb_fread(void *ptr, size_t size, size_t nmemb, WFDB_FILE *fp); +extern int wfdb_fseek(WFDB_FILE *fp, long offset, int whence); +extern long wfdb_ftell(WFDB_FILE *fp); +extern size_t wfdb_fwrite(void *ptr, size_t size, size_t nmemb, WFDB_FILE *fp); +extern int wfdb_getc(WFDB_FILE *fp); +extern int wfdb_putc(int c, WFDB_FILE *fp); +extern void wfdb_wwwquit(void); +#endif + /* These functions are defined in signal.c */ extern void wfdb_sigclose(void); extern void wfdb_osflush(void); @@ -347,6 +354,15 @@ extern void wfdb_p16(), wfdb_p32(), wfdb_addtopath(), wfdb_error(), wfdb_setirec(), wfdb_sigclose(), wfdb_anclose(), wfdb_osflush(), wfdb_oaflush(); + +# if WFDB_NETFILES +extern char *wfdb_fgets(); +extern int wfdb_feof(), wfdb_ferror(), wfdb_fflush(), wfdb_fseek(), + wfdb_getc(), wfdb_putc(); +extern long wfdb_ftell(); +extern size_t wfdb_fread(), wfdb_fwrite(); +extern void wfdb_clearerr(), wfdb_wwwquit(); +# endif /* Some non-ANSI C libraries (e.g., version 7, BSD 4.2) lack an implementation of strtok(); define NOSTRTOK to compile the portable version in wfdbio.c. */ diff -Naur wfdb-10.2.5/lib/wfdblib.h0 wfdb-10.2.6/lib/wfdblib.h0 --- wfdb-10.2.5/lib/wfdblib.h0 Wed Nov 7 16:46:17 2001 +++ wfdb-10.2.6/lib/wfdblib.h0 Mon Jun 17 09:50:22 2002 @@ -1,10 +1,10 @@ /* file: wfdblib.h G. Moody 13 April 1989 - Last revised: 7 November 2001 wfdblib 10.2.1 + Last revised: 17 June 2002 wfdblib 10.2.6 External definitions for WFDB library private functions _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 2001 George B. Moody +Copyright (C) 2002 George B. Moody This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free @@ -64,7 +64,11 @@ /* Define the symbol MSDOS if this library is to be used under MS-DOS or MS Windows. Note: MSDOS is predefined by some MS-DOS and MS Windows compilers. */ -/* #define MSDOS */ +#if defined(_WINDOWS) +# if !defined(MSDOS) +# define MSDOS +# endif +#endif /* Uncomment the next line if this software is to be compiled on a Macintosh.*/ /* #define MAC */ @@ -131,7 +135,7 @@ invoking setgvmode(), the value of the environment variable WFDBGVMODE determines the mode (0: WFDB_LOWRES, non-zero: WFDB_HIGHRES); if WFDBGVMODE is not set, the value of DEFWFDBMODE determines the mode. */ -#define DEFWFDBGVMODE 0 +#define DEFWFDBGVMODE WFDB_LOWRES /* putenv() is available in POSIX, SVID, and BSD Unices and in MS-DOS and 32-bit MS Windows, but not under 16-bit MS Windows or under MacOS. If it is @@ -229,24 +233,8 @@ #define NF_CHUNK_MODE 0 /* http range requests supported */ #define NF_FULL_MODE 1 /* http range requests not supported */ -/* Function prototypes */ -extern void wfdb_clearerr(WFDB_FILE *fp); -extern int wfdb_fclose(WFDB_FILE *fp); -extern int wfdb_feof(WFDB_FILE *fp); -extern int wfdb_ferror(WFDB_FILE *fp); -extern int wfdb_fflush(WFDB_FILE *fp); -extern char* wfdb_fgets(char *s, int size, WFDB_FILE *fp); -extern size_t wfdb_fread(void *ptr, size_t size, size_t nmemb, WFDB_FILE *fp); -extern int wfdb_fseek(WFDB_FILE *fp, long offset, int whence); -extern long wfdb_ftell(WFDB_FILE *fp); -extern size_t wfdb_fwrite(void *ptr, size_t size, size_t nmemb, WFDB_FILE *fp); -extern int wfdb_getc(WFDB_FILE *fp); -extern int wfdb_putc(int c, WFDB_FILE *fp); -extern void wfdb_wwwquit(void); - #else /* WFDB_NETFILES = 0 -- use standard I/O functions only */ -#define wfdb_fclose(wp) fclose(wp->fp) #define wfdb_feof(wp) feof(wp->fp) #define wfdb_ferror(wp) ferror(wp->fp) #define wfdb_fflush(wp) ((wp == NULL) ? fflush(NULL) : fflush(wp->fp)) @@ -261,11 +249,13 @@ #endif /* The following block is needed only to declare the values returned by - malloc() (either char * or void *) and sprintf() (either int or char *). - The object code should be correct even if these declarations are not. */ + getenv() (char * unless otherwise defined in stdlib.h), malloc() (either + char * or void *) and sprintf() (either int or char *). The object code + should be correct even if these declarations are not. */ #if defined(__STDC__) || defined(_WINDOWS) # include #else +extern char *getenv(); # ifndef NOMALLOC_H # include # else @@ -296,6 +286,7 @@ #endif #ifdef _WINDOWS +#include /* needed for mkdir() declaration */ #ifndef _WIN32 /* these definitions are needed for 16-bit MS Windows only */ #define strcat _fstrcat #define strchr _fstrchr @@ -314,6 +305,7 @@ #endif /* These functions are defined in wfdbio.c */ +extern int wfdb_fclose(WFDB_FILE *fp); extern WFDB_FILE *wfdb_open(char *file_type, char *record, int mode); extern int wfdb_checkname(char *name, char *description); extern int wfdb_g16(WFDB_FILE *fp); @@ -323,10 +315,25 @@ extern int wfdb_parse_path(char *wfdb_path); extern void wfdb_addtopath(char *pathname); extern void wfdb_error(char *format_string, ...); -extern WFDB_FILE* wfdb_fopen(char *fname, const char *mode); +extern WFDB_FILE *wfdb_fopen(char *fname, const char *mode); extern int wfdb_fprintf(WFDB_FILE *fp, const char *format, ...); extern void wfdb_setirec(char *record_name); +#if WFDB_NETFILES +extern void wfdb_clearerr(WFDB_FILE *fp); +extern int wfdb_feof(WFDB_FILE *fp); +extern int wfdb_ferror(WFDB_FILE *fp); +extern int wfdb_fflush(WFDB_FILE *fp); +extern char *wfdb_fgets(char *s, int size, WFDB_FILE *fp); +extern size_t wfdb_fread(void *ptr, size_t size, size_t nmemb, WFDB_FILE *fp); +extern int wfdb_fseek(WFDB_FILE *fp, long offset, int whence); +extern long wfdb_ftell(WFDB_FILE *fp); +extern size_t wfdb_fwrite(void *ptr, size_t size, size_t nmemb, WFDB_FILE *fp); +extern int wfdb_getc(WFDB_FILE *fp); +extern int wfdb_putc(int c, WFDB_FILE *fp); +extern void wfdb_wwwquit(void); +#endif + /* These functions are defined in signal.c */ extern void wfdb_sigclose(void); extern void wfdb_osflush(void); @@ -347,6 +354,15 @@ extern void wfdb_p16(), wfdb_p32(), wfdb_addtopath(), wfdb_error(), wfdb_setirec(), wfdb_sigclose(), wfdb_anclose(), wfdb_osflush(), wfdb_oaflush(); + +# if WFDB_NETFILES +extern char *wfdb_fgets(); +extern int wfdb_feof(), wfdb_ferror(), wfdb_fflush(), wfdb_fseek(), + wfdb_getc(), wfdb_putc(); +extern long wfdb_ftell(); +extern size_t wfdb_fread(), wfdb_fwrite(); +extern void wfdb_clearerr(), wfdb_wwwquit(); +# endif /* Some non-ANSI C libraries (e.g., version 7, BSD 4.2) lack an implementation of strtok(); define NOSTRTOK to compile the portable version in wfdbio.c. */ diff -Naur wfdb-10.2.5/psd/Makefile wfdb-10.2.6/psd/Makefile --- wfdb-10.2.5/psd/Makefile Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/psd/Makefile Mon Jun 24 22:43:07 2002 @@ -32,12 +32,12 @@ # directory). # _____________________________________________________________________________ # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables @@ -45,7 +45,7 @@ VDEFS = -DWFDB_MAJOR=$(MAJOR) -DWFDB_MINOR=$(MINOR) -DWFDB_RELEASE=$(RELEASE) # _____________________________________________________________________________ -PACKAGE=wfdb-10.2.5 +PACKAGE=wfdb-10.2.6 # file: linux.def G. Moody 31 May 2000 # Last revised: 17 December 2001 # 'make' definitions for compiling the WFDB Software Package under Linux diff -Naur wfdb-10.2.5/wave/Makefile wfdb-10.2.6/wave/Makefile --- wfdb-10.2.5/wave/Makefile Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/wave/Makefile Mon Jun 24 22:43:07 2002 @@ -45,12 +45,12 @@ # just type `make' (from within this directory). # _____________________________________________________________________________ # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables @@ -58,7 +58,7 @@ VDEFS = -DWFDB_MAJOR=$(MAJOR) -DWFDB_MINOR=$(MINOR) -DWFDB_RELEASE=$(RELEASE) # _____________________________________________________________________________ -PACKAGE=wfdb-10.2.5 +PACKAGE=wfdb-10.2.6 # file: linux.def G. Moody 31 May 2000 # Last revised: 17 December 2001 # 'make' definitions for compiling the WFDB Software Package under Linux @@ -180,8 +180,8 @@ lib-post-uninstall: echo "Nothing to be done for lib-post-uninstall" # _____________________________________________________________________________ -# file: Makefile.tpl G. Moody 31 May 2000 -# Last revised: 13 October 2001 +# file: Makefile.tpl G. Moody 31 May 2000 +# Last revised: 24 June 2002 # Change the settings below as appropriate for your setup. # WAVEVERSION is the WAVE version number. @@ -253,7 +253,7 @@ grid.c sig.c annot.c analyze.c scope.c search.c xvwave.c help.c OFILES = wave.o init.o mainpan.o modepan.o helppan.o logpan.o annpan.o edit.o \ grid.o sig.o annot.o analyze.o scope.o search.o xvwave.o $(HELPOBJ) -HELPFILES = analysis.hlp buttons.hlp editing.hlp faq.hlp intro.hlp log.hlp \ +HELPFILES = analysis.hlp buttons.hlp editing.hlp intro.hlp log.hlp \ printing.hlp resource.hlp OTHERFILES = wave.hl0 wave.info wave.pro demo.txt Wave.res wavemenu.def \ Makefile diff -Naur wfdb-10.2.5/wave/Makefile.tpl wfdb-10.2.6/wave/Makefile.tpl --- wfdb-10.2.5/wave/Makefile.tpl Thu Dec 13 12:56:01 2001 +++ wfdb-10.2.6/wave/Makefile.tpl Mon Jun 24 22:42:38 2002 @@ -1,5 +1,5 @@ -# file: Makefile.tpl G. Moody 31 May 2000 -# Last revised: 13 October 2001 +# file: Makefile.tpl G. Moody 31 May 2000 +# Last revised: 24 June 2002 # Change the settings below as appropriate for your setup. # WAVEVERSION is the WAVE version number. @@ -71,7 +71,7 @@ grid.c sig.c annot.c analyze.c scope.c search.c xvwave.c help.c OFILES = wave.o init.o mainpan.o modepan.o helppan.o logpan.o annpan.o edit.o \ grid.o sig.o annot.o analyze.o scope.o search.o xvwave.o $(HELPOBJ) -HELPFILES = analysis.hlp buttons.hlp editing.hlp faq.hlp intro.hlp log.hlp \ +HELPFILES = analysis.hlp buttons.hlp editing.hlp intro.hlp log.hlp \ printing.hlp resource.hlp OTHERFILES = wave.hl0 wave.info wave.pro demo.txt Wave.res wavemenu.def \ Makefile diff -Naur wfdb-10.2.5/wave/faq.hlp wfdb-10.2.6/wave/faq.hlp --- wfdb-10.2.5/wave/faq.hlp Fri Nov 16 15:54:48 2001 +++ wfdb-10.2.6/wave/faq.hlp Wed Dec 31 19:00:00 1969 @@ -1,1106 +0,0 @@ -This is the WAVE FAQ (frequently asked questions) list. It was last revised on -16 November 2001 (recent changes are marked with `*' below). - -Hardware questions: - . Can I use WAVE if I don't run Linux or another Unix? - . How can I use WAVE from an X terminal, PC, Mac, etc.? - . Can I run WAVE remotely using a modem? - . How can I insert annotations using a two-button mouse? - . How do I get spot help if I don't have a `Help' key? -Problems starting WAVE: - . Why won't WAVE run? - . Why does WAVE take so long to display the first screen? - . Where do I find the missing fonts? -Display-related questions: - . I can't see the signals! - . I can't see text in the signal window! - . WAVE doesn't draw/erase properly in the scope window! - . How can I get correct display scales? - . Why are signals too big or too small? - . How can I change WAVE's default scales or display colors? - . Why do colors in other windows change when I use WAVE? - . Everything in the Analysis Commands window appears twice! -File-related questions: - . I can't find the file named `RECORD'! - . Why does WAVE tell me `Record ... is unavailable'? - . How can I view a record stored on a web site or an FTP server? -Questions about editing: - . Where are my annotations? - . Why does WAVE tell me `You may not edit annotations ...'? - . How do I edit a record on a CD-ROM, a web site, or an FTP server? - . How can I undo an edit? - . Can I define my own annotations? - . How can I recover work after a crash? - . Can I edit annotations with a text editor? - . What are `link' annotations? - . Can WAVE edit signal files? -What else can WAVE do? - . How can I make a screen dump? - . Can WAVE read digitized signals in (fill in the blank) format? - . What is ``high-resolution'' mode? - . Can WAVE open more than one record at once? - . Can WAVE open more than 32 signals at once? - . Can WAVE open more than one annotation file at once? - . Can WAVE do smooth scrolling? - . Can WAVE be used for real-time display of data being acquired? - . Can WAVE scroll through a record without user intervention? - . How can I use WAVE's menu variables in a script or other program? - . Is there a Motif version of WAVE? - . How can I find out about ...? - -If your question is not on this list, and you think it should be, please -send it to me (george@hstbme.mit.edu)! - - -Hardware questions -================== - -Can I use WAVE if I don't run Linux or another Unix? ----------------------------------------------------- - -Why would you not want to run Linux or Unix? Any version of Linux or Unix is a -much better choice for research than any version of MS-Windows. See -http://www.dyncorp-is.com/darpa/meetings/win98aug/wars.html for an independent -perspective on this issue. Linux can coexist on the same PC with MS-Windows if -necessary. - -The major obstacle to porting WAVE to other platforms is that the XView -toolkit is needed for the user interface components of WAVE. XView is free -software and can be ported to other platforms, but this task is not trivial. - -Another possibility is to reimplement WAVE's user interface with a different -toolkit. The GTKWave project is doing just that, using the Gimp toolkit -(GTK+), which runs not only under Linux and Unix, but also under MS-Windows. -Beta-quality versions of GTKWave for Linux and for MS-Windows are currently -available from PhysioNet (search for GTKWave for further information). - -If you have any networked computer that can run X11R4 or a later version -(this includes all current UNIX workstations, PCs, Macintoshes, and a variety -of other systems), and access via network to another computer that can host -WAVE (see above), you can run WAVE remotely (see the next question). - -Other WFDB applications (WVIEW for Microsoft Windows, VIEW for MS-DOS, MacView -for the Macintosh, and pschart and psfd for PostScript devices) offer many of -the display features of WAVE in other environments; none of these currently -support annotation editing or control of external programs, however. - - -How can I use WAVE from an X terminal/PC/Mac/etc? -------------------------------------------------- - -As with any X application, you can use an X terminal or any system equipped -with an X server to interact with a copy of WAVE running on another computer -connected to the same network. To do so, however, requires a few additional -steps: - - - Find out the host names of the two systems. On a UNIX system, the - `hostname' command will give you this information. If your display is - connected to a PC or other non-UNIX system, you can try remotely logging - onto the UNIX system on which WAVE resides, and using the `who' command - to discover the name of the system in front of you. - - Assume that your system is named HITHER and that WAVE resides on YON. - You may need to add YON to the X server access control list on HITHER, - in order to make it possible for X clients on YON to open windows on your - screen. If HITHER is a UNIX system, you can accomplish this by typing - (on HITHER) `xhost +YON'. - - Remotely log in to YON (for example, via ssh or telnet), and set the DISPLAY - environment variable on YON to point back to your display. If you use the - C-shell on YON, this will normally be done by `setenv DISPLAY HITHER:0.0'. - Bourne shell, Korn shell, and `bash' users should type `DISPLAY=HITHER:0.0; - export DISPLAY'. - - Check the connection by starting an X11 client such as `xterm' on YON. A - new window should appear on your display within a few seconds. (See the - documentation for your X server if this doesn't work). - - Once you have succeeded in the test in the previous step, start WAVE in the - usual way (`wave -r RECORD ...') on YON. See `Where do I find the missing - fonts?' (below) if your X server complains about missing fonts. See `I - can't find the file named `RECORD'!' (below) if WAVE complains about missing - files. - -X servers are standard on all current UNIX workstations, but not on PCs or -Macintoshes. There are many MS Windows-hosted X servers available -commercially, as well as a smaller number of MS-DOS and Macintosh-hosted X -servers. - - -Can I run WAVE remotely using a modem? --------------------------------------- - -It is possible, with appropriate (SLIP or PPP) software, to run WAVE -across a serial connection, but this will be painfully slow even with a 28.8 -kbps modem. Using WAVE remotely via Ethernet is usually quite tolerable, -however. - - -How can I insert annotations using a two-button mouse? ------------------------------------------------------- - -Normally, the middle button is used to insert annotations, so the problem is to -simulate a middle button click if you don't have a middle button. Most, if not -all, X servers that support two-button mice provide a way to do this. The most -common method is to press both buttons simultaneously (an operation sometimes -called ``chording,'' by analogy with playing a chord on the piano). Typically, -you have an adjustable window of 50 to 100 milliseconds in which to press both -buttons, so that you don't need exactly simultaneous clicks (which would be -impossible to achieve reliably). Some X servers delay reporting a button-down -event until a button-up event occurs; this approach makes chording less -error-prone, but it means that the feedback that WAVE produces in response to -button-down events gets delayed until it may no longer be useful. Another -approach, more commonly used with one-button mice, is to simulate the middle -button (and, if necessary, the right button) using a mouse button and keyboard -key combination, such as clicking while pressing the Shift or Ctrl keys. Check -your X server's manuals for information about which of these methods is -supported. With a little practice, annotation editing can be tolerable with a -button-impaired mouse. - -Independent of the X server, WAVE also makes it possible to simulate a middle -button click, by using the F2 key (or the `5' key on the numeric keypad). If -you use this technique, you might also wish to use the F3 and F4 keys to drag -the pointer and marker bars left or right. - -Inexpensive three-button mice, trackballs, and touchpads manufactured by -Logitech and many others are widely available for PCs, and are highly -recommended if you do much annotation editing. Most are fully compatible with -Microsoft two-button mice and with X server software for PCs. Some users prefer -trackballs for precision editing since there is no tendency for the pointer to -move when clicking the buttons, as with a mouse. - - -How do I get spot help if I don't have a `Help' key? ----------------------------------------------------- - -If you are not using WAVE with a Sun keyboard, use the F1 key to open XView -spot help for WAVE. If this doesn't work, you may need to use the `xmodmap' -utility (a standard component of X11, usually found in the same directory -as other X clients such as `xterm'). Try the following command: - xmodmap -e "keysym F1 = Help" -If this command fixes the problem, you may wish to include it in your -`.xinitrc' (a text file in your home directory; create it if it doesn't -exist) so that spot help via F1 is enabled whenever you log in. - -If you are not using olwm or olvwm, spot help may not work properly; in -particular, your window manager may pass incorrect information about which -window is active when you invoke spot help. There is no general solution -to this problem; try using olvwm or olwm, at least until you are familiar -with WAVE's controls. - - -Problems starting WAVE -====================== - -Why won't WAVE run? -------------------- - -Here are a few things to check: - -1. The command used to run WAVE must be typed in lower case, as in: - wave -r 100s -a atr - Note that letters in record names and annotator names are also usually in - lower case. - -2. Try typing `wave' with no command-line arguments. You should see a summary - of options. If you don't, `wave' has not been installed properly, is not - in your PATH, or another program named `wave' is in your PATH. - - Errors similar to - wave: can't load library 'libxview.so.3' - indicate an installation problem which is probably shared by other - applications that use the same libraries. Use the command - ldd `which wave` - to identify which dynamically linked libraries are missing. Locate these - on your system (for example, using a command such as - find / -name libxview.so.3 -print - If any of these libraries cannot be found on your system, it may be - downloaded from http://www.physionet.org/. Add the directories in which the - missing libraries are found to your LD_LIBRARY_PATH. For example, if the - missing libraries are located in /usr/openwin/lib, and you are using the - C-shell, use the command - setenv LD_LIBRARY_PATH /usr/openwin/lib:${LD_LIBRARY_PATH} - Under Linux, if you can obtain root permissions, a more permanent - solution is to add /usr/openwin/lib to the list of directories - in /etc/ld.so.conf, and then to run `ldconfig'. - -3. If the previous test works, try typing `wave -r 100s -a atr'. (All WAVE - distributions come with record 100s.) One of the following should happen: - * If you see a summary of options, rather than the WAVE main window, read - the message carefully; you may not have set the DISPLAY or WFDB - environment variables, or the X server may not be running. - * If you see a lengthy error message referring to missing fonts, see `Where - do I find the missing fonts?' below. - * If you see neither a summary of options nor the WAVE main window, the - DISPLAY environment variable may be set incorrectly, the X server may be - refusing permission to open a window, or your window manager may be waiting - for you to specify the location or size of the window to be opened. - * If you see only a message box reading `Record 100s is unavailable', your - WFDB environment variable may be set incorrectly; in this case, find the - directory (probably /usr/local/database) containing a file named `100s.hea' - and append the name of that directory to the value of WFDB. - * If WAVE's signal window appears, but is solid white, your X server has a - bug. Click on any of the navigation controls (e.g., `<<', `<', `>', or - `>>'), or resize the window, to make the signals appear. - * If the signals appear, but there are no annotations or time stamps in the - signal window, your X server has a (different) bug. Restart `wave', adding - the `-S' option to the end of the `wave' command. Also see `I can't see - text in the signal window!' below. - * If you see a correct display, your problem is specific to the record you - were previously trying to view. Find the directory containing the header - file (`RECORD.hea', where RECORD is the record name) for the desired - record, and append the name of that directory to the value of WFDB. - -Why does WAVE take so long to display the first screen? -------------------------------------------------------- - -If you are running WAVE remotely, a slow network connection may be the -reason for sluggish performance. If possible, run WAVE locally, or get -a faster network connection. You might also try changing the time scale -so that fewer points need to be drawn on each screen. - -If you are using WAVE to view a record via FTP, it is currently not possible -to begin until the entire record has been downloaded; for long records over -slow network connections, this can take a long time. Some web (HTTP) servers -suffer from the same limitation. If possible, use a web server that supports -HTTP range requests, such as Apache, or download a copy of the record to your -local disk. - - -Where do I find the missing fonts? ----------------------------------- - -WAVE is an XView application, and requires the Open Look cursor font on the -server. If your server doesn't have this font (`olcursor.snf' for X11R4 and -earlier servers, `olcursor.pcf' for X11R5 and later servers), you must -install it before WAVE will run. XView applications also use the `olgl??.snf' -or `olgl??.pcf' glyph fonts; if these are missing, WAVE will run but certain -standard Open Look graphical elements will not have the correct appearance. To -install these fonts on your X server's system: - - generate copies of `ol*.snf' or `ol*.pcf' for your X server system's - architecture; - - copy `ol*.snf' or `ol*.pcf' to a world-readable directory on the server - machine; - - update the font database on the server machine; and - - force the server to reread the font database. -You should be able to find `ol*.snf' or `ol*.pcf' files on the machine on which -WAVE resides (probably in /usr/lib/X11/fonts/misc). The `ol*.pcf' files are -portable (although usually optimized for the architecture of the system on -which they are installed). If you need to use `snf' fonts, however, and the -server machine is not of the same architecture, it will be necessary to find -`ol*.bdf' in the XView distribution and use `bdftosnf' to generate `.snf' files -for your X server system's architecture (see the man page for `bdftosnf'; this -step can be done trivially on the server machine, if `bdftosnf' is available -there, or with a little more trouble on the remote machine). If the server -machine runs UNIX, read the man pages for `mkfontdir' and `xset' to see how to -update and reread the font database; otherwise, consult the documentation for -your X server. Note that (under UNIX) you do not need to have write permission -in the standard font directory in order to perform these steps; if you add your -own font directory to the font path using `xset', however, remember that this -setting lasts only until the server exits and will need to be repeated -afterwards. - - -Display-related questions -========================= - -I can't see the signals! ------------------------- - -If the signal window is solid white, your X server has a bug. Click on any of -the navigation controls (e.g., `<<', `<', `>', or `>>'), or resize the window, -to make the signals appear. - -If the signal window is solid or nearly solid blue (black if you have a -monochrome or greyscale display), the signals are too big. WAVE may be -attempting to display signals that fill the entire window. In rare cases, -noise in the signals themselves can produce this effect. More common causes -include incorrect signal format or gain specifications in the header file for -the record you have opened, incorrect display calibration, or a choice of -amplitude scale that results in excessive vertical range of one or more -signals. This effect can also occur as a result of various problems related -to the WFDB calibration file, for example, if the WFDBCAL environment variable -does not name an accessible WFDB calibration file (type `man wfdbcal' for -details), if any of the signals in the record are of types not listed in the -WFDB calibration file, or if the WFDB calibration file does not contain -appropriate default display scales for all of the signal types in the record. -See the next several questions for suggestions on correcting these problems. - -If the signal window contains horizontal lines (in blue if you have a color -display) where the signals should appear, the signals are too small. In this -case, the signal gains specified in the header file may be incorrect, the -display calibration may be incorrect, or you may have specified an amplitude -scale that reduces the vertical range of the signals to zero. Click on -`View...' to check the scales, and adjust them if necessary. - -If the signal window contains time indicators in the lower corners, look for -the signal names along the left edge of the window. If there are no signal -names visible, click on `View...', then on `signal names' and `Redraw' in the -View panel. If signal names still do not appear, either the header file or -the signal file for the record you have opened may be inaccessible. Find these -files (see `File-related questions', below), add the directory that contains -them to your WFDB path, and try to read a few samples using - rdsamp -r RECORD -t 1 -If this fails, examine the header file for the record (a text file), and be -sure that it specifies at least one signal in an accessible signal file. - - -I can't see text in the signal window! --------------------------------------- - -This may result from an X server bug. This bug appears to be limited to X -servers that support `true color' (typically 24-bit) displays, when using -overlay graphics. Restart `wave', adding the `-S' option to the end of the -`wave' command. - -This problem may also occur on 8-bit `pseudo-color' displays, if another -application such as Netscape has already allocated most of the color map. To -avoid this problem, start `wave' before starting Netscape. - - -WAVE doesn't draw/erase properly in the scope window! ------------------------------------------------------ - -This problem may result from several different X server bugs. You may be -able to avoid it by switching from overlay graphics mode (the usual default) to -shared color mode (selected using WAVE's `-S' command-line option), or vice -versa, since WAVE uses different techniques for drawing in the scope window -depending on the display mode. - -A bug in network file handling can sometimes interfere with correct display -of waveforms in the scope window when reading records via HTTP. For now, -the only workarounds are to restart WAVE, or to copy the record to local -disk files (this can be done easily using `xform', `snip', or a web browser). -Check http://www.physionet.org/ for updates to WAVE or to the WFDB library -that may correct this bug. - - -How can I get correct display scales? -------------------------------------- - -Use `xdpyinfo' (a standard X client that is provided as part of the X core -distribution) to check several server parameters. (As with virtually all X -clients, it doesn't matter which machine you find `xdpyinfo' on; it will query -your server from wherever it is run.) `xdpyinfo' will report the version and -release numbers of your server; you should have version 11, release 3 or later. -It will also report the screen size in pixels and the resolution in pixels per -inch. Take a minute to verify the screen resolution by direct measurement of -the screen with a ruler. If the resolution reported by `xdpyinfo' is -incorrect, WAVE will not be able to draw waveforms at properly calibrated -scales. The sample X11 servers from MIT and the X Consortium, and the XFree86 -project's X11 servers, all support a `-dpi' option, which allows you to specify -the correct screen resolution at the time the server is started; read the man -page for X or Xserver for details. (If your server does not support this -feature, WAVE can be given a similar `-dpi' option; see Options, above.) - -You can also double-check your display calibration using WAVE itself. Run -WAVE, enable the grid display, and set the display scales to their default -values (25 mm/sec, 10 mm/mV). (Click on `View...' to pop up the controls for -the grid and the display scales; remember that any adjustments you make become -effective only after you click on `Redraw' within the View panel.) The grid -intervals should measure exactly 5 mm in each direction. If they are too -small, use a larger value for the `-dpi' specification; if the grid lines are -more than 5 mm apart, decrease the `-dpi' values. - - -Why are signals too big or too small? -------------------------------------- - -There are several reasons why the size of signals may be incorrect. WAVE -determines display scales for signals based on several parameters: - - First, the WFDBCAL environment variable specifies the name of a text file - (located in a directory in the WFDB path) containing the names of many - common signals and customary display scales for each (expressed as physical - units per centimeter). For example, ECG signals are customarily displayed - at a scale of 1 mV per centimeter. If a signal appears at an - inappropriately large or small scale, its name may be missing from the - WFDBCAL file, the WFDBCAL variable may not correctly specify the name of - the WFDBCAL file, or the WFDBCAL file may not reside in a directory in the - WFDB path. On most systems, the WFDBCAL file is - `/usr/local/database/wfdbcal', and the WFDBCAL environment variable is set - by the same command used to set the WFDB path (see above). Instructions - for adding additional signal names and scales to the WFDBCAL file are - located within the WFDBCAL file, and may also be found in the WFDB - Applications Guide. - - Second, the header file for the record specifies the gain for each signal - (the number of analog-to-digital units per physical unit). If the gain has - not been determined, or is incorrect, the size of the signal as drawn by - WAVE may be incorrect as well. If you know the physical values that - correspond to at least two levels represented in the signal (for example, - the top and bottom of a calibration pulse), you can use the `calsig' - application to determine the gain and to rewrite the header file. See the - WFDB Applications Guide for details. `calsig' can be most conveniently run - from WAVE's Analysis panel. - - Finally, the display calibration determines the number of pixels per inch - (25.4 mm). WAVE usually gets its information about the display calibration - from the X server, but the X server may not supply the correct information. - See `How can I get correct display scales' (above) for details on diagnosing - and correcting this problem. - - -How can I change WAVE's default scales or display colors? ---------------------------------------------------------- - -The easiest way to make simple changes in WAVE's default display parameters is -by using the controls in the View panel to configure the display to your -liking. If you then click on `Save as new defaults' in the View panel, your -choices are recorded in your `.Xdefaults' file (in your home directory) and -will be used for future WAVE sessions. (Be sure that you have made your -changes effective by using `Redraw' before `Save as new defaults'.) - -Colors are also determined by X resources that may be specified in your -`.Xdefaults' file, but the View panel does not include color controls. See the -`Resources' topic in WAVE's on-line help, or type `man wave', for guidance on -setting display colors. - - -Why do colors in other windows change when I use WAVE? ------------------------------------------------------- - -WAVE queries the X server to determine how many colors it can display, and -what methods it can use to do so. If the X server does not answer this query -correctly, WAVE may attempt to use a suboptimal or unavailable display mode. -If you find that the colors of other windows change when the cursor moves into -a WAVE window, you may prefer to use the `-S' option to avoid this behavior at -a slight (often unnoticeable) cost in speed. - - -Everything in the Analysis Commands window appears twice! ---------------------------------------------------------- - -This problem, which may occur when you are running WAVE under Linux, appears to -result from a bug in an early Linux version of the XView `termsw' package. -Type the command `stty -echo' in the Analysis Commands window, and the problem -should go away. - - -File-related questions -====================== - -I can't find the file named `RECORD'! -------------------------------------- - -Record names are NOT file names; they are components of file names only. For -example, three files belong to record 100s: 100s.hea, 100s.dat, and 100s.atr. -There is no file named `100s' belonging to the database. See the WFDB -Applications Guide, section 5, for information about file types and formats. - - -Why does WAVE tell me `Record ... is unavailable'? --------------------------------------------------- - -In common with other WFDB applications, WAVE searches for its input signals and -annotations in directories named by the WFDB environment variable (see the -discussion of the WFDB path in the WFDB Programmer's Guide). If WAVE is -running remotely, remember to set WFDB on the WAVE host (a default can usually -be set for C-shell users by `source /usr/local/bin/cshsetwfdb', or for Bourne -shell, Korn shell, and `bash' users by `. setwfdb'; don't omit the `.'). The -directories named by WFDB are those on the WAVE host; thus (unless your WFDB -files are already on the WAVE host, or are accessible to the WAVE host via -HTTP or FTP -- see the next question) you must either transfer them to the -remote machine, or NFS- or RFS-mount the directory in which they reside onto a -suitable point in the file system of the WAVE host. Furthermore, remember that -output annotation, log, and print files will be written to your current -directory on the WAVE host. - -To get the pathname of a WFDB file, use `wfdbwhich' (type `man wfdbwhich' for -details). For example, the output of `wfdbwhich header 100s' is the pathname -of the header file for record 100s (usually `/usr/local/database/100s.hea'). -If `wfdbwhich' can't find the file, neither can WAVE (or any other WFDB -application). In this case, you will need to check and correct the value of -the WFDB environment variable. In unusual cases, the WFDB path may be correct, -but you may not have permission to read the file or one of the directories in -the path to the file; in such cases, you will need to get the file's owner or -your system administrator to give you appropriate permissions. - - -How can I view a record stored on a web site or an FTP server? --------------------------------------------------------------- - -Add the directory containing the record to your WFDB path, then use WAVE just -as you would to view a record stored on your local disk. For example, suppose -the WFDB path is: - . /usr/local/database http://www.signals.r.us/data ftp://sand.bar.com/pub -In this case, WAVE would look for input files first in the current directory -(.) of the local disk, then in /usr/local/database (which might be local or -might be part of a networked file system), then on the signals.r.us web site, -and finally on sand.bar.com's FTP server. Unless you have a slow network -connection, you may not notice any difference between viewing locally and -remotely stored records. - -Questions about editing -======================= - -Where are my annotations? -------------------------- - -When you create a new set of annotations, if you have specified the annotator -name in the Load window, WAVE saves your annotations in a new file with a name -of the form RECORD.ANNOTATOR, in the current directory. When you edit an -existing set of annotations, WAVE makes a copy of the annotation file -containing your edits, gives it a name of the form RECORD.ANNOTATOR, and saves -it in the current directory (i.e., whatever directory was current when you -started WAVE). To be able to read your annotations in a later WAVE session, be -sure that the directory that contains your edited copy is listed in your WFDB -path *before* any other directory that contains an older version of the same -annotation file. Usually, your WFDB path begins with `.', a synonym for the -current directory. If this is the case, simply return to the directory that -contains your edited annotation file before starting WAVE each time. - -If you created an annotation file without specifying an annotator name, -WAVE uses its own name as the annotator name, so you should look for a file -named `RECORD.wave' in this case. - -Old versions of WAVE created annotation files with names of the form -ANNOTATOR.RECORD; if you have any of these, rename them in order to continue -using them with WAVE. - - -Why does WAVE tell me `You may not edit annotations ...'? ---------------------------------------------------------- - -Since WAVE is often used to *view* annotated data, without necessarily editing -annotations, annotation editing is disabled when WAVE starts. If you have -inadvertently done something (such as clicking the middle mouse button in the -signal window) that WAVE interprets as an editing command, it will warn you -that the editing action is disabled. - -If you did intend to edit the annotations, select `Allow editing' from the -`Edit' menu, then repeat the edit. - - -How do I edit a record on a CD-ROM, a web site, or an FTP server? ------------------------------------------------------------------ - -Be sure that your current directory is writable, that both your current -directory and the source (CD-ROM, web, or FTP) directory containing the record -you wish to edit are in your WFDB path, and that your current directory comes -*before* the source directory in your WFDB path. When WAVE writes your edits, -they always go into the current directory (so the current directory cannot be -on a CD-ROM, since a CD-ROM is not writable). At a later time, when WAVE (or -any other WFDB application) opens the record, it finds your edited version -first, and doesn't look for the original version, provided only that, in your -WFDB path, the source directory follows the one in which your edits are stored. - - -How can I undo an edit? ------------------------ - -WAVE doesn't support a general mechanism for `undoing' edits. Once you move an -annotation or change its attributes, you must manually restore its position and -attributes. Deleted annotations can always be restored, however, by selecting -the `phantom' annotation left behind (these are displayed with a `.' for the -annotation mnemonic) and then `deleting' the phantom. This action restores the -attributes of the original annotation, including the subtype, chan, num, and -aux fields; if the annotation was moved, however, its original position (time -field) is not restored. - -WAVE is careful not to destroy the version of the annotation file that was -current at the time WAVE loaded the record. WAVE always saves edited -annotation files to the current directory (even if the original annotation -file was loaded from another directory). WAVE's saved annotation files are -given names of the form `RECORD.ANNOTATOR'. If, by saving its output, WAVE -would overwrite an existing file with the same name, WAVE first renames the -existing file by appending a tilde (`~') to its name. Thus it is always -possible to recover the state of the annotation file as it was before you -began the most recent editing pass. To do so, exit WAVE, and: - * If there is a file with a name of the form `RECORD.ANNOTATOR~' in the - current directory, rename it as `RECORD.ANNOTATOR'. - * Otherwise, delete or rename `RECORD.ANNOTATOR' so that the previous version - (which must be in another directory in the WFDB path) becomes visible once - again to WAVE. - - -Can I define my own annotations? --------------------------------- - -Yes. See the file named `anntab' in the WAVE distribution for examples. - - -How can I recover work after a crash? -------------------------------------- - -WAVE autosaves your edits at 1-minute intervals, or after every 20 insertions, -deletions, or attribute changes (repositioning doesn't count). You don't need -to do anything special to recover your work, but you may lose up to a minute's -worth of edits. - - -Can I edit annotations with a text editor? ------------------------------------------- - -Believe it or not, sometimes users ask this question. - -If you have unusual requirements (for example, if you want to change all -annotations of a certain type), you may be able to edit annotations more -efficiently using a text editor such as emacs. Since annotation files are not -text files, however, you will need to convert your files from binary to text -form to edit them, and then convert the edited text back to binary form in -order to use them further with WAVE. You can do this using rdann and wrann -(see rdann(1) and wrann(1), in the WFDB Applications Guide, for -details). - - -What are `link' annotations? ----------------------------- - -By analogy to hyperlinks in World Wide Web documents, link annotations allow -external data (including documents, images, and audio annotations among other -possibilities) to be associated with specific locations in a record. In fact, -any URL that can be understood by a supported web browser can be used to -specify the location of external data in a link annotation. Within the link -annotation, the URL appears as the first part of the aux string (in the Text -field of the Annotation Template). If the aux string contains any spaces, any -characters following the space are treated as a label to be displayed by WAVE -in place of the URL itself. - -Support for link annotations is a new feature of WAVE 6.0. To view the external -data associated with a link annotation, select the link and press Enter (or -Return). If your web browser is not already running, this may take a few -moments while WAVE starts it. If nothing happens after a minute or so, check -WAVE's Analysis Commands window for errors that may have occurred when WAVE -attempted to start your web browser. (WAVE uses Netscape 1.1 or any later -version by default. See WAVE and the Web for details on obtaining Netscape, or -on configuring WAVE to use a different web browser.) - -Link annotations may be moved, copied, attached to specific signals, inserted, -changed, and deleted just as for any other annotation. WAVE does not include -built-in facilities for editing the external data, however; other software such -as a text editor or a special-purpose HTML editor may be useful for this -purpose. - - -Can WAVE edit signal files? ---------------------------- - -WAVE itself doesn't do this, but certain kinds of signal file editing are easy -to do using snip from WAVE's Analyze panel. A common requirement is to remove -unwanted data from the beginning or end of a record. To do this, simply mark -the segment to be retained using the `<' and `>' markers, then click on -`Extract segment'. - -If your record contains unwanted signals, remove them from the Signal list -before extracting the segment. You can also rearrange the order of signals -within the signal list if you wish. - -Note that this operation does not modify the original record; rather, the -desired portions of the record are copied to create a new record. If you wish -to copy a set of annotations as well as data from signal files, be sure to load -the annotation file for the original record into WAVE before extracting the -segment. (See snip(1), in the WFDB Applications Guide, if you need to -copy two or more sets of annotations.) - -To join two or more records end-to-end, use wfdbcollate to create a -multi-segment record. wfdbcollate writes a special header file for the new -record, but does not copy or modify the signal or header files of the original -records; it will, however, write new annotation files on request, since the -WFDB library does not support multi-segment annotation sets. The records to be -joined must be ordinary (not multi-segment) records. If necessary, xform can be -used to rewrite a multi-segment record as an ordinary record. See -wfdbcollate(1), in the WFDB Applications Guide, for further information. - -More complex editing of signal files, such as splicing segments or modifying -individual samples, can be done by converting the signals to text form using -rdsamp (accessible from WAVE via the `List samples' button in the Analyze -window), editing the text as required, and converting the edited text to a -signal file using wrsamp (see wrsamp(1), in the WFDB Applications -Guide, for details). - -What else can WAVE do? -====================== - -How can I make a screen dump? ------------------------------ - -If you really want a screen dump, - xwd | xpr -will produce one in PostScript form. (Type `man xwd' and `man xpr' for details -on options.) Another way to do this, if xpr is not available, is - xwd | xwdtopnm | pnmdepth 255 | pnmtops -If your printer is not a PostScript printer, you can still print -the output of either of these commands using Ghostscript, a freely available -PostScript interpreter. - -Why settle for a screen dump, though? In most cases, you will prefer to use -`pschart' to produce a much nicer plot, and in much less time. Select `Print' -from WAVE's File menu to print the current contents of the signal window; use -the `Print chart' option on the Analyze panel if you wish to specify start and -stop times. Type `man pschart' or see the WFDB Applications Guide for -information about pschart's numerous formatting options; if you don't like -the defaults, change them by editing WAVE's menu file (this also allows you -to change the default format for the `Print' choice on the File menu; see -the comments in the menu file for details). - -If you are plotting a great deal of data, you may wish to use `psfd' rather -than `pschart'; to do so, select `Print full disclosure' rather than `Print -chart' on WAVE's Analyze panel. Most of pschart's options are accepted by -psfd. - -If you need to collect a set of figures, either from a single record or from -many records, use WAVE's Log panel to record the times of interest, and enter -captions for each figure in the Description field of the Log panel. The log -file generated in this way can be interpreted directly as a command file by -pschart, which prints the captions as titles for each figure. - - -Can WAVE read digitized signals in (fill in the blank) format? --------------------------------------------------------------- - -Probably it can. The most common formats for storage of digitized signals are -fixed-length binary formats that encode integer samples, and WAVE supports -dozens of such formats. WAVE does not require any embedded header information -within signal files (but it can be made to ignore such information). In most -cases, all you need to do is to write a header file that describes the format -in terms understandable to WAVE; once you have done so, any of the other WFDB -applications can also read your signals. Writing a header file can be most -easily done by copying an existing header file and modifying it using a text -editor. See signal(5) and header(5) in the WFDB Applications Guide for -details on supported signal formats and how to write a header file. - -There are at least three common ways of storing multiple signals: in separate -files, in multiplexed (sample-interleaved) files, and in block-interleaved -files. In a multiplexed file containing N signals, each set of N consecutive -samples contains one sample from each signal. In a block-interleaved file -containing N signals in blocks of 512 samples, for example, the first 512 -samples come from the first signal, the next 512 samples come from the second -signal, and so on. WAVE supports reading multiple signals from separate files -or from multiplexed files (or both in the same recording), but it does not -directly support block-interleaved files in general. - -WAVE does support reading a special type of file containing signals sampled at -different sampling frequencies. Files of this type contain "frames" of -samples. Each frame contains at least one sample of each signal, but there -may be two or more samples of signals sampled at multiples of the frame rate -within each frame. - -Block-interleaved files may be described simply as files with very large -frames. If you have a block-interleaved file, therefore, you may be able to -view it with WAVE via this expedient: - - * Write a header file describing the layout of the block-interleaved signal - file (see header(5), in the WFDB Applications Guide, for details). The - sampling frequency in the first line of the header should be given as the - frame rate (i.e., the basic sampling rate divided by the number of samples - per block), and the ``samples per frame'' field in each signal - specification line should be given as the number of samples per block. - * Open the record in ``high-resolution'' mode with WAVE (see ``What is - high-resolution mode?'', below). - -One significant limitation of this approach is that the time resolution of any -annotation files created in this way is limited to the frame interval. You can -avoid this limitation by reformatting the signal file (for example, by -following the steps above to verify that the signal file is properly readable, -then using xform with its own -H option; see xform(1) in the WFDB Applications -Guide. - -A common feature of many signal file formats is embedded header data: bytes at -the beginning of the signal file that do not contain digitized samples. By -specifying the length of the embedded header data as the byte offset for the -sample data in the (external) header file, such formats can be easily -accommodated; WAVE and any other applications built using the WFDB library -simply ignore any preamble. If the signal file format is documented, it is -usually not difficult to write a program to generate a header file based on -embedded header data. See header(5), in the WFDB Applications Guide, for -details on byte offsets. - -WAVE does not support directly reading signals stored in text files, because -there is no general method for computing the position within such files of -samples occuring at arbitrarily-chosen times. It is usually simple to convert -such text files into WAVE-compatible binary files using wrsamp(1), an -application supplied with WAVE. - -For the same reason, WAVE does not support directly reading signals stored -using variable-length encoding or non-uniform sampling intervals. If a -decompression utility is available, convert the data to fixed-length, uniform -samples. - -WAVE does not support any non-integer storage formats either, mainly because -such formats are not commonly used for digitized data. - -If you have signals in an unsupported format, you have two choices if you wish -to analyze them using WAVE: - - * Write a utility to convert your data to a supported format. This is usually - easy to do -- use `wrsamp.c' (the source for `wrsamp', provided with WAVE) - as a model. - * Add support for your format to the WFDB library, and recompile the shared - WFDB library. Once the new library is installed, WAVE and the other WFDB - applications will be able to use your format without recompilation. - If you have a large amount of data, this may be the only reasonable choice. - It may not be much more difficult than writing a conversion utility, - provided that your format permits computing file position as a function of - time. See the appendix titled `Extensions' in the WFDB Programmer's - Guide for hints on how to proceed. - -For example, WAVE does not support directly reading EDF, the European Data -Format first used for recordings of polysomnograms. (This is not the format -used for either the European ST-T Database or the MIT-BIH Polysomnographic -Database, both of which can be read directly by WAVE.) EDF uses block -interleaving, and also includes an embedded header. Although the method -outlined above for reading block-interleaved files can be used to read EDF -files, a difficulty in doing so is that the block size is specified within the -embedded header, and may vary between records. Moreover, since typical block -sizes are quite large, the time resolution of annotations in this case is very -coarse. A format converter for EDF files, edf2mit (available from PhysioNet, -http://www.physionet.org/), may be used to rewrite such files in a format that -WAVE can read without these limitations. This converter also constructs a -suitable header file from the embedded header in the EDF file. - -All currently supported signal formats use 16 bits per sample or less. In -principle, formats requiring up to 32 bits per sample should pose no problem -in environments that support WAVE, but formats requiring more than 16 bits may -be difficult to support in other environments. - - -What is ``high-resolution'' mode? ---------------------------------- - -Briefly, it is an alternative display mode for multi-frequency records only. -See the WFDB Programmer's Guide for details on multi-frequency -records. - -The -H option, introduced in WAVE 6.0, selects high-resolution mode. For -ordinary records (those for which all signals are sampled at the same -frequency), high-resolution mode is identical to standard mode. - -In a multi-frequency record, some signals are sampled at multiples of the basic -sampling rate. These are referred to as oversampled signals. In standard mode, -WAVE decimates these signals (i.e., WAVE reduces their sampling rates to the -basic sampling rate by averaging successive samples) before displaying them. In -high-resolution mode, however, WAVE displays each sample from any oversampled -signals if the screen resolution is high enough (note that at standard display -scales, it may be difficult to see the difference). In this mode, WAVE -replicates additional copies of each sample of any signals sampled at lower -rates before displaying them; in consequence, particularly at highly magnified -display scales, these signals may have a marked stairstep appearance. - -Note that the time resolution for placement of annotations is the same in -high-resolution mode and in standard mode. Thus, for example, it is not -possible to place annotations on consecutive samples of an oversampled -signal, since the second annotation will replace the first one. This is a -limitation of the WFDB library, not of WAVE itself, and may be removed in a -future release of the WFDB library. - - -Can WAVE open more than one record at once? -------------------------------------------- - -Yes. All records should be listed in one command-line argument, following -the -r argument on the command line; separate the record names by `+' -characters. For example, the command - - wave -r 237+237n & - -starts a WAVE process group, opening a separate WAVE signal window for -each of record 237 and record 237n. Each signal window corresponds to a -separate WAVE process; thus you may browse through and edit each record -independently. The signal window assigned to the last record in the group (in -this case, 237n) is the master signal window; it contains a `Sync' button, -which may be used to synchronize the other signal windows with the master -at any time. By synchronizing, we mean that the other windows are redrawn -as necessary so that the times shown in their lower left corners match that -shown in the master signal window. - -Remote-control applications such as wavescript and wave-remote can also -start or control a WAVE process group. All signal windows in the group move -synchronously in response to commands from wavescript or wave-remote. -You may change the record that is open in any signal window, either via the -Load window or using a remote-control application. You may quit from any -signal window without affecting the others. - -Note that there are a few important limitations: - - * The number of signal windows (WAVE processes) in any process group - cannot be increased once the process group has been created. - * Although you may run two or more WAVE process groups - simultaneously, applications such as wavescript can control only a - single process group at a time (by default, the last one started). - * Although you may have the same record open in more than one signal - window, you should not edit the same annotator of the record in more - than one window at a time (just as you should not edit the same text file - in more than one editor window at once). You may edit different - annotators of the same record freely. - -Taken together, the first two of these points imply that if you decide after -opening a record that you would like to add another record to the group, it -will be necessary to exit and start again, naming all desired records in the -group on the WAVE command line when you do so. - -If you wish to move through two records sampled at the same sampling frequency -in lockstep (for example, to view digitally filtered signals and the original -unfiltered signals side-by-side), another approach is to create a single header -file that names the signal files for both records. It is not necessary for all -signals to be in the same signal file, or even on the same disk drive. In this -case, however, the total number of open signals must be 32 or less (see the -next question). - - -Can WAVE open more than 32 signals at once? -------------------------------------------- - -Yes. There is no fixed limit on the number of signals that current versions -of WAVE can open. Earlier versions were limited to 32 or fewer signals. - - -Can WAVE open more than one annotation file at once? ----------------------------------------------------- - -No. In most cases, however, it's not really necessary to do so. - -For example, if you want to compare two sets of annotations of the same data in -order to study their differences, use `bxb' with the `-o' option to prepare a -comparison annotation file, and then use WAVE to open that file. (Type `man -bxb' or see the WFDB Applications Guide for details.) If your goal is to find -discrepancies, this is by far the best way to do so; `bxb' produces a -statistical summary of them, and you can search for NOTE annotations to find -each disagreement (enter `"' in the `Search for' field of WAVE's Find panel). - -If you want to annotate multiple signals independently (for example, ECG and -respiration), set `Show annotations' to `attached to signals' in WAVE's View -window. See `Multi-edit mode' under the `Editing' topic in WAVE's on-line -help for details. - -If you already have multiple independent annotation files for a single record -(whether these contain annotations for independent signals or annotations -for disjoint segments of the record), you can use mrgann to merge them into a -single file, preserving information about which file each annotation came -from if you wish (see mrgann, in the WFDB Applications Guide, for -details). - -`wfdbcollate' can also be used for this purpose if you have separate annotation -files for each segment of a multi-segment record. - - -Can WAVE do smooth scrolling? ------------------------------ - -No. - - -Can WAVE be used for real-time display of data being acquired? --------------------------------------------------------------- - -Not easily. If you have a UNIX application that can write data in a format -readable by WAVE, it should be possible in principle to run it from WAVE's -Analyze panel, and to use WAVE to review the data being acquired, using the -`Reload' button on WAVE's Analyze panel to read additional samples as they -become available. (WAVE will not attempt to read beyond what it thinks is -the end of the record; if it ever catches up with the digitizing process, -therefore, WAVE can only be forced to read further by using the `Reload' -button, or by closing and reopening the record.) - - -Can WAVE scroll through a record without user intervention? ------------------------------------------------------------ - -Yes. Create a log file that contains entries spaced at the desired intervals -throughout the record. A suitable interval might be 10 seconds if that is the -width of the signal window, or half of that amount. Open the log panel, load -the log file, and click on `>>' to start the scrolling. Adjust the delay -between frames using the slider on the log panel. - -Another way to review a record is via the scope window (accessible by clicking -on `Show scope window' on WAVE's Analyze panel). Note that the scope display, -since it is triggered by annotations, is of no use in detecting erroneously -unannotated waveforms (false negatives), since such waveforms are simply not -displayed in the scope window. The scope is useful for studying morphologic -variation of waveforms, and for locating erroneously annotated waveforms (false -positives). - - -How can I use WAVE's menu variables in a script or other program? ------------------------------------------------------------------ - -See WAVE's default menu file for examples of passing WAVE's menu variables -as command-line arguments to other programs. - -Click on `Export variables' in WAVE's analyze menu if you need to use these -variables within a shell script. (If you are not using bash, ksh, or sh, edit -the WAVE menu file first to select the alternate definition of this action.) -Once the variables have been exported, they may be used in the same way as -any other environment variables within your shell scripts. For example, the -time of the left edge of the signal window is $LEFT. Within a C program, -read the values of these variables using `getenv'; for example, getenv("LEFT") -returns the (string) value of the time of the left edge of the signal window. -Note that the exported values are only a snapshot of the variables at the time -you click on the `Export variables' button; the values do not track later -actions performed within WAVE. - - -Is there a Motif version of WAVE? ---------------------------------- - -No. (Rant begins here.) When I designed WAVE, I attempted to use Motif, but -switched to XView when it became clear that much of the documented -functionality of the Motif toolkit (at the time, version 0.9) was -unimplemented or unusable. It also seemed unlikely that anyone would prefer -Motif's buggy, ugly, proprietary, bloated, kludgy procedural interface over -XView's buggy, attractive, non-proprietary, streamlined, elegant -object-oriented interface (end of rant). - -Motif and its lookalikes (notably GTK+, Qt, and LessTif) have clearly become -the standard, however, and a consequence of this is that the Open Look user -interface presented by WAVE is unfamiliar to many users. There is a scarcity -of introductory material for Open Look in print (but there is an excellent -and comprehensive set of documentation available on CD-ROM from Darwin Open -Systems, http://www.darwinsys.com/). Unfortunately, the Motif API, and those -of its lookalikes, are vastly different from the XView API with which WAVE is -written, and a port to a Motif-like user interface would be decidedly -non-trivial. - -The GTKWave project is reimplementing the user interface of WAVE using the Gimp -toolkit (GTK+). A beta-quality release of {\sf GTKWave} is now available from -PhysioNet. This offers a stable, object-oriented, and non-proprietary -Motif-like interface under any version of Linux or Unix, and also under -MS-Windows. - - -How can I find out about ...? ------------------------------ - -There are several sources of information about WAVE: - - * If you have not used WAVE before, start by reading the WAVE User's Guide - and working through the tutorial examples it contains. If you need to - use existing WFDB applications under WAVE's control, refer to the WFDB - Applications Guide. If you need to develop your own applications for use - with WAVE, read the WFDB Programmer's Guide. Printed copies of - these guides may be purchased from MIT, or you may read them on-line or - print your own copies (visit http://www.physionet.org/). - - * The on-line version of the WAVE User's Guide can be opened for browsing by - clicking left on `User's Guide' in WAVE's Help Topics window (this requires - WAVE 6.0 or later, and Netscape 1.1 or later on the WAVE host). This guide - may also be read with any Web browser independently of WAVE (point your - browser to file:///usr/help/html/wug/wug.htm if you have installed WAVE - 6.0 or later, or to http://www.physionet.org/physiotools/wug/ otherwise). - - * Use XView spot help for brief descriptions of WAVE's controls and other - graphic elements. Point to any control and press the Help key (see `How - do I get spot help ...', above, if you don't have a Help key). - - * Use WAVE's task-oriented on-line help (of which this is a part) to learn - how to use WAVE as a tool for interactive data analysis, control of external - programs, annotation editing, and other topics. Click left on `Help' in - WAVE's main control panel to open the Help window, containing buttons for - each topic. Click left on any of these buttons to open a help window for - the associated topic. Within the help window, use the scroll bar to move - through the topic, or click on the `Print' button to obtain a printed copy - of the entire topic. - - * Select `About WAVE...' from the `Properties' menu, or select `What's new' - from the Help panel, for a summary of new features in WAVE, a current list - of known bugs, and instructions for printing a copy of the on-line manual, - which includes the text of all of the other help topics. Click on the - `Print' button to obtain a printed copy of the `What's new' topic. - - * The man page for `wave' contains a concise description of its command-line - options, the environment variables and X resources it uses, and the WAVE - menu file. (This information is also included in the WAVE User's Guide; - the man page is intended as a compact reference. The man page for `wave' - can be found in the WFDB Applications Guide, or on-line by typing - `man wave', or by using `xman' or `tkman', etc.) - - * For additional information on the WAVE Analyze menu file, see the comments - in the default menu file distributed with `wave' (usually installed as - `/usr/lib/wavemenu.def'). - - * For information about the data formats supported by WAVE and the other WFDB - applications, see section 5 of the WFDB Applications Guide, or the man pages - for annot(5), header(5), signal(5), and wfdbcal(5). diff -Naur wfdb-10.2.5/wave/helppan.c wfdb-10.2.6/wave/helppan.c --- wfdb-10.2.5/wave/helppan.c Tue Nov 27 13:32:28 2001 +++ wfdb-10.2.6/wave/helppan.c Mon Jun 24 22:36:38 2002 @@ -52,6 +52,20 @@ strcpy(url, "http://www.physionet.org/physiotools/wug/"); } +void find_faq() +{ + FILE *ifile; + + sprintf(url, "%s/html/wug/wave-faq.htm", helpdir); + if (ifile = fopen(url, "r")) fclose(ifile); + else if (ifile = fopen("wave-faq.htm", "r")) { + fclose(ifile); + sprintf(url, "%s/wave-faq.htm", getcwd(NULL, 256)); + } + else + strcpy(url, "http://www.physionet.org/physiotools/wug/wave-faq.htm"); +} + void help() { find_user_guide(); @@ -115,6 +129,14 @@ find_user_guide(); open_url(); } +/* Open the WAVE FAQ in a web browser. */ +static void help_faq(item, event) +Panel_item item; +Event *event; +{ + find_faq(); + open_url(); +} /* Create a text subwindow and display help on selected topic. */ static void help_select(item, event) @@ -268,11 +290,11 @@ PANEL_NOTIFY_PROC, help_select, PANEL_CLIENT_DATA, (caddr_t) 'n', 0); + xv_create(help_panel, PANEL_BUTTON, PANEL_LABEL_STRING, "Frequently asked questions", XV_HELP_DATA, "wave:help.faq", - PANEL_NOTIFY_PROC, help_select, - PANEL_CLIENT_DATA, (caddr_t) 'f', + PANEL_NOTIFY_PROC, help_faq, 0); xv_create(help_panel, PANEL_BUTTON, diff -Naur wfdb-10.2.5/wave/wave.info wfdb-10.2.6/wave/wave.info --- wfdb-10.2.5/wave/wave.info Sun Mar 10 17:30:10 2002 +++ wfdb-10.2.6/wave/wave.info Mon Jun 24 22:29:00 2002 @@ -25,13 +25,13 @@ # please visit PhysioNet (http://www.physionet.org/). # _____________________________________________________________________________ -:file:url_view /usr/help/html/wug/node63.htm +:file:url_view /usr/help/html/wug/node64.htm This button opens a pull-down menu containing selections for loading, saving, printing, analyzing, and logging database files. # -:file.load:url_view /usr/help/html/wug/node64.htm +:file.load:url_view /usr/help/html/wug/node65.htm This selection pops up a window in which you can enter a new record or annotator name, or change the name of the WFDB calibration @@ -97,7 +97,7 @@ edits. # -:file.print:url_view /usr/help/html/wug/node14.htm +:file.print:url_view /usr/help/html/wug/node15.htm This selection prints the contents of the signal window on paper. The output is made from the original signal files, and therefore is of better @@ -106,7 +106,7 @@ output reflects any changes you have made. # -:file.printsetup:url_view /usr/help/html/wug/node65.htm +:file.printsetup:url_view /usr/help/html/wug/node66.htm This selection pops up a panel that shows the commands WAVE uses to print PostScript and text data from the standard input. You may change @@ -131,7 +131,7 @@ example, to specify use of a different printer). # -:file.analyze:url_view /usr/help/html/wug/node66.htm +:file.analyze:url_view /usr/help/html/wug/node67.htm This selection pops up a panel containing a set of buttons, and a terminal emulator window. The names of the buttons and their assigned actions @@ -269,13 +269,13 @@ signal from the list), and click left. # -:file.analyze.show_scope_window:url_view /usr/help/html/wug/node76.htm +:file.analyze.show_scope_window:url_view /usr/help/html/wug/node77.htm This button pops up WAVE's Scope window, which can be used to display a signal in `oscilloscope' mode. # -:file.analyze.show_command_window:url_view /usr/help/html/wug/node15.htm +:file.analyze.show_command_window:url_view /usr/help/html/wug/node16.htm This button pops up a terminal emulator window that receives commands generated by selecting most of the other buttons in this window, and @@ -283,7 +283,7 @@ You may type commands directly into the window. # -:file.analyze.edit_menu:url_view /usr/help/html/wug/node34.htm +:file.analyze.edit_menu:url_view /usr/help/html/wug/node35.htm This button allows you to edit the menu configuration file for this panel, using the text editor named in the EDITOR environment @@ -292,7 +292,7 @@ `Reread menu' to reconfigure this panel. # -:file.analyze.reread_menu:url_view /usr/help/html/wug/node34.htm +:file.analyze.reread_menu:url_view /usr/help/html/wug/node35.htm Select this button to reconfigure this panel after you have made changes to the menu configuration file (most easily done by @@ -316,7 +316,7 @@ analysis menu file. # -:file.log:url_view /usr/help/html/wug/node67.htm +:file.log:url_view /usr/help/html/wug/node68.htm This selection pops up a window that allows you to name a log file, and to record in that file the current record name and start and end time entries @@ -431,7 +431,7 @@ log entry. # -:view:url_view /usr/help/html/wug/node68.htm +:view:url_view /usr/help/html/wug/node69.htm This button pops up the View window, which allows you to choose (or merely examine) display scales, grid styles, and annotation, signal, and time @@ -561,14 +561,14 @@ and refreshes the signal window. # -:view.save_as_new_defaults:url_view /usr/help/html/wug/node60.htm +:view.save_as_new_defaults:url_view /usr/help/html/wug/node61.htm This button causes WAVE to record the current View panel settings in your .Xdefaults file (at the same time erasing any comments in that file). These settings become the new defaults for your future WAVE sessions. -:edit:url_view /usr/help/html/wug/node69.htm +:edit:url_view /usr/help/html/wug/node70.htm This button brings up the Edit menu, which allows you to specify if annotation editing is to be allowed or forbidden. By default, @@ -586,7 +586,7 @@ You may still edit `<', `:', and `>' markers. # -:prop:url_view /usr/help/html/wug/node70.htm +:prop:url_view /usr/help/html/wug/node71.htm This button brings up the Properties menu, with selections for obtaining information about the current signal and annotation files @@ -637,7 +637,7 @@ half of the width of the signal window. # -:find:url_view /usr/help/html/wug/node71.htm +:find:url_view /usr/help/html/wug/node72.htm This button opens a window that allows you to specify what portion of the current record should be displayed next. You may set a specific start @@ -687,7 +687,7 @@ . to match a deletion made during this edit # -:find.more_options:url_view /usr/help/html/wug/node74.htm +:find.more_options:url_view /usr/help/html/wug/node75.htm This button clears the contents of the "Search for" field and opens the Search Template window. # @@ -716,7 +716,7 @@ or marker will be counted as a match. # -:help:url_view /usr/help/html/wug/node72.htm +:help:url_view /usr/help/html/wug/node73.htm This button pops up a panel containing buttons that name several topics for which extensive on-line help is available. Choosing a topic @@ -821,7 +821,7 @@ Editing' topic from the Help window. # -:annot.type:url_view /usr/help/html/wug/node17.htm +:annot.type:url_view /usr/help/html/wug/node18.htm This field specifies the type of annotation to be inserted. It may be changed by selecting a new value from the pull-down menu, by typing @@ -922,7 +922,7 @@ This button closes the Level window. # -:scope_panel:url_view /usr/help/html/wug/node76.htm +:scope_panel:url_view /usr/help/html/wug/node77.htm This panel contains controls for the Scope window, which displays the signal indicated by the Signal control in the @@ -983,7 +983,7 @@ an index mark (`:'), or the `>' marker. # -:scope_canvas:url_view /usr/help/html/wug/node76.htm +:scope_canvas:url_view /usr/help/html/wug/node77.htm This is the scope window, which displays the signal indicated on the Analyze panel. The scales match those in the signal window (use diff -Naur wfdb-10.2.5/waverc/Makefile wfdb-10.2.6/waverc/Makefile --- wfdb-10.2.5/waverc/Makefile Sun Mar 10 12:42:43 2002 +++ wfdb-10.2.6/waverc/Makefile Mon Jun 24 22:43:07 2002 @@ -25,12 +25,12 @@ # please visit PhysioNet (http://www.physionet.org/). # _____________________________________________________________________________ # file: version.def G. Moody 24 May 2000 -# Last revised: 15 January 2002 +# Last revised: 11 March 2002 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 MINOR = 2 -RELEASE = 5 +RELEASE = 6 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # VDEFS is the set of C compiler options needed to set version number variables @@ -38,7 +38,7 @@ VDEFS = -DWFDB_MAJOR=$(MAJOR) -DWFDB_MINOR=$(MINOR) -DWFDB_RELEASE=$(RELEASE) # _____________________________________________________________________________ -PACKAGE=wfdb-10.2.5 +PACKAGE=wfdb-10.2.6 # file: linux.def G. Moody 31 May 2000 # Last revised: 17 December 2001 # 'make' definitions for compiling the WFDB Software Package under Linux @@ -164,20 +164,13 @@ # Last revised: 19 June 2000 # Change the settings below as appropriate for your setup. -# URLV is the command that starts your web browser if necessary and opens the -# URL named in its first argument. The following works properly with Netscape -# 1.1 and later versions; if you are using a different browser, consult its -# documentation. -URLV='( netscape -remote "openURL($$1)" 2>/dev/null || netscape $$1 ) &' - -# `make all' creates url_view, wavescript, and wave-remote without installing -# them. +# `make all' creates wavescript and wave-remote without installing them. all: wavescript wave-remote -# `make install' installs `wavescript' and `wave-remote'. See the WAVE User's -# Guide for instructions on setting up `wavescript' as a helper application for -# your Web browser. -install: $(BINDIR) url_view wavescript wave-remote +# `make install' installs `url_view', `wavescript', and `wave-remote'. See +# the WAVE User's Guide for instructions on setting up `wavescript' as a helper +# application for your Web browser. +install: $(BINDIR) wavescript wave-remote $(STRIP) wavescript $(STRIP) wave-remote $(SETXPERMISSIONS) url_view wavescript wave-remote @@ -186,11 +179,6 @@ uninstall: ../uninstall.sh $(BINDIR) url_view wavescript wave-remote -# `url_view' opens a web browser to view a named URL. -url_view: Makefile - cp urlvhead url_view - echo $(URLV) >>url_view - # `wavescript' reads commands from a named file and passes them to WAVE. wavescript: wavescript.c $(CC) -o wavescript -DBINDIR=$(BINDIR) -O wavescript.c @@ -208,7 +196,7 @@ # `make clean': remove intermediate and backup files clean: - rm -f url_view wavescript wave-remote wave-remote-test *~ + rm -f wavescript wave-remote wave-remote-test *~ # Create directory for installation if necessary. $(BINDIR): diff -Naur wfdb-10.2.5/waverc/Makefile.tpl wfdb-10.2.6/waverc/Makefile.tpl --- wfdb-10.2.5/waverc/Makefile.tpl Mon Jun 19 15:13:12 2000 +++ wfdb-10.2.6/waverc/Makefile.tpl Wed Jun 19 21:43:50 2002 @@ -2,20 +2,13 @@ # Last revised: 19 June 2000 # Change the settings below as appropriate for your setup. -# URLV is the command that starts your web browser if necessary and opens the -# URL named in its first argument. The following works properly with Netscape -# 1.1 and later versions; if you are using a different browser, consult its -# documentation. -URLV='( netscape -remote "openURL($$1)" 2>/dev/null || netscape $$1 ) &' - -# `make all' creates url_view, wavescript, and wave-remote without installing -# them. +# `make all' creates wavescript and wave-remote without installing them. all: wavescript wave-remote -# `make install' installs `wavescript' and `wave-remote'. See the WAVE User's -# Guide for instructions on setting up `wavescript' as a helper application for -# your Web browser. -install: $(BINDIR) url_view wavescript wave-remote +# `make install' installs `url_view', `wavescript', and `wave-remote'. See +# the WAVE User's Guide for instructions on setting up `wavescript' as a helper +# application for your Web browser. +install: $(BINDIR) wavescript wave-remote $(STRIP) wavescript $(STRIP) wave-remote $(SETXPERMISSIONS) url_view wavescript wave-remote @@ -24,11 +17,6 @@ uninstall: ../uninstall.sh $(BINDIR) url_view wavescript wave-remote -# `url_view' opens a web browser to view a named URL. -url_view: Makefile - cp urlvhead url_view - echo $(URLV) >>url_view - # `wavescript' reads commands from a named file and passes them to WAVE. wavescript: wavescript.c $(CC) -o wavescript -DBINDIR=$(BINDIR) -O wavescript.c @@ -46,7 +34,7 @@ # `make clean': remove intermediate and backup files clean: - rm -f url_view wavescript wave-remote wave-remote-test *~ + rm -f wavescript wave-remote wave-remote-test *~ # Create directory for installation if necessary. $(BINDIR): diff -Naur wfdb-10.2.5/waverc/url_view wfdb-10.2.6/waverc/url_view --- wfdb-10.2.5/waverc/url_view Wed Dec 31 19:00:00 1969 +++ wfdb-10.2.6/waverc/url_view Thu Jun 20 10:10:04 2002 @@ -0,0 +1,59 @@ +#!/bin/sh +# file: url_view G. Moody 16 April 1997 +# Last revised: 20 June 2002 + +# Use this script to view an HTML document or any other URL (specified by +# the command-line argument to this script). Set the environment variable +# URLV to specify your favorite web browser; if you have not done so, +# url_view will attempt to use Mozilla. + +if [ $# -lt 1 ]; then + echo usage: url_view URL; exit +fi + +if [ "x$URLV" = "x" ]; then + URLV=mozilla +else + case $URLV in + Gal*) URLV=galeon ;; + Kfm*) URLV=konqueror ;; + Kon*) URLV=konqueror ;; + Moz*) URLV=mozilla ;; + Net*) URLV=netscape ;; + Ope*) URLV=opera ;; + esac +fi + +case $URLV in + gal*) $URLV -x $1 2>/dev/null & ;; + konq*|kfm*) kfmclient openURL 2>/dev/null $1 ;; + moz*|net*|ope*) ( $URLV -remote "openURL($1)" 2>/dev/null || $URLV $1 ) & ;; + *) $URLV $1 & ;; +esac + +exit + +# For supported browsers (Galeon, Konqueror (kfm), Mozilla, Netscape, and +# Opera), url_view avoids launching a new instance of the browser if one +# is already running. For all of these except Konqueror, url_view reuses +# an already-open browser window if possible. + +# Note that early versions of these browsers may not support the remote +# control features of current versions. All versions of Netscape since 1.1 +# will work properly, but remote control was added to Mozilla and Galeon +# relatively recently. It is likely that all versions of Konqueror will +# work, but only Konqueror 2.2.2 has been tested. Opera has not been tested. + +# If URLVIEWER specifies an unsupported browser, url_view invokes it in the +# background, passing the URL as the first (and only) command-line argument. + +# If you are still using Mosaic, you are invited to add Mosaic support (see +# http://archive.ncsa.uiuc.edu/SDG/Software/Mosaic/Docs/remote-control.html). + +# If you want to port url_view to MS-Windows, you may be able to use IE with +# the command "rundll32.exe url.dll,FileProtocolHandler $1" (where $1 is the +# URL, as above). According to http://www.jsifaq.com/SUBI/tip4100/rh4162.htm, +# you will need to convert .htm to .ht%6D (and presumably .html to .ht%6D%6C) +# if $1 ends in .htm or .html, because rundll32 chokes otherwise. Note that +# the remote control features of the other browsers may work differently or +# may be unsupported under MS-Windows. diff -Naur wfdb-10.2.5/waverc/urlvhead wfdb-10.2.6/waverc/urlvhead --- wfdb-10.2.5/waverc/urlvhead Mon Jun 19 15:13:16 2000 +++ wfdb-10.2.6/waverc/urlvhead Wed Dec 31 19:00:00 1969 @@ -1,10 +0,0 @@ -#!/bin/sh -# file: url_view G. Moody 16 April 1997 -# -# Use this script to view an HTML document or any other URL, either by starting -# your web browser or by instructing an already-running copy of your browser to -# open the URL. - -if [ $# -lt 1 ]; then - echo usage: url_view URL; exit -fi diff -Naur wfdb-10.2.5/waverc/wave-remote.c wfdb-10.2.6/waverc/wave-remote.c --- wfdb-10.2.5/waverc/wave-remote.c Sat Mar 9 13:21:17 2002 +++ wfdb-10.2.6/waverc/wave-remote.c Wed Jun 19 13:54:27 2002 @@ -1,5 +1,5 @@ /* file: wave-remote.c G. Moody 10 October 1996 - Last revised: 9 March 2002 + Last revised: 19 June 2002 Remote control for WAVE ------------------------------------------------------------------------------- @@ -118,8 +118,9 @@ { char fname[30]; FILE *ofile; - int i, j = 0, pid, *siglist; + int i, j = 0, pid; static char *ppid, *record, *annotator, *ptime; + static int *siglist; pname = argv[0]; for (i = 1; i < argc; i++) { /* read command-line arguments */ @@ -170,13 +171,13 @@ exit(2); } /* fill the signal list */ + siglist[j] = -1; for (i -= j, j = 0; i < argc && argv[i][0] != '-'; ) siglist[j++] = atoi(argv[i++]); i--; break; } } - siglist[j] = -1; if (annotator == NULL && ptime == NULL && record == NULL && j == 0) { help(); exit(1); @@ -194,7 +195,7 @@ if (annotator) sprintf(command+strlen(command), " -a %s", annotator); if (ptime) sprintf(command+strlen(command), " -f %s", ptime); - if (siglist[0] >= 0) { + if (siglist && (siglist[0] >= 0)) { sprintf(command+strlen(command), " -s %d", siglist[0]); for (j = 1; siglist[j] >= 0; j++) sprintf(command+strlen(command), " %d", siglist[j]); @@ -226,7 +227,7 @@ if (record) fprintf(ofile, "-r %s\n", record); if (annotator) fprintf(ofile, "-a %s\n", annotator); if (ptime) fprintf(ofile, "-f %s\n", ptime); - if (siglist[0] >= 0) { + if (siglist && (siglist[0] >= 0)) { fprintf(ofile, "-s %d", siglist[0]); for (j = 1; siglist[j] >= 0; j++) fprintf(ofile, " %d", siglist[j]); diff -Naur wfdb-10.2.5/waverc/wavescript.c wfdb-10.2.6/waverc/wavescript.c --- wfdb-10.2.5/waverc/wavescript.c Sat Mar 9 13:21:32 2002 +++ wfdb-10.2.6/waverc/wavescript.c Wed Jun 19 21:58:08 2002 @@ -1,5 +1,5 @@ /* file: wavescript.c G. Moody 10 October 1996 - Last revised: 9 March 2002 + Last revised: 19 June 2002 Remote control for WAVE via script ------------------------------------------------------------------------------- @@ -140,7 +140,7 @@ if (*annotator) nargs += 2; if (*ptime) nargs += 2; if (*path) nargs += 2; - if (*siglist) { + if (siglist) { for (i = 0; siglist[i]; i++) ; nargs += i+1; @@ -162,7 +162,7 @@ arg[nargs++] = "-p"; arg[nargs++] = path; } - if (*siglist) { + if (siglist) { arg[nargs++] = "-s"; while (*siglist) arg[nargs++] = *siglist++; @@ -312,7 +312,8 @@ if (*record) fprintf(ofile, "-r %s\n", record); if (*annotator) fprintf(ofile, "-a %s\n", annotator); if (*ptime) fprintf(ofile, "-f %s\n", ptime); - if (siglist[0]) { + if (*path) fprintf(ofile, "-p %s\n", path); + if (siglist && siglist[0]) { fprintf(ofile, "-s %s", siglist[0]); for (i = 1; siglist[i]; i++) fprintf(ofile, " %s", siglist[i]); diff -Naur wfdb-10.2.5/wfdb.spec wfdb-10.2.6/wfdb.spec --- wfdb-10.2.5/wfdb.spec Tue Jan 15 15:39:19 2002 +++ wfdb-10.2.6/wfdb.spec Mon Mar 18 23:25:27 2002 @@ -34,6 +34,12 @@ %clean make clean +%post +/sbin/ldconfig + +%postun +/sbin/ldconfig + %files %defattr(-,root,root) %doc checkpkg doc examples fortran lib/COPYING.LIB wave/anntab wave/wavemenu.def COPYING INSTALL MANIFEST NEWS README README.NETFILES

  • 2:14.8752 minutes + 14.875 seconds
    143143 seconds (2 minutes + 23 seconds)